Graduate Program KB

Containerizing Databases

Create a new Node.js module using npm:

mkdir brain-school-05
cd brain-school-05
npm init

Create a docker-compose.yaml file

touch docker-compose.yaml
  1. Add the following content to your docker-compose.yaml file:
version: "3.8"

services:
  node_app:
    build: .
    ports:
      - "3000:3000"
    env_file:
      - ./neo4j/.neo4j.env
      - ./mongo/.mongo.env
      - ./mysql/.mysql.env
      - ./postgres/.postgres.env
    restart: always
    depends_on:
      - mongo
      - postgres
      - mysql
      - neo4j

  neo4j:
    image: neo4j:5.6.0
    env_file: ./neo4j/.neo4j.env
    restart: always
    ports:
      - "7474:7474"
      - "7687:7687"
    volumes:
      - neo4j-data:/data
      - neo4j-logs:/logs

  mongo:
    image: mongo:6.0
    env_file: ./mongo/.mongo.env
    restart: always
    ports:
      - "27017:27017"
    volumes:
      - ./mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js
      - mongo-data:/data/db

  postgres:
    image: postgres:latest
    env_file: ./postgres/.postgres.env
    restart: always
    ports:
      - "5732:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data

  mysql:
    image: mysql:latest
    command: --authentication-policy=mysql_native_password
    restart: always
    env_file: ./mysql/.mysql.env
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mongo-data:
  postgres-data:
  mysql-data:
  neo4j-data:
  neo4j-logs:

This docker-compose.yaml file describes a multi-container Docker application, which includes a Node.js app and several databases (MongoDB, PostgreSQL, MySQL, and Neo4j). Docker Compose is a tool that allows defining and running multi-container Docker applications using a single YAML file. This file has the following components:

  1. version: Specifies the version of the Docker Compose file format (3.8).

  2. services: Lists the services (containers) that make up the application:

    • node_app: The Node.js application container. It has the following settings:

      • build: . Builds the image using the Dockerfile in the current directory.
      • ports: ["3000:3000"] Maps the container's port 3000 to the host machine's port 3000.
      • env_file: ... Specifies the environment files containing environment variables for the Node.js app.
      • restart: always Always restarts the container if it stops.
      • depends_on: Specifies the services that this container depends on, which are mongo, postgres, mysql, and neo4j.
    • neo4j: The Neo4j graph database container. It has the following settings:

      • image: neo4j:5.6.0 Specifies the Neo4j image with the tag 5.6.0.
      • env_file: ./neo4j/.neo4j.env Specifies the environment file containing environment variables for the Neo4j database.
      • restart: always Always restarts the container if it stops.
      • ports: Maps the container's ports 7474 and 7687 to the host machine's corresponding ports.
      • volumes: Mounts the named volumes neo4j-data and neo4j-logs to the container's /data and /logs directories, respectively.
    • mongo: The MongoDB container. It has the following settings:

      • image: mongo:6.0 Specifies the MongoDB image with the tag 6.0.
      • env_file: ./mongo/.mongo.env Specifies the environment file containing environment variables for the MongoDB database.
      • restart: always Always restarts the container if it stops.
      • ports: ["27017:27017"] Maps the container's port 27017 to the host machine's port 27017.
      • volumes: Mounts the init-mongo.js script and the named volume mongo-data to the container's /docker-entrypoint-initdb.d/init-mongo.js and /data/db directories, respectively.
    • postgres: The PostgreSQL container. It has the following settings:

      • image: postgres:latest Specifies the latest PostgreSQL image.
      • env_file: ./postgres/.postgres.env Specifies the environment file containing environment variables for the PostgreSQL database.
      • restart: always Always restarts the container if it stops.
      • ports: ["5732:5432"] Maps the container's port 5432 to the host machine's port 5732.
      • volumes: Mounts the named volume postgres-data to the container's /var/lib/postgresql/data directory.
    • mysql: The MySQL container. It has the following settings:

      • image: mysql:latest Specifies the latest MySQL image.
      • command: --authentication-policy=mysql_native_password Sets the authentication policy to use the MySQL native password.
      • restart: always Always restarts the container if it stops.
      • env_file: ./mysql/.mysql.env Specifies the environment file containing environment variables for the MySQL database.
      • ports: ["3306:3306"] Maps the container's port 3306 to the host machine's port 3306.
      • volumes: Mounts the named volume mysql-data to the container's /var/lib/mysql directory.
  3. volumes: Defines the named volumes used by the containers. Named volumes are useful for persisting data and sharing it between containers. In this file, the following named volumes are defined:

    • mongo-data Used by the MongoDB container to store its data.
    • postgres-data Used by the PostgreSQL container to store its data.
    • mysql-data Used by the MySQL container to store its data.
    • neo4j-data Used by the Neo4j container to store its data.
    • neo4j-logs Used by the Neo4j container to store its logs.

