Dockerizing A NodeJS App Along With PostgreSQL Database - Stelab
17962
post-template-default,single,single-post,postid-17962,single-format-standard,bridge-core-2.5.9,qode-page-transition-enabled,ajax_fade,page_not_loaded,,qode-title-hidden,hide_top_bar_on_mobile_header,qode-theme-ver-24.4,qode-theme-bridge,qode_advanced_footer_responsive_1000,qode_header_in_grid,wpb-js-composer js-comp-ver-6.4.2,vc_non_responsive,elementor-default,elementor-kit-16812,elementor-page elementor-page-17962

Dockerizing A NodeJS App Along With PostgreSQL Database

Building an app is an adventure with many processes, algorithms, schema, design, etc. Even though it is not easy to build a robust app, publishing the project’s first release is a real pleasure. While there can be so many problems developers have to deal with throughout the production, deploying comes with its problems and questions like hows, wheres, whats… And when it comes to deployment, Docker is a powerful tool to use.

In this post, I am going to show how to deploy a NodeJS App along with PostgreSQL as a Docker image. Additionally, we are going to use Express.js and Sequelize ORM.

Here we go.

Project Structure

As the post is aiming to discuss deployment issues, we are going to pass the installation of the environment as quickly as possible. So let’s run this command in a shell:

npx express-generator example-project

It will create a project directory called example-project, let’s open it in a text editor. Then install the dependencies and run the project.

npm i && npm start//or with yarn
yarn && yarn start

The project will run on port 3000 of your localhost. Now we are going to create our database schemas using Sequelize ORM. Create a file called .sequelizerc in the project root folder and add these lines to it:

const path = require(‘path’)

;module.exports = {
  ‘config’: path.resolve(‘config’, ‘config.js’),
  ‘models-path’: path.resolve(‘db’, ‘models’),
  ‘seeders-path’: path.resolve(‘db’, ‘seeders’),
  ‘migrations-path’: path.resolve(‘db’, ‘migrations’)
};

Then install the sequelize library with npm or yarn. Once you have installed it, run this command:

npx sequelize-cli init

This command, using the .sequelizerc file, will create two directories. One is the config folder which includes database configurations and the other called db which has database models along with other directories that we are not going to talk about in this post.

And we need to install the pg package to use PostgreSQL in our NodeJS app.

Database Structure

In this section, we are going to configure a database structure. First, rename the config/database.json file as config/config.js. Then open the .sequelizerc file and change database.json to config.js. It helps Sequelize to find the configuration file. Change the content of the config/config.js like that:

module.exports = {
development: {
username: “postgres”,
password: “postgres”,
database: “postgres”,
host: “localhost”,
dialect: “postgres”,
},
test: {
username: process.env.CI_DB_USERNAME,
password: process.env.CI_DB_PASSWORD,
database: process.env.CI_DB_NAME,
host: process.env.CI_DB_HOSTNAME,
dialect: “postgres”,
},
production: {
username: process.env.PROD_DB_USERNAME,
password: process.env.PROD_DB_PASSWORD,
database: process.env.PROD_DB_NAME,
host: process.env.PROD_DB_HOSTNAME,
dialect: “postgres”,
},
};

Now we are going to create our first model. Let’s run this command:

npx sequelize-cli model:generate –name User –attributes firstName:string,lastName:string,email:string

It will create a file called user.js inside the db/model directory. And by that, we created our first model.

Next, we need to start the database connection before the app starts. To do that let’s call db class which is exported from the db/models/index.js and change relevant lines like that in the bin/www file:

const db = require(“../db/models”);

..

./**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
db.sequelize.sync({ force: false }).then(function () {
  server.on(“error”, onError);
  server.on(“listening”, onListening);
  console.log(“Database created successfully.”);
});

It is time to create a route to add some users. Let’s go.

Creating Database Record

Let’s open routes/index.js and change it like that:

var express = require(“express”);
var router = express.Router();
const db = require(“../db/models/index”);

/* GET users listing. */
router.get(“/”, async function (req, res, next) {
  const users = await db.User.findAll();
  res.render(“index”, { users });
});
/*POST user*/
router.post(“/”, async function (req, res, next) {
  const newUser = await db.User.create({ …req.body });
  res.json(newUser);
});

module.exports = router;

That’s it. We have created our first two routes one for creating users and the other for listing them.

Now, we need to change the frontend slightly so that we can add and list users via the app. So, change views/index.jade like that:

extends layout

block content
  h1= title
  p Welcome to #{title}
  form(name=”add-estimation”, method=”post”)
    div.input
        span.label First Name
        input(type=”text”, name=”firstName”)
    div.input
        span.label Last Name
        input(type=”text”, name=”lastName”)
    div.input
        span.label Email
        input(type=”text”, name=”email”)
    div.actions
        input(type=”submit”, value=”Add”)
  if users
    ul
      each user in users
        if user
          li=user.firstName + ” ” + user.lastName + ” ” + user.email

It is time to create Docker configuration files.

Docker Configuration

First, we need a Dockerfile. This is going to be like that:

FROM node:12.13.0-alpine

RUN mkdir -p /opt/app

WORKDIR /opt/app

RUN adduser -S app

COPY . .

RUN npm install

RUN chown -R app /opt/app

USER app

EXPOSE 3000

CMD [ “npm”, “start” ]

Then we need to create a docker-compose.yaml file and put these lines in it:

version: “3.7”
services:
  postgres:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      – “5432:5432”
    volumes:
      – example-db:/var/lib/postgresql/data

example:
    build:
      context: .
    environment:
      PROD_DB_NAME: postgres
      PROD_DB_USERNAME: postgres
      PROD_DB_PASSWORD: postgres
      PROD_DB_HOSTNAME: postgres
    depends_on:
      – postgres
    ports:
      – “3000:3000”

volumes:
  example-db:

Now, we need persistent data storage that the database will use so that our data isn’t removed in case the container is going down. Persistent data storage are added as running this command:

docker volume create example-db

Now run these commands and then go to the http://localhost:3000

docker build -t example-project . && docker-compose up -d

You will see a form in the http://localhost:3000:

metin, tablo içeren bir resim Açıklama otomatik olarak oluşturuldu

Let’s add a user. Then reload the page. You should see the user you added on the page.

Finally to make sure that the persistent volume works successfully, lets down and up the Docker containers with this command:

docker-compose down && docker-compose up -d

After that, if you still see the user you added in the http://localhost:3000, then congratulations, you have Dockerized a NodeJS app with a PostgreSQL database, using Express.js and Sequelize ORM!

Arda Örkin – Software Developer

 

No Comments

Sorry, the comment form is closed at this time.