Search code examples
node.jsdockerdockerfiledocker-build

How to run different ENTRYPOINT commands in Dockerfile for different build environments?


Right now I have a single Dockerfile:

FROM node:12-slim

WORKDIR /

COPY ./package.json ./package.json
COPY ./dist ./dist

RUN npm install

ENTRYPOINT npm start
# ENTRYPOINT npm run dev

You see that I have 2 options for the ENTRYPOINT. 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 Dockerfile file?

Is there a way to pass some kind of build arguments / ENV variables? How do people usually handle this?

Here is how I run it:

docker run hello-world:latest

Solution

  • If you change ENTRYPOINT to CMD, you can easily override it at the docker run command line:

    # No ENTRYPOINT
    CMD npm start
    
    # The command after the image name overrides CMD
    docker run hello-world:latest npm run dev
    

    (There is a docker run --entrypoint option, but its syntax winds up being pretty awkward.)

    How do people usually handle this?

    I do as much development as I can outside of Docker. It's very rare for me to run into problems that are sensitive to exact interpreter versions, and the host environment often doesn't make a difference either. This is doubly true for front-end applications where the only thing that happens in Docker is the application build; all of the runtime and I/O happens in the end user's browser.

    # Without Docker
    npm run dev
    npm run test
    npm run lint
    
    # Ship it
    docker build -t my/image .
    docker run -p 3000:3000 my/image
    

    If at all possible, run the same image in test and production environments. Do not overwrite the code in the image with a bind mount or other volume mount.