One of the biggest stumbling blocks I see when pushing code to production servers is unidentified dependencies: something installed locally on my workstation that doesn’t exist on the production servers. In this lesson, I’ll show you how to use npm scripts to deploy your node.js application to a newly-provisioned server via Vagrant for validation before going to production.
I have a generic Hello World node.js application, and in the package.json file, I'm going to create a new script command called deploy. You can name this command whatever is appropriate for your use. It's not a specific command.
The command's going to execute a Bash script called deploy.sh, and we're going to be creating this script in this lesson. If there's a more appropriate name for you to use, I encourage you to use it, so long as the file name of the script matches whatever you type in here.
The deploy.sh script is responsible for two things, launching our Vagrant image, and logging us into a shell on the system. Our first command is going to launch the Vagrant image based on the parameters specified in our Vagrant file, which we'll build next.
The Vagrant file contains the parameters for launching our server. It's a Ruby file, and inside of this do-end block is where we'll configure the server. Vagrant uses prepackaged boxes to launch the instance. Think of a box as a zipped up, downloadable cloud server.
There's many to choose from, and I'm choosing the RTAC Debian Jessie box, because it's a minimal Debian server installation. If my application depends on a software package being present outside of the core operating system, I'll have to install it manually, or my application is going to fail.
Next, I'm going to forward TCP port 3000. My Hello World node.js application is running on port 3000, and this setting will allow me to access it via localhost. If your node.js application is running on a different port, you can specify it here, or if port 3000 is already in use on your local workstation, you can change it here.
These numbers don't have to be the same, either. Use whatever works for your environment. I'm also going to open port 5858, so that if later, I need to connect to a debug session on my node.js server, the port's already open.
The final step is to provision a server, and to do that, I'm going to use a provisioning script. I'll specify the name here, and so now, we can go build that provisioning script. My provisioning script is going to execute the commands needed to fully configure the server.
I'm using a minimal Debian Linux install. I need to start with updating the package list, then installing curl and Screen. The curl command is used to download node.js from NodeSource. Then I'll use apt-get to install it.
I'm also going to install build-essential as well. If later, I end up specifying any NPM packages that require compiling, the tools will already be available, and installed. If you're not already familiar with Vagrant, one of the cool things it does is create a shared directory from your local workstation to your Vagrant server.
This means that the entire contents of this folder are available as the /vagrant directory on the Vagrant server. That's how we're going to run the Hello World node.js application. I'll change directory into the Vagrant directory, run NPM install to install any required modules, and then I'll launch a Screen session that starts the node.js server.
If you haven't used Screen, it's going to open a session as the default user, Vagrant, launch my node.js application, and then disconnect the session, leaving node.js running, and in a state where I can reconnect to it.
That completes the provisioning of the Vagrant server, so the provisioning script is going to exit. The Vagrant file is complete, and I'm going to go back into our deploy.sh file, where I'll add a second command that's going to log us into the Vagrant image once it's booted up.
I need to add execute permissions to my deploy script, so it can actually execute. I can launch the environment, and deploy my Node application to it, with the NPM run deploy command. It looks like it's up and running. If we switch to a browser, I should be able to browse the site by going to localhost 3000, and there it is. It works.
The final step of our provisioning sequence logged us into the Vagrant image, and you can see that here in my console. Remember, the Screen command that we typed? If I type now screen -r, it connects me to the running session for Node, where you can see the command that launched Node, as well as any log output from the Node server.
I can also kill and restart Node from this, and disconnect it, while leaving it running, using the command control A, control D. I hope this helps you both test your applications before deploying them, and stimulate ideas of your own on how to use NPM scripts to automate tasks in your development life cycle.