Docker ENV, ARG, and docker-compose environment

Where does entrypoint.sh in Dockerfile get env variables from?

  • Does docker compose pass them directly when a dockerfile is specified?

  • Does the dockerfile need to have them specified in any way in order to pass them to entrypoint.sh?

So the ARG are received when running docker run ... whereas ENV are populated with ARG or docker compose envirnoment if passed?

Many questions I end up returning to, so let’s clarify how environment variables, ARG, and ENV work together in docker and docker compose.

  1. ARG:

    • Used for build-time arguments in the Dockerfile.
    • Accessible only during the image build process and not in the running container unless explicitly mapped.
    • Set using docker build --build-arg or the args section in docker-compose.yml.
  2. ENV:

    • Used to define environment variables within the Dockerfile.
    • Accessible in the running container and therefore available to entrypoint.sh.
    • Can be set to a fixed value, or assigned the value of an ARG to transfer a build-time value to runtime.
  3. docker-compose.yml environment section:

    • Sets environment variables for runtime in the container.
    • Passes these directly to the container at runtime, meaning they will be available to entrypoint.sh and the running application.
    • Takes precedence over ENV variables defined in the Dockerfile.
  4. entrypoint.sh:

    • Runs in the container at runtime.
    • Receives environment variables directly from Docker Compose’s environment section and any ENV variables set in the Dockerfile.

Step-by-Step Behavior

1. During the Dockerfile Build Process

  • ARG Variables:

    • These are only available during the docker build step.
    • You can set them with ARG in the Dockerfile and pass them through docker-compose.yml using args.
    • Example:
      build:
        args:
          APP_PORT: ${APP_PORT}
      
  • ENV Variables in the Dockerfile:

    • ENV can be used to make ARG values persist into the container runtime.
    • For example:
      ARG APP_PORT
      ENV APP_PORT=${APP_PORT}
      

2. At Runtime in docker-compose.yml

  • Variables defined in the environment section in docker-compose.yml (e.g., APP_PORT=${APP_PORT}) are passed directly to the container and take precedence over any ENV values in the Dockerfile.

3. entrypoint.sh Access to Environment Variables

  • entrypoint.sh runs when the container starts and can access:
    • Any variables defined in docker-compose.yml environment (like APP_PORT=${APP_PORT}).
    • Any variables defined with ENV in the Dockerfile if they aren’t overridden by Docker Compose.

Example Workflow

Dockerfile.dev

# Build-time argument
ARG APP_PORT=5000

# ENV allows access to APP_PORT during runtime (if not overridden by docker-compose)
ENV APP_PORT=${APP_PORT}

# Other setup commands

docker-compose.dev.yml

version: '3.9'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile.dev
      args:
        APP_PORT: ${APP_PORT}  # Build-time ARG value passed here
    environment:
      - APP_PORT=${APP_PORT}  # Runtime environment variable for the container

Summary Table

Source Purpose Accessible In Typical Use
ARG in Dockerfile Build-time Only during docker build Build configurations (e.g., which port to expose)
ENV in Dockerfile Runtime Inside the container Setting runtime defaults
environment in Compose Runtime Inside the container Custom environment variables for the container

In short:

  • ARG values are only for build but can be mapped to ENV to persist at runtime.
  • ENV and environment values are available at runtime for scripts like entrypoint.sh.
  • Docker Compose’s environment section takes precedence at runtime.