How to use NPM to package a deployment? - node.js

I've developed an Angular website that lives in a Node-based project. Gulp is used to build sources into development and production versions of the site. The project includes an ExpressJS server that can serve either the dev or prod versions of the files. Now I want to build and deploy the site in CI fashion.
I have a private NPM registry that I'm able to publish the entire project module to. The easy route would be:
In the build environment, check out the project repository
npm install
pass tests
npm publish
In the production environment..
npm install project
build for production
Run the server over the newly built prod files
But this doesn't seem right. Shouldn't I output the production files as part of the build process, and publish these as a versioned artifact with NPM? Are there acceptable, different ways to publish an NPM module for development and deployment?
Or am I stuck building my sources in the production environment? Doesn't this defeat the purpose of NODE_ENV=production?

It depends where you are hosting your server.
If you want to deploy to heroku, you can follow https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction and install the gulp build task https://github.com/appstack/heroku-buildpack-nodejs-gulp. Basically, you will push the version you want to deploy to heroku's git server and it will automatically trigger the build process for dev or prod and start the express server. Assuming you are already using git for your project, it is only a matter of adding a new remote.
If you want to deploy to Amazon's elastic beanstalk, it's a little bit more complicated but it all boils down to pushing your application code to the service and this will trigger the build process in the host instance.
If you want to deploy it on your environment you could still use git push and git hook to trigger the deployment. Check out How can I automatically deploy my app after a git push ( GitHub and node.js)? for various implementations.
As for your question "Shouldn't I output the production files as part of the build process, and publish these as a versioned artifact with NPM": you could, but this is not what most people do. As long as your build process is repeatable, there is no reason to package and publish the built version of your app. I am assuming here that your are building an application and not a reusable library in which case it would be a different story.

Related

Typescript Node.js project - deployment to production workflow

How should I setup my dist build and production deployment workflow for my Node.js server app? (NestJS API)?
My current workflow:
Commit changes to production branch
Production server with pm2 automatically pull changes from this repo
Automatic npm install on prod server.
Automatic npm run build on prod server.
Automatic pm2 start on prod server.
The main problem I see in this workflow is that I am running build on production server. This means that I need all devDependencies on server and also I am doing performance spikes on server when building.
I already configured GitHub Actions on my repo to build my code and save it as artifact on commit, but now I am stuck.
Should I commit built source code to repo and then use pm2 hook on production?
Should I download artifact by some script to production, unpack it and run it? I see few problems here:
/dist folder (artifact) does not have package.json and assets
I lost Git functionality, so I need to always delete old source and unpack new source
I don't have all the info I need, but I guess you should run the build step on a CI/CD tool (TravisCI for example), and push the content of the /dist folder to your production server afterwards. Then, pm2 would only run this production build.

Deploy only the build artifacts of a Next.js project

I'm trying to deploy a Next.js project using a Docker image and I was wondering if it's possible to simply use an already generated dist folder (.next) and start the next.js server (npm run start) without having to trigger the build step again in the container.
The container will be hosted in AWS Elastic Beanstalk and I also want to avoid uploading the source code and installing the npm packages there, as I already have a CI pipeline that is generating the production artifacts.
Answering because I was going through issues with this myself and found this question. My research shows the only way to accomplish this is to run a docker environment on beanstalk and not node.js. The primary reason is that there are absolute paths in the .next build artifacts so you have to build on each instance and you have to make sure that BUILD_ID is synced across those instances.
If you CI pipeline can handle creating and pushing the Docker image, then its pretty easy to deploy on Beanstalk without any rebuilding etc. Hope that helps!

Using WebDeploy with an Azure node website doesn't trigger npm install

