DEV Community

Bryan
Bryan

Posted on • Edited on • Originally published at devlogbook.com

Setting Up Node App using Docker

Create a docker setup to build an Express app with MySQL and Redis

  1. Create a directory and go switch to it

    mkdir nodeapp
    cd nodeapp
    
  2. Create package.json

    To avoid installing Node locally, we will use this docker command to npm init

    docker run --rm -v "$PWD:/$(basename $PWD)" -w "/$(basename $PWD)" -it node:current-alpine sh -c "npm init"
    
  3. Install dotenv and express packages

    docker run --rm -v "$PWD:/$(basename $PWD)" -w "/$(basename $PWD)" -it node:current-alpine sh -c "npm install dotenv express"
    
    docker run --rm -v "$PWD:/$(basename $PWD)" -w "/$(basename $PWD)" -it node:current-alpine sh -c "npm install --save-dev nodemon"
    
  4. Edit package.json to add to scripts section

    "start": "node index.js",
    "dev": "nodemon index.js"
    
  5. Create .env

    APP_PORT=3000
    DOCKER_PORT=3000
    
    #db is the service name in docker-compose.yml
    DB_HOST=db
    DB_PORT=3306
    DB_NAME=nodeapp
    
    #can be left blank if using root username
    DB_USERNAME=
    DB_PASSWORD=
    DB_PORT=3306
    
    #redis is the service name in docker-compose.yml
    REDIS_HOST=redis
    REDIS_PASSWORD=null
    REDIS_PORT=6379
    
  6. Create Dockerfile

    #change node version to your liking
    FROM node:18
    WORKDIR /app/
    COPY ./package.json .
    RUN npm install
    COPY ./* .
    EXPOSE $DOCKER_PORT
    
  7. Create docker-compose.yml

    version: '3'
    services: 
      web:
        build:
          context: .
        env_file: ./.env
        tty: true
        volumes: 
          - ./:/app/
          - node_modules:/app/node_modules
        ports:
          - '${APP_PORT:-3000}:${DOCKER_PORT:-3000}'
        depends_on: 
          - db
        networks:
          - nodeapp
      db:
        image: mysql:latest
        env_file: ./.env
        environment: 
          MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
          MYSQL_ROOT_HOST: "%"
          MYSQL_DATABASE: '${DB_NAME}'
          MYSQL_USER: '${DB_USERNAME}'
          MYSQL_PASSWORD: '${DB_USERNAME}'
          MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
        ports:
          - '${DB_PORT:-3306}:3306'
        volumes:
          - mysql:/var/lib/mysql
        networks:
          - nodeapp
      redis:
        image: 'redis:alpine'
        ports:
          - '${REDIS_PORT:-6379}:6379'
        volumes:
          - 'redis:/data'
        networks:
          - nodeapp
        healthcheck:
          test: ["CMD", "redis-cli", "ping"]
          retries: 3
          timeout: 5s
    networks:
      nodeapp:
        driver: bridge
    volumes:
      node_modules:
        driver: local
      mysql: 
        driver: local
      redis:
        driver: local
    
  8. Create index.js

    require('dotenv').config();
    
    const express = require('express');
    const app = express();
    
    // Constants
    const PORT = process.env.DOCKER_PORT || 3000;
    const HOST = '0.0.0.0';
    
    // App
    app.get('/', (req, res) => {
        res.send('Hello World!');
    });
    
    app.listen(PORT, HOST, () => {
         console.log(`Running on http://${HOST}:${PORT}`);
    });
    
  9. Run docker-compose up -d

  10. Run docker-compose exec web npm run dev

  11. Go to http://localhost:3000 3000 will be APP_PORT

BONUS

To easily run npm commands, do the following

  1. Create a file with the name soar

    #!/bin/bash
    
    path=$(printf '%s\n' "${PWD##*/}")
    
    # get first arg
    arg1=$1
    
    if [[ $arg1 == "up" ]]; then
        command="docker-compose up -d"
        $command
    elif [[ $arg1 == "down" ]]; then
        command="docker-compose down"
        $command
    else
        # remove first arg
        shift
    
        # get rest of args
        argrest=$@
    
        # web is the service name in docker-compose.yml
        ccommand="docker-compose exec web $arg1 "$argrest""
    
        # run the command
        $command
    fi
    
  2. Make soar runnable

    chmod 700 soar
    
  3. Test it with

    ./soar npm -h
    
  4. Create an alias for ./soar to soar

    alias './soar'
    

    To make sure this is always available, you may add this to your shell configuration file in your home directory, such as ~/.zshrc or ~/.bashrc, and then restart your shell.

  5. Now you can start docker, run npm, or npx

    Start docker container

    soar up
    

    Stop docker container

    soar down
    

    Run npm

    soar npm list
    

    Run npx

    soar npx ...
    

Top comments (0)