Deploy an Always-On Node.js Express Application with Docker
In this article, you'll learn how to deploy a simple NodeJS Express web application within a Docker container, using the Vultr One-Click Docker app.
1. Create the Docker Instance
The One-Click Docker application automatically installs Docker for you and creates a docker user and group for limited access. Use the steps in the One-Click Docker article to set up the instance.
Create an instance using the Docker application for Server Type.
SSH to the server as root. Install NodeJS and NPM, the Node package manager.
# curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - # sudo apt-get install -y nodejs
log into the pre-created Docker user.
# su - docker
2. Create the Node Application
Set up a simple Express app that listens on port 80 and responds to requests at http://<server-ip>/
with "Hello from Docker!".
Make a directory named
src
in the docker user's home directory and navigate into it:$ mkdir ~/src $ cd ~/src
Initialize the ~/src directory as a NodeJS application:
$ npm init
When prompted for the package name, enter
hello_node_docker
. Press Enter for the remaining prompts.Install the
express
package, which also creates apackage.json
file that tells node how to run your application.$ npm install express
Create an
index.js
file, which contains the application code.$ nano index.js
Paste the following code:
var express = require('express'); var app = express(); app.get('/', (req, res) => { res.send("Hello from Docker!"); }); app.listen(80, () => { console.log("Listening on port 80!"); });
Save and exit the file.
So far, you've created a basic NodeJS application that has Express as a dependency, listens on port 80, and responds to GET requests at /
with "Hello from Docker!".
3. Create the Dockerfile
Create a Dockerfile that describes how Docker will build your application.
$ nano Dockerfile
Paste the following contents into the file.
FROM node:latest COPY ./ . EXPOSE 80 CMD ["node", "index.js"]
Save and exit the file.
The Dockerfile tells Docker to:
- Use the latest version of node
- Copy the code to the docker image
- Expose port 80
- Run the command
node index.js
to start your application.
4. Create the Docker Image
Create the docker image using the application code and the Dockerfile. Run the command below, replacing example-name/example-application
with your name and the name of your application (without spaces):
$ docker build -t example-name/example-application .
This command will build a Docker image and tag (-t
) it with name/application
.
The command may take a few minutes to complete.
Step 5: Run the Docker Container
After building the image, run the container with the following command:
docker run -p 80:80 --restart unless-stopped -d example-name/example-application
If you changed example-name/example-application
, be sure to update it in the command above.
This command will:
- Run the Docker container named
example-name/example-application
. - Expose port 80 of the Docker container to port 80 of your Vultr instance with:
-p 80:80
.- The number on the right is the port of the Docker container, which is exposed to the port number on the left of the Vultr instance.
- Restart the application if stopped, unless you stop it manually. The
-restart unless-stopped
directive will automatically restart the app if the code crashes or if the instance restarts, making it ideal for running long-term processes like a web server.
Understanding Restart Policies
A restart policy for a Docker container can be specified using the --restart
flag (such as the --restart unless-stopped
used in the previous command). Restart policies are especially helpful when configuring Docker containers, as they can help you manage unintended failures and avoid unnecessary downtime associated with crashes or bugged code.
The default option for a container's restart policy is to do nothing. If no option is specified, the container will stop if it crashes or the process exits (and will not restart automatically).
This guide uses the --restart unless-stopped
option. This option tells Docker to restart your container unless the container is stopped manually.
The --restart on-failure
restart policy tells Docker only to restart the container if its process exits due to an error (non-zero exit code). It is possible to specify the maximum number of attempted restarts by adding :max-retries
to the end. For example, to only make three restart retries due to non-zero exit codes, specify --restart on-failure:3
.
The final restart policy is --restart always
. This directive tells Docker to restart your container any time it exits (for any reason, error, or not). The container will automatically start whenever the Docker daemon starts.
Testing Your Application
In a web browser, navigate to your instance's IP address. You should see "Hello from Docker!" printed in the browser.
Cleaning Up
List the running Docker containers:
$ docker container list
Optionally, list all containers:
$ docker container list -a
Look for the container you created. You should see a column named
CONTAINER ID
.Copy the id and replace
CONTAINER_ID
in the following commands with your container's ID.
To stop your container:
docker container stop CONTAINER_ID
The application will exit, and requests to your app will fail.
To delete the container:
docker container rm CONTAINER_ID