Multi-Environment Docker
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