skip to Main Content

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


  1. See this answer docker-compose build environment variable

    Are you setting the variable in your docker file? Something like:

    ARG NODE_ENV
    ENV NODE_ENV $NODE_ENV
    
    Login or Signup to reply.
  2. 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 your node 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) through nginx and supervisor. But please, be aware that neither nginx nor supervisor have knowledge about the NODE_ENV variable: that variable is only managed at runtime when the application is served with node, not nginx(sorry if I am missing something at this point, this is why I asked you about the nginx and supervisor configuration, I am not aware if in any way you are proxying node, 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search