Dockerfile: Is there any way to read variables from .env file

Viewed 14503

I want to read the PORT variable inside Dockerfile which is defined in .env file. Is there any way to do this?

This is my Dockerfile:

FROM node:11-alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

ENV PORT=3000

COPY . .

RUN npm install

EXPOSE 3000

CMD ["npm", "run", "start"]
2 Answers

UPDATED

After discussion in a chat was realised that there's no problem with the nodejs app container, and the issue comes from a wrongly configured nginx proxy.

Proof for the working nodejs app is the next docker-compose file.

version: "3"
services:
    api:
        build: .
    curl:
        image: curlimages/curl:7.70.0
        depends_on:
          - api
        entrypoint: ""
        command: curl -si --retry 5 --retry-delay 5 --retry-max-time 40 http://api:6000
        restart: on-failure

ORIGINAL

If you want to change the port while a build process (it will be static later when you run a container) then use build-args

docker build --build-arg APP_PORT=3000
FROM node:11-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ARG APP_PORT=80
EXPOSE ${APP_PORT}

COPY . .
RUN APP_PORT=${APP_PORT} npm install

CMD APP_PORT=${APP_PORT} npm run start

if you want to be able to change the port when you're starting a container - then build-args don't fit and you need to stay with env variables. Notice that after build EXPOSE can't be changed.

Anyway if you have different ports in EXPOSE and your app listens to - it doesn't break anything, the app's port will be available on the port you want, despite it wasn't specified in EXPOSE.

You can even skip EXPOSE in your file, because it's rather more a metadata information of your image than an instruction for a system to open the port: https://docs.docker.com/engine/reference/builder/#expose

Regardless of the EXPOSE settings, you can override them at runtime by using the -p flag.

if your image is static after the build (you don't plan to change .env) you can do next, then npm install and npm run start has the same env. And you're still allowed to change port later, but it won't affect npm install.

FROM node:11-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . .
RUN export $(cat .env) && npm install 

CMD export $(cat .env) && npm run start

if you have to keep CMD as an array - then we need to create a bootstrap script

FROM node:11-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . .
RUN export $(cat .env) && npm install

RUN echo '#!/usr/bin/env sh' > start.sh && echo 'export $(cat .env) && npm run start ${@}' >> start.sh
CMD ["sh", "./start.sh"]

you can use the ARG in your Dockerfile which is meant for this purpose.

Related