Node.js REST API setup with Docker Compose, Express and Postgres
Learn how to deploy a Node.js app with PostgreSQL DB using docker-compose file
Docker-compose:
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproduced anywhere. - Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment. - Run
docker-compose up
and Compose starts and runs your entire app.
A docker-compose.yml
looks like this:
version: '2.0'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Create the Node.js app
First, create a new directory where all the files would live. In this directory create a package.json
file that describes your app and its dependencies:
{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <first.last@example.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
With your new package.json
file, run npm install
. If you are using npm
version 5 or later, this will generate a package-lock.json
file which will be copied to your Docker image.
Then, create a server.js
file that defines a web app using the Express.js framework:
'use strict';
const express = require('express');
const { Pool, Client } = require('pg');// Constants
const PORT = 3000;
const HOST = '0.0.0.0';// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World App');
});const client = new Client({
user: 'user',
host: 'postgres',
database: 'db',
password: 'pass',
port: 5432,
});client.connect()
client.query('SELECT NOW()', (err, res) => {
console.log("Error or response:: ", err, res)
client.end()
});app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
In the next steps, we’ll look at how you can run this app inside a Docker container using the official Docker image. First, you’ll need to build a Docker image of your app.
Creating a Dockerfile
Create an empty file called Dockerfile
:
touch Dockerfile
Open the Dockerfile
in your favorite text editor
The first thing we need to do is define from what image we want to build from. Here we will use the latest LTS (long term support) version 12
of node
available from the Docker Hub:
FROM node:12
WORKDIR /app
COPY ./package.json .RUN npm cache clean --force
RUN npm install
COPY . .
EXPOSE 3000
# CMD npm start
CMD [ "node", "server.js" ]
.dockerignore file
Create a .dockerignore
file in the same directory as your Dockerfile
with the following content:
node_modules
npm-debug.log
This will prevent your local modules and debug logs from being copied onto your Docker image and possibly overwriting modules installed within your image.
Creating docker-compose.yml file
# docker-compose.yml
version: "3"
services:
app:
restart: on-failure
build: .
depends_on:
- postgres
environment:
DATABASE_URL: postgres://user:pass@postgres:5432/db
NODE_ENV: development
PORT: 3000
ports:
- "3000:3000"
command: npm run dev
volumes:
- .:/app/
- /app/node_modules
postgres:
image: postgres:11
ports:
- "35432:5432"
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: db
Accessing the application
The application is available at http://localhost:3000.
curl http://localhost:3000
OK
However, you can download the repo from docker-hub alternatively
docker pull kdsharma/nodewithdocker
Deploying the application
docker-compose up -d
Deploying with rebuild the application
When we changed anything in our application, then we have to build the application.
docker-compose up --build -d
Show running containers
docker ps
# or
docker container ls
Stop the application
docker-compose down
Automatic restart container on crash
By default, there is “no restart” policies assigned to our container. Add restart policies inside images.
Restart polices ex:
docker run -d --restart unless-stopped redis
More info regarding the restart policies: