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