Right now I have a single docker-compose.yml
:
version: "3"
services:
hello-world:
image: hello-world
build: .
environment:
NODE_ENV: development
ports:
- 3000:3000
entrypoint: npm run dev
# entrypoint: npm start
working_dir: /
volumes:
- ./distService:/distService
You see that I have 2 options for the entrypoint
command. When I'm developing, I need it to run npm run dev
. When I'm deploying it, I need it to run npm start
.
How can I do this while keeping a single docker-compose.yml
file?
Is there a way to pass some kind of build arguments / ENV variables to docker-compose? How do people usually handle this?
Well, first up, you want to build your Dockerfile with the production defaults, such as ENTRYPOINT, baked in.
Then, its easy to take advantage of the fact the docker-compose will process both a docker-compose.yml
, and a docker-compose.override.yml
by default.
So, build your basic production ready definition in the compose.yml
, and add the specific development overrides, such as local volumes mappings and entrypoints in the override file.
docker compose up
etc commands will automatically work with your development stack, production deployments can be done by specifying -f compose.yml
explicitly.
Here is an example of how this might be structured.
FROM node AS builder
# Your usual setup here
WORKDIR /src
FROM builder AS build
COPY /src .
RUN npm build
FROM node AS final
COPY --from=build /src/build /app
WORKDIR /app
ENTRYPOINT ["npm", "start"]
services:
hello-world:
image: hello-world:prod
build: .
ports:
- 3000:3000
services:
hello-world:
image: hello-world:dev
environment:
NODE_ENV: development
entrypoint: npm run dev
build:
target: builder
volumes:
- ./src:/src