This is my dockerfile :
FROM node:6-onbuild
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
ENV PORT 80
EXPOSE ${PORT}
CMD [ "npm","run", "start" ]
and in package.json I do have this :
"scripts": {
"start": "node start.js",
"stagestart": "NODE_ENV=content-staging node start.js"
}
the start script is for production, now I want a way to run the staging script in dockerfile. is there a way to read NODE_ENV inside dockerfile, so I can have one dockerfile which handle staging and production.
Here is two possible implementation.
FYI: you don't need to mention NODE_ENV in package.json if you already set NODE_ENV at the system level or set NODE_ENV during build time or runtime in docker.
Here Dockerfile as same but I used to alpine base image
FROM node:alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
ENV PORT 3000
ARG DOCKER_ENV
ENV NODE_ENV=${DOCKER_ENV}
RUN if [ "$DOCKER_ENV" = "stag" ] ; then echo your NODE_ENV for stage is $NODE_ENV; \
else echo your NODE_ENV for dev is $NODE_ENV; \
fi
EXPOSE ${PORT}
CMD [ "npm","run", "start" ]
when you build this Dockerfile with this command
docker build --build-arg DOCKER_ENV=stag -t test-node .
You will see at layer
---> Running in a6231eca4d0b your NODE_ENV for stage is stag
When you run this docker container and run this command your output will be
/usr/src/app # echo $NODE_ENV
stag
Simplest Approch same image and but set environment variable at run time
Your Dockerfile
FROM node:alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
ENV PORT 3000
EXPOSE ${PORT}
CMD [ "npm","run", "start" ]
Run this docker image with this command
docker build -t test-node .
docker run --name test -e NODE_ENV=content-staging -p 3000:3000 --rm -it test-node ash
So when you run this command at container you will see
/usr/src/app # echo $NODE_ENV
content-staging
So this is how you can start your node application with NODE_ENV without setting environment variable at package.json. So if your nodejs configuration is based on NODE_ENV it should pick configuration according to NODE_ENV .
You can use the ENV instruction to get the environment variable as an environment variable inside container. Have an entry point script that injects the available environment variable (perhaps something as simple as sed) in place of a placeholder variable name that is in your package.json file. Then start your node application. Obviously this will require you to make a few changes to your Dockerfile in regards to entrypoint script etc.
That is how I have achieved such things in the past.