In summary, this docker-compose.yaml file defines a multi-container Docker application consisting of a Node.js app and four different database services (MongoDB, PostgreSQL, MySQL, and Neo4j). Each service runs in its own container, with specified environment variables, port mappings, and volume mounts.

Next, add a directory to hold each service's configuration files:

mkdir mongo;
mkdir mysql;
mkdir neo4j;
mkdir postgres;

Lets add the configuration files for the mongo service:

touch mongo/.mongo.env;
touch mongo/init-mongo.js;

Add the following content to the .mongo.env:

MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=admin
MONGO_INITDB_DATABASE=brain-school-05
MONGO_USER=alanbilby
MONGO_PASSWORD=lovememahlots

Add the following content to init-mongo.js:

db.getSiblingDB("admin").auth(
  process.env.MONGO_INITDB_ROOT_USERNAME,
  process.env.MONGO_INITDB_ROOT_PASSWORD
);
db.createUser({
  user: process.env.MONGO_USER,
  pwd: process.env.MONGO_PASSWORD,
  roles: ["readWrite"],
});

Lets add the configuration files for the mysql service:

touch mysql/.mysql.env;

Add the following content to .mysql.env:

MYSQL_ROOT_PASSWORD=root
MYSQL_USER=alanbilby
MYSQL_PASSWORD=lovememahlots
MYSQL_DATABASE=brain-school-05

Lets add the configuration files for the postgres service:

touch postgres/.postgres.env;

Add the following content to .postgres.env:

POSTGRES_USER=alanbilby
POSTGRES_PASSWORD=lovememahlots
POSTGRES_DB=brain-school-05

Lets add the configuration files for the neo4j service:

touch neo4j/.neo4j.env;

Add the following content to the .neo4j.env:

USER=neo4j
PASSWORD=lovememahlots
AUTH=neo4j/lovememahlots

Now we need to add a directory to hold our Node.js application's source files:

mkdir old;

Add an entrypoint for our Node.js application in the src directory we just created

touch old/index.js

Add the following content to your index.js file:

console.log('Add your application code here!');

You can now start the services specified in your docker-compose.yaml file by running the following command:

docker-compose up

Mounting a source directory on the host into a running container

Here's a basic docker-compose.yml file for a Node.js application, with the source folder mounted as a volume:

version: '3.8'

services:
  node-app:
    image: node:18
    container_name: node-app-container
    command: npm start
    environment:
      - NODE_ENV=development
    volumes:
      - ./old:/app/old
      - ./package.json:/app/package.json
      - ./package-lock.json:/app/package-lock.json
    working_dir: /app
    ports:
      - "3000:3000"

This docker-compose.yml file does the following:

  1. Defines a service named node-app that uses the node:18 image.
  2. Sets the container name to node-app-container .
  3. Runs npm start as the container's main command.
  4. Sets the NODE_ENV environment variable to development .
  5. Mounts the src folder, package.json , and package-lock.json from the host machine to the appropriate locations within the container.
  6. Sets the container's working directory to /app .
  7. Maps port 3000 on the host machine to port 3000 within the container.

Remember to replace the image version, path, and port numbers with the appropriate values for your specific application.