I am using WebDeploy to deploy a node website to azure.
I've seen in samples and demos that it should trigger a npm install on deploy.
But it is not. I've also seen almost every demo uses git deployment.
Is automatic npm install not supported for WebDeploy or am I missing something?
when you use WebDeploy, it will just copy over all the file from your machine to cloud, it will not trigger any build process. You will have to responsible to make sure your app is ready to run.
if you want CI function, please setup continues deployment, here is tutorial for setting up local git
https://azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control/
and there are other options if you have repository in github/bitbucket/Visual studio Team Service etc ... (go to https://portal.azure.com, select your site --> all settings --> continuous deployment to see all supported optinos)
According to the doc Publish to Microsoft Azure Website using Web Deploy, it said
Deployment will include all the files in your project. Files in the node_modules folder are included automatically, even if they are not part of the project.
So all files under your project folder in VS, including the node_modules folder, will be deployed.

Build and deploy or deploy to build

My application is based on node.js, and uses bower.js and others task runners to compile assets and build the actual assets (minify, concat, inject...).
Since this is my first application that will be running in a scalable enviroment on Heroku, I was wondering how is the process of deploying.
I mean, my current workflow is:
cd myRepo
git commit [blabla...]
git push heroku
And when running it, it runs npm run wich calls geddy and runs the server.
If I build before pushing, there will be files that are kind of redundant, but if I push the unbuilt project, it should build it on the cloud. Is that the main idea?
Thanks
it should build it on the cloud. Is that the main idea?
Correct; checkout the Dev Center for more Nodejs information:
Heroku Dev Center: Getting Started with Nodejs
Specifically here, it lists information on bower:
Heroku Node.js Support: Customizing the Build Process

How to package & deploy Node.js + express web application?

I am new to Node.js programming and I have recently created a sample working web application using (express, backbone & other complimentary view technologies, with mongoDB). Now i am at a point where I want to deploy the same on a staging environment and I am not sure how to package this application and distribute the same. [I can take care of mongoDb and setting it up seperately]
I am from Java world and in there we create jars for reusable libs and war/ear packages for web applications which is deployed in a servlet container. Now in this case since node.js itself acts as a web container as well, how do i package my webapp?
Is there any standard format/guidelines of packaging node webapps built using express? (Is there a similar jar/war packaging systems for node apps?)
How do I deploy it once packaged? Would it become an exe, since it is also its own container?
PS: As of now I am thinking of just manually copying all the required source files into the staging environment and run npm commands to download all dependencies on that machine and then use 'forever' or some other mechanism to run my server.js. (Also, add some sort of monitoring, just in case app crashes and forever fails) I am not sure if that is the right way? I am sure there must be some standardized way of addressing this problem.
Deploying Node.js applications is very easy stuff. In maven, there is pom.xml. Related concept in Node.js is package.json. You can state your dependencies on package.json. You can also do environmental setup on package.json. For example, in dev environment you can say that
I want to run unit tests.
but in production;
I want to skip unit tests.
You have local repositories for maven under .m2 folder. In Node.js, there is node_modules folder under your Node.js project. You can see module folders with its name.
Let's come to the grunt part of this answer. Grunt is a task manager for your frontend assets, html, javascript, css. For example, before deployment you can minify html, css, javascript even images. You can also put grunt task run functions in package.json.
If you want to look at a sample application, you can find an example blog application here. Check folder structure and package.json for reference.
For deployment, I suggest you heroku deployment for startup applciations. You can find howto here. This is simple git based deployment.
On project running part, simply set your environment NODE_ENV=development and node app.js. Here app.js is in your project.
Here is relative concept for java and nodejs;
maven clean install => npm install
.m2 folder => node_modules(Under project folder)
mvn test => npm test(test section on package.json)
junit, powermock, ... => mocha, node-unit, ...
Spring MVC => Express.JS
pom.xml => package.json
import package => require('module_name')
There is no standardized way, but you're on the right track. If your package.json is up to date and well kept, you can just copy/zip/clone your app directory to the production system, excluding the node_modules.
On your production system, run
npm install to install your dependencies, npm test if you have tests and finally NODE_ENV=production node server.js
Some recent slides I considered to be quite helpful that also include the topic of wrappers like forever, can be found here.
Hope this might be helpful for somebody looking for the solution,Packaging of Node js apps can be done using "npm pack" command.It creates a zip file of your application which can be run in production/staging environment.
Is there any standard format/guidelines of packaging node webapps
built using express? (Is there a similar jar/war packaging systems for
node apps?)
Yes, the CommonJS Packages specification:
This specification describes the CommonJS package format for
distributing CommonJS programs and libraries. A CommonJS package is a
cohesive wrapping of a collection of modules, code and other assets
into a single form. It provides the basis for convenient delivery,
installation and management of CommonJS components.
For your next question:
2. How do I deploy it once packaged? Would it become an exe, since it is also its own container?
I second Hüseyin's suggestion to deploy on Heroku for production. For development and staging I use Node-Appliance with VirtualBox and Amazon EC2, respectively:
This program takes a Debian machine built by build-debian-cloud or
Debian-VirtualBox-Appliance and turns it into a Node.js "appliance",
capable of running a Node application deployed via git.
Your webapp will not become an exe.
few ways to approach this:
Push your code into Git repository, excluding everything that isn't your code (node_modules/**), then pull it in your staging environment, run npm install to restore all dependencies
create an NPM package out of it , install it via npm in your staging environment (this should also take care of all of the dependencies)
manual copy/ssh files to your staging environment (this can be automated with Grunt), than restore your dependencies via npm
I used zeit's pkg module. It can create cross platform deliverables for linux/win/macos. Actually used it in production and works fine without any issues.
It takes in all the js scripts and packages it into a single file.
The reason I used it is because it helps in securing your source code. That way in production at customers environment they will have access to application but not the source code.
Also one of the advantages is that at production environment, you do not actually need to have the customer install node.js as the node binaries also get packaged inside the build.
https://www.npmjs.com/package/pkg

Resources