Local Development with Docker Compose
As the JS developer, your machine may already have many dev tools like nodejs, nvm, PostgreSQL, and so on. But let face it, if you have a new machine or have a new teammate join the projects, it's still quite time-consuming to set up a local development environment from scratch without spending a half-day. Lucky we can leverage container to set up the local development environment with the following benefits:
- Able to run on any OS, Mac, Windows, and Linux.
- Save time to set up a local development environment.
- Easy to create a container with a specific node version.
Assume you already have docker desktop installed. If not, let download and install it before moving on.
Dockerising Nextjs with Dockerfile
Create Dockerfile inside your nextjs root folder
FROM node:current-alpine
WORKDIR /base
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
- FROM node:current-alpine - Use
node:current-alpine
as the base image. - WORKDIR /base - Specify base folder inside container as working directory.
- COPY package*.json ./ - Copy package.json and package-lock.json from host machine to container root folder.
- RUN npm install - Run
npm install
in the container. - COPY . . - Copy all files from host to the container working directory.
Bring up Nextjs and PostgreSQL services with docker compose
Create docker-compose.yml inside your nextjs root folder
version: '3'
services:
npm:
build: ./
working_dir: /base
volumes:
- .:/base
- app_node_modules:/base/node_modules
entrypoint: npm
dev:
build: ./
working_dir: /base
volumes:
- .:/base
- app_node_modules:/base/node_modules
ports:
- "3000:3000"
networks:
- app_network
depends_on:
- postgres
command: npm run dev
postgres:
image: 'postgres:13'
ports:
- '${FORWARD_DB_PORT:-5432}:5432'
environment:
PGPASSWORD: '${DB_PASSWORD:-secret}'
POSTGRES_DB: '${DB_DATABASE}'
POSTGRES_USER: '${DB_USERNAME}'
POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
volumes:
- 'app_db_data:/var/lib/postgresql/data'
networks:
- app_network
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"]
networks:
app_network:
driver: bridge
volumes:
app_node_modules:
app_db_data:
driver: local
- version: '3' - Indicate which docker engine version using. E.g 3 mean using docker engine 1.13.0+. For more info, visit Compose file version 3 reference.
- services - Specify the container services you want to compose. For our case, we have three services
npm
,dev
, andpostgres
.
npm service
- build: ./ - Specify the current root folder as directory for build the docker image.
- working_dir: /base - Specify base folder inside container as working directory.
- entrypoint: npm - Allow us to execute npm command inside the container with syntax like
docker-compose run npm install
volumes
- .:/base: Mapping current host folder to container working directory.
- app_node_modules:/base/node_modules - Mapping app_node_modules volume to container
/base/node_modules
folder
dev service
- build: ./ - Specify the current root folder as directory for build the docker image.
- working_dir: /base - Specify base folder inside container as working directory.
- .:/base: Mapping current host folder to container working directory.
- app_node_modules:/base/node_modules - Mapping app_node_modules volume to container
/base/node_modules
folder. - command: npm run dev - Default command to run when container start.
ports
- 3000:3000 - Mapping the host port 3000 to container port 3000.
networks
- app_network - Specify which network to use. In this case, we use
app_network
depends_on
- postgres - This container will only start after postgres start.
postgres service
- image: 'postgres:13' - We will use postgres:13 the base image.
ports
- ${FORWARD_DB_PORT:-5432}:5432 - If FORWARD_DB_PORT environment variable exist, it will mapping that FORWARD_DB_PORT from host to container port 5432. Otherwise, it will mapping host port 5432 to container port 5432
environment
- PGPASSWORD: '${DB_PASSWORD:-secret}' - If DB_PASSWORD environment variable exist, it will be used for db password, otherwisw it will use secret as the db password.
- POSTGRES_DB: '${DB_DATABASE}' - If DB_DATABASE environment variable exist, it will be used for db database name.
- POSTGRES_USER: '${DB_USERNAME}' - If DB_USERNAME environment variable exist, it will be used for db username.
- POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' - If DB_PASSWORD environment variable exist, it will be used for db password, otherwisw it will use secret as the db password.
volumes
- .:/base: Mapping current host folder to container working directory.
- app_db_data:/var/lib/postgresql/data - Mapping app_db_data volume to container
/var/lib/postgresql/data
folder
networks
- app_network - Specify which network to use. In this case, we use
app_network
healthcheck
- test: "CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}" - Command to check this container is healthy.
networks
We specify the network name as app_network
with bridge network.
volumes
We defined two volumes
- app_node_modules - For storing node modules packages.
- app_db_data - For storing postgresql data.
Finally, run the following command to start your nextjs and postgresql in container:
docker-compose up
Useful docker-compose commands
build the docker container
docker-compose build
start the docker container
docker-compose up
remove all docker containers in the repository
docker-compose down
More Stories
Web analytics with Ackee on Vercel
Bootstrapping SaaS business from Zero to Profitable is hard. You have to pay for every single must-have service like web analytics before earning a buck.
Get the best Next.js boilerplate at the lowest price ever!
Today, we offer a 90% discount for the best Next.js boilerplate at the lowest price ever.