I’ve tried passing NODE_ENV as an argument
ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}
I tried passing it as an environment variable on my docker-compose.yaml
services:
app:
build:
context: .
args:
- NODE_ENV=development
environment:
- PORT=3000
- NODE_ENV=development
Nothing works, inside my program, its value is "production"
My Dockerfile is based on node:18-slim
, there is nothing special on it.
Complete example
Dockerfile
FROM node:18-slim AS base
FROM base AS build
WORKDIR /opt
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
RUN npm run prisma:generate
FROM base
WORKDIR /app
RUN apt-get update &&
apt-get install --yes --no-install-recommends gettext-base supervisor nginx
COPY nginx.conf /etc/nginx/conf.d/configfile.template
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY --from=build /opt/node_modules node_modules
COPY --from=build /opt/dist .
ARG NODE_ENV
ENV NODE_ENV ${NODE_ENV}
ARG PORT=3000
ENV PORT $PORT
EXPOSE $PORT
CMD ["/usr/bin/supervisord"]
docker-compose.yaml
services:
app:
build:
context: .
args:
NODE_ENV: ${NODE_ENV:-development}
environment:
- PORT=3000
- DATABASE_URL=postgresql://docker:docker@postgres:5432/oidc?schema=public
- REDIS_HOST=redis
- REDIS_PORT=6379
ports:
- 3000:3000
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
redis:
image: redis:7
tmpfs:
- /data
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 1s
timeout: 5s
start_period: 5s
retries: 3
postgres:
image: postgres:14.3
tmpfs:
- /var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready --dbname $$POSTGRES_DB --username $$POSTGRES_USER"]
interval: 1s
timeout: 5s
start_period: 5s
retries: 3
environment:
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_USER: docker
POSTGRES_PASSWORD: docker
POSTGRES_DB: oidc
If I build without docker compose, it works.
docker compose version
Docker Compose version v2.15.1
docker-compose –version
Docker Compose version v2.15.1
docker version
Client:
Cloud integration: v1.0.31
Version: 20.10.23
API version: 1.41
Go version: go1.18.10
Git commit: 7155243
Built: Thu Jan 19 17:35:19 2023
OS/Arch: darwin/arm64
Context: default
Experimental: true
Server: Docker Desktop 4.17.0 (99724)
Engine:
Version: 22.06.0-beta.0-926-g914b02ebaf.m
API version: 1.43 (minimum version 1.12)
Go version: go1.18.4
Git commit: 914b02ebaf
Built: Thu Feb 9 12:31:06 2023
OS/Arch: linux/arm64
Experimental: true
containerd:
Version: 1.6.18
GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
I read somewhere else, that docker-compose never overwrites the environment variables from the base image. Is it because of that? My base image is a node
What I’m doing wrong?
2
Answers
See this answer docker-compose build environment variable
Are you setting the variable in your docker file? Something like:
I think the problem could be related, not to
docker-compose
, but actually to the way the application is being deployed.In the first stage of your
Dockerfile
you are building yournode
or SPA application.In the next stage you are exposing the result of that build (by the way, probably you can safely don’t copy the
node_modules
directory to the final image) throughnginx
andsupervisor
. But please, be aware that neithernginx
norsupervisor
have knowledge about theNODE_ENV
variable: that variable is only managed at runtime when the application is served withnode
, notnginx
(sorry if I am missing something at this point, this is why I asked you about thenginx
andsupervisor
configuration, I am not aware if in any way you are proxyingnode
, I hope you get the point).In order to make this variable visible to the application you probably will need to tweak the build process, or trying providing a helper script. Please, consider read for instance this or this other related SO questions, or this great post for further reference.