Setting Up Node App using Docker
Create a docker setup to build a Node Express app with MySQL and Redis
Create a directory and go switch to it
mkdir nodeapp cd nodeapp
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"
Install
dotenv
andexpress
packagesdocker 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"
Edit
package.json
to add toscripts
section"start": "node index.js", "dev": "nodemon index.js"
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
Create
Dockerfile
#change node version to your liking FROM node:18 WORKDIR /app/ COPY ./package.json . RUN npm install COPY ./* . EXPOSE $DOCKER_PORT
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
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}`); });
Run
docker-compose up -d
Run
docker-compose exec web npm run dev
Go to
http://localhost:3000
3000 will be APP_PORT
BONUS
To easily run npm
commands, do the following
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 command="docker-compose exec web $arg1 "$argrest"" # run the command $command fi
Make
soar
runnablechmod 700 soar
Test it with
./soar npm -h
Create an alias for
./soar
tosoar
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.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 ...