Serving a node app with nginx
I’m using Ubuntu 14.04 and Node 0.12.5. (A convenient digital ocean droplet!)
SSH into our machine….
Setup Nginx
Nginx is a web server. It routes and manages incoming connections. It serves the same purpose as Apache.
Install
|
|
The main commands:
It will be started after install. These are for reference. You don’t need to do any of them right now.
|
|
Getting familiar with nginx
Where is nginx?
|
|
If we looks at the directory listing (ls
), we see all the goodies. At this point, all I really care about are two folders: sites-enabled
and sites-available
.
We need to put a record of our site in sites-available
. Then, we’ll put a symbolic link to that file in sites-enabled
. The records in sites-enabled
are what nginx looks for when mapping incoming requests to the files to execute (our app!).
Make a record for our app in sites-available
I like to start by making a copy of the default record.
|
|
Tell nginx what we want to happen when we get a request to that URL
We do that by creaing a vhost file. You can use any shell text editor you want. I like pico because it tells me what to do. If you’re a cool person you’ll probably use vim.
|
|
You’ll see there’s a ton of comments. (# = comment). If you study this file it will explain a lot of great things. Otherwise, I just delete everything (Ctrl+K cuts a line at a time. I’m too lazy to learn the correct way to delete thing). So what was the purpose of copying? Yeah, I really just think it’s worthing looking at the possible options to get familiar with nginx.
So here’s what your file should look like:
|
|
Two things you’ll need to change…. the server name on line 4. And the port at the end of line 61. Well, you don’t need to change the port, but it will need to match whatever port your launch your node app on.
So what’s going on here? Basically, this is known as a reverse proxy. When you run node on development on your computer you get a local address with a port. You visit that local address on that port and you see your site. This is the same thing. Nginx just acts as a gobetween from external users to the localhost on your server.
Enable the site
We enable the site by placing the same record we created in sites-available
in sites-enabled
. The best way to do this is with a symbolic link so that changes in one place are reflected in both locations.
|
|
Now that everything is setup, we need to restart Nginx
Run our app with PM2
You could start your app like you normally woul with the node
command, adjusting the port as you normally would, but if you have one error, your app will crash.
PM2 is a service that automatically restarts your node app if it crashes. It does some other cool things too that make it better for production that something like nodemon
.
I chose PM2 over Passenger because I couldn’t get Passenger to work. PM2 just works with very little config.
Install PM2
|
|
Here is my go-to pm2 command:
That gives an overview of your processes.
Note: PM2 works on a per-user basis. I use PM2 from my deployer
user since the deployer
user has restricted permissions and needs to restart the app whenever there’s an update. I know I haven’t mentioned a deployer
user yet. I’ll explain in another blog post
Configure PM2 to run our app
We can configure PM2 with a json file. This isn’t the only way, but I like it since I can set my environment to be production
and do other cool things.
I’ve created a file called pm2-config.json
in my app file home: /var/www/your.site.com
. It doesn’t matter too much where you put the file.
Let’s create our config file:
Here’s what my file looks like:
It’s pretty simple. You just need to change the valuse to match your needs. Script is the entry point of your app. I’m using the express framework, so the entry point to your app may look different.
Important Make sure the port
setting matches what you said the port would be when you were configuring Nginx. It doesn’t matter if you have a different port setting in your script file. PM2 will override it.
Note: Why do I have “myprocessname” instead of “your.site.com”. Many of my apps use two processes. One to access the app in a traditional manner, and another to listen for messages from a message queue. I can restart these processes independently from eachother.
Start the app
|
|
We’re good to go!