Multi-Environment Docker

Tags
Learn how to utilize multi-stage Dockerfiles with build targets to support multiple environments.

It's quite helpful to be able to quickly fire up an application configured specifically for your environment using a single command. Utilizing multi-stage build and build targets we can accomplish this with Docker.

Multi-Stage Builds

Multi-stage builds allows you to compose a final image of multiple preliminary images in a single Dockerfile. By providing an AS keyword with a stage name allows you to reference that image in a subsequent build stage. For our purposes, we'll install all of our dependencies in an install stage and then COPY --from=install so that we have our dependencies in our final image. As we'll see later we can reference a stage as a build target in docker-compose.yml.

Dockerfiles

# First install all necessary dependencies as 'install' stage
FROM node:12-alpine3.11 AS install
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN yarn
COPY . .
# Build and run the application
FROM node:12-apline3.11 as build
WORKDIR /app
COPY --from=install /app /app
RUN yarn build
CMD ["node", "./dist/index.js" ]
EXPOSE 4000

Base docker-compose.yml

The base docker-compose.yml file should outline only the basic information of your services. Save all of the special coffiguration for differnet environments.

version: "3.8"
services:
db:
image: database/image
backend:
build: ./backend
depends_on:
- db
frontend:
build: ./frontend

Set up development environment

docker-compose automatically reads from both docker-compose.yml and docker-compose.override.yml which makes the override file perfect for configuring your development environment. Here we'll set a build target in the backend to create an image with our dependencies and then execute a development command.

version: "3.8"
services:
# ignore the db service as it doesn't change
backend:
build:
context: ./backend
# set the target to the install stage to stop the image at this step
target: install
# run the development script
command: "yarn develop"
# set a volume to listen to file changes for hot reloading
volumes:
- ./backend:/app
# frontend is set up similarly as backend
frontend:

Now running docker-compose up --build will run the application in development mode with hot reloading.

Let's stay in touch!

Follow me ontwitter