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 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:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  3. 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

{
"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

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

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

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

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:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store