Search code examples
dockerdocker-composedocker-build

How to run different ENTRYPOINT commands in docker-compose.yml for different build environments?


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?


Solution

  • 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.

    Dockerfile

    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"]
    

    compose.yml

    services:
      hello-world:
        image: hello-world:prod
        build: .
        ports:
        - 3000:3000
    

    compose.override.yml

    services:
      hello-world:
        image: hello-world:dev
        environment:
          NODE_ENV: development
        entrypoint: npm run dev
        build:
          target: builder
        volumes:
        - ./src:/src