Create a docker setup to build an 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
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"
-
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 ccommand="docker-compose exec web $arg1 "$argrest"" # run the command $command fi
-
Make
soar
runnable
chmod 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 ...
Top comments (0)