What is the best way to deploy Node.js?
I have a Dreamhost VPS (that's what they call a VM), and I have been able to install Node.js and set up a proxy. This works great as long as I keep the SSH connection that I started node with open.
What is the best way to deploy Node.js?
I have a Dreamhost VPS (that's what they call a VM), and I have been able to install Node.js and set up a proxy. This works great as long as I keep the SSH connection that I started node with open.
2016 answer: nearly every Linux distribution comes with systemd, which means forever, monit, PM2, etc. are no longer necessary - your OS already handles these tasks.
Make a myapp.service
file (replacing 'myapp' with your app's name, obviously):
[Unit]
Description=My app
[Service]
ExecStart=/var/www/myapp/app.js
Restart=always
User=nobody
# Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody'
Group=nogroup
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp
[Install]
WantedBy=multi-user.target
Note if you're new to Unix: /var/www/myapp/app.js
should have #!/usr/bin/env node
on the very first line and have the executable mode turned on chmod +x myapp.js
.
Copy your service file into the /etc/systemd/system
folder.
Tell systemd about the new service with systemctl daemon-reload
.
Start it with systemctl start myapp
.
Enable it to run on boot with systemctl enable myapp
.
See logs with journalctl -u myapp
This is taken from How we deploy node apps on Linux, 2018 edition, which also includes commands to generate an AWS/DigitalOcean/Azure CloudConfig to build Linux/node servers (including the .service
file).
Failed to issue method call: Unit name ... is not valid.
?
Commented
Apr 1, 2015 at 18:56
/etc/systemd/system
you might need to run systemctl daemon-reload
(systemd will normally tell you if this is needed). TBH this is best asked as a separate question.
Commented
Apr 1, 2015 at 19:03
/etc/systemd/system
, you can just use systemctl enable /full/path/to/myapp.service
, which creates a symlink in /etc/systemd/system
for you.
node
is called by /var/www/myapp/app.js
itself. In Unix, if you make a file executable, and the first line starts with #!/some/file
the file will be interpreted with that binary. Google 'interpreter Unix' to know more.
Commented
Jan 5, 2018 at 12:56
Use Forever. It runs Node.js programs in separate processes and restarts them if any dies.
Usage:
forever start example.js
to start a process.forever list
to see list of all processes started by foreverforever stop example.js
to stop the process, or forever stop 0
to stop the process with index 0 (as shown by forever list
).forever stop 0
had an error and things just kind of fell apart from there. I have been trying to do this without root on its own user so that I can clean up easily once I find the right solution. That may be my problem. I will look into it some more.
Commented
Jan 15, 2011 at 10:37
I've written about my deployment method here: Deploying node.js apps
In short:
pm2 does the tricks.
Features are: Monitoring, hot code reload, built-in load balancer, automatic startup script, and resurrect/dump processes.
You can use monit
, forever
, upstart
or systemd
to start your server.
You can use Varnish or HAProxy instead of Nginx (Nginx is known not to work with websockets).
As a quick and dirty solution you can use nohup node your_app.js &
to prevent your app terminating with your server, but forever
, monit
and other proposed solutions are better.
I made an Upstart script currently used for my apps:
description "YOUR APP NAME"
author "Capy - http://ecapy.com"
env LOG_FILE=/var/log/node/miapp.log
env APP_DIR=/var/node/miapp
env APP=app.js
env PID_NAME=miapp.pid
env USER=www-data
env GROUP=www-data
env POST_START_MESSAGE_TO_LOG="miapp HAS BEEN STARTED."
env NODE_BIN=/usr/local/bin/node
env PID_PATH=/var/opt/node/run
env SERVER_ENV="production"
######################################################
start on runlevel [2345]
stop on runlevel [016]
respawn
respawn limit 99 5
pre-start script
mkdir -p $PID_PATH
mkdir -p /var/log/node
end script
script
export NODE_ENV=$SERVER_ENV
exec start-stop-daemon --start --chuid $USER:$GROUP --make-pidfile --pidfile $PID_PATH/$PID_NAME --chdir $APP_DIR --exec $NODE_BIN -- $APP >> $LOG_FILE 2>&1
end script
post-start script
echo $POST_START_MESSAGE_TO_LOG >> $LOG_FILE
end script
Customize all before #########, create a file in /etc/init/your-service.conf and paste it there.
Then you can:
start your-service
stop your-service
restart your-service
status your-service
I've written a pretty comprehensive guide to deploying Node.js, with example files:
Here's a longer article on solving this problem with systemd: http://savanne.be/articles/deploying-node-js-with-systemd/
Some things to keep in mind:
All of these things are easily done with systemd.
If you have root access you would better set up a daemon so that it runs safe and sound in the background. You can read how to do just that for Debian and Ubuntu in blog post Run Node.js as a Service on Ubuntu.
Forever will do the trick.
@Kevin: You should be able to kill processes fine. I would double check the documentation a bit. If you can reproduce the error it would be great to post it as an issue on GitHub.
A great and detailed guide for deploying Node.js apps with Capistrano, Upstart and Nginx
As Box9 said, Forever is a good choice for production code. But it is also possible to keep a process going even if the SSH connection is closed from the client.
While not necessarily a good idea for production, this is very handy when in the middle of long debug sessions, or to follow the console output of lengthy processes, or whenever is useful to disconnect your SSH connection, but keep the terminal alive in the server to reconnect later (like starting the Node.js application at home and reconnecting to the console later at work to check how things are going).
Assuming that your server is a *nix box, you can use the screen command from the shell to do keep the process running even if the client SSH is closed. You can download/install screen from the web if not already installed (look for a package for your distribution if Linux, or use MacPorts if OS X).
It works as following:
You can have multiple screen sessions running concurrently like this if you need, and you can connect to any of it from any client. Read the documentation online for all the options.
nohup
and forever
Commented
Dec 27, 2017 at 14:06
Forever is a good option for keeping apps running (and it's npm installable as a module which is nice).
But for more serious 'deployment' -- things like remote management of deploying, restarting, running commands etc -- I would use capistrano with the node extension.
https://paastor.com is a relatively new service that does the deploy for you, to a VPS or other server. There is a CLI to push code. Paastor has a free tier, at least it did at the time of posting this.
In your case you may use the upstart daemon. For a complete deployment solution, I may suggest capistrano. Two useful guides are How to setup Node.js env and How to deploy via capistrano + upstart.
Try node-deploy-server. It is a complex toolset for deploying an application onto your private servers. It is written in Node.js and uses npm for installation.
I am using express on Dreamhost and got pm2 running on background pm2 start app.js
. Convenient. Can view logs and even save log files pm2 logs <PM2_ID> mylogs.txt
,
pm2 monit - monitoring metrics of app
pm2 list - table view of processes
You can configure PM2 to automatically restart a process if it exceeds a certain memory usage threshold. This helps prevent memory leaks or excessive memory usage.
pm2 start app.js --name=myapp --max-memory-restart 200M