Docker 환경 변수(Environment Variables) 완벽 가이드! ENV·-e·.env 파일 사용법 총정리

Docker 컨테이너를 실행할 때 데이터베이스 주소, 포트 번호, 애플리케이션 실행 모드, API 주소처럼 환경마다 달라지는 설정이 필요합니다.

이러한 값을 Docker 이미지 안에 직접 작성하면 개발 서버와 운영 서버마다 이미지를 새로 만들어야 하며, 비밀번호나 인증 정보가 이미지에 포함될 위험도 있습니다.

이 문제를 해결하기 위해 Docker에서는 환경 변수(Environment Variable)를 사용합니다.

이번 글에서는 Docker 환경 변수의 개념부터 Dockerfile의 ENV, docker run -e, --env-file, Docker Compose의 environment, .env 파일 사용법과 주의사항까지 자세히 알아보겠습니다.

Docker 환경 변수란?

환경 변수는 애플리케이션이 실행될 때 참조할 수 있는 이름과 값의 조합입니다.

예를 들어 다음과 같은 설정을 환경 변수로 관리할 수 있습니다.

APP_ENV=production
APP_PORT=8080
DB_HOST=mysql
DB_PORT=3306

애플리케이션은 설정 파일에 값을 고정하지 않고 환경 변수를 읽어 실행 환경을 결정합니다.

전체 구조는 다음과 같습니다.

Docker Host

↓

환경 변수 전달

↓

Docker Container

↓

Application에서 환경 변수 사용

환경 변수를 사용하면 같은 Docker 이미지를 개발, 테스트, 운영 환경에서 재사용할 수 있습니다.

환경 변수가 필요한 이유

환경 변수를 사용하면 다음과 같은 장점이 있습니다.

  • 환경별 설정 분리
  • 동일한 이미지 재사용
  • 설정 변경 간소화
  • Docker Compose 연동
  • CI/CD 자동화
  • 설정값을 코드와 분리
  • 데이터베이스 주소와 포트 관리

예를 들어 개발 환경에서는 다음 값을 사용할 수 있습니다.

APP_ENV=development
DB_HOST=localhost

운영 환경에서는 다음처럼 변경할 수 있습니다.

APP_ENV=production
DB_HOST=production-db

Docker 이미지는 변경하지 않고 실행할 때 전달하는 값만 바꾸면 됩니다.

Dockerfile ENV 명령어

Dockerfile에서는 ENV 명령어로 기본 환경 변수를 설정할 수 있습니다.

FROM node:22

ENV NODE_ENV=production
ENV PORT=8080

WORKDIR /app

COPY . .

CMD ["node", "server.js"]

이미지를 빌드한 뒤 컨테이너를 실행하면 NODE_ENVPORT 환경 변수가 기본으로 설정됩니다.

환경 변수를 확인하려면 다음 명령을 사용합니다.

docker run --rm myapp env

특정 환경 변수만 확인할 수도 있습니다.

docker run --rm myapp printenv NODE_ENV

출력 결과는 다음과 같습니다.

production

ENV 여러 개 작성하기

환경 변수를 각각 작성할 수 있습니다.

ENV APP_ENV=production
ENV APP_PORT=8080
ENV LOG_LEVEL=info

한 줄로 작성하는 것도 가능합니다.

ENV APP_ENV=production \
    APP_PORT=8080 \
    LOG_LEVEL=info

가독성을 고려해 관련 있는 값끼리 묶어 작성하면 관리하기 편리합니다.

docker run -e 옵션 사용법

컨테이너 실행 시 -e 또는 --env 옵션을 사용하면 환경 변수를 직접 전달할 수 있습니다.

docker run -d \
--name web \
-e APP_ENV=production \
-e APP_PORT=8080 \
myapp

컨테이너 내부에서 값을 확인합니다.

docker exec web printenv APP_ENV

출력 결과는 다음과 같습니다.

production

Dockerfile ENV 값 덮어쓰기

Dockerfile에 기본값이 있어도 컨테이너 실행 시 -e 옵션으로 값을 변경할 수 있습니다.

Dockerfile 설정은 다음과 같습니다.

ENV APP_ENV=development

실행할 때 운영 환경으로 변경합니다.

docker run --rm \
-e APP_ENV=production \
myapp \
printenv APP_ENV

출력 결과는 다음과 같습니다.

production

일반적으로 실행 시 전달한 환경 변수가 Dockerfile에 정의된 기본값보다 우선합니다.

호스트 환경 변수 전달하기

호스트에 이미 설정된 환경 변수를 컨테이너에 전달할 수도 있습니다.

호스트에서 값을 설정합니다.

export APP_ENV=production

변수 이름만 지정하여 컨테이너에 전달합니다.

docker run --rm \
-e APP_ENV \
ubuntu \
printenv APP_ENV

출력 결과는 다음과 같습니다.

production

값을 명령어에 직접 작성하지 않고 현재 셸의 환경 변수를 사용할 때 편리합니다.

–env-file 사용법

환경 변수가 많아지면 -e 옵션을 반복해서 작성하기 불편합니다.

이때 환경 변수 파일을 사용할 수 있습니다.

app.env 파일을 생성합니다.

APP_ENV=production
APP_PORT=8080
DB_HOST=mysql
DB_PORT=3306

컨테이너 실행 시 파일을 지정합니다.

docker run -d \
--name web \
--env-file app.env \
myapp

파일에 작성된 모든 환경 변수가 컨테이너에 전달됩니다.

env 파일 작성 시 주의사항

일반적인 환경 변수 파일은 다음 형식으로 작성합니다.

KEY=value

예시는 다음과 같습니다.

APP_NAME=myapp
APP_PORT=8080
LOG_LEVEL=info

등호 앞뒤에 불필요한 공백을 넣지 않는 것이 좋습니다.

APP_PORT = 8080

위와 같은 형식은 예상하지 못한 값으로 처리되거나 오류 원인이 될 수 있습니다.

다음과 같이 작성하는 것이 안전합니다.

APP_PORT=8080

Docker Compose environment 사용법

Docker Compose에서는 environment 항목으로 환경 변수를 전달할 수 있습니다.

services:
  web:
    image: myapp
    environment:
      APP_ENV: production
      APP_PORT: 8080
      DB_HOST: mysql

목록 형식으로도 작성할 수 있습니다.

services:
  web:
    image: myapp
    environment:
      - APP_ENV=production
      - APP_PORT=8080
      - DB_HOST=mysql

두 방식 모두 사용할 수 있지만, 키와 값을 구분하는 형식이 읽기 편한 경우가 많습니다.

Docker Compose env_file 사용법

환경 변수를 별도 파일로 관리하려면 env_file을 사용합니다.

services:
  web:
    image: myapp
    env_file:
      - app.env

app.env 파일은 다음과 같습니다.

APP_ENV=production
APP_PORT=8080
DB_HOST=mysql

Compose를 실행합니다.

docker compose up -d

app.env 파일의 값이 컨테이너 환경 변수로 전달됩니다.

.env 파일이란?

Docker Compose는 프로젝트 디렉터리의 .env 파일을 변수 치환에 사용할 수 있습니다.

.env 파일을 작성합니다.

APP_IMAGE=myapp
APP_PORT=8080
DB_PASSWORD=example-password

compose.yaml에서 다음처럼 참조합니다.

services:
  web:
    image: ${APP_IMAGE}
    ports:
      - "${APP_PORT}:8080"

  mysql:
    image: mysql:8.4
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}

Compose 실행 시 ${변수명} 부분이 .env 파일 값으로 변경됩니다.

.env와 env_file의 차이

.envenv_file은 비슷해 보이지만 용도가 다릅니다.

구분주요 용도
.envCompose 설정 파일의 변수 치환
env_file컨테이너 내부에 환경 변수 전달
environmentCompose 파일에서 컨테이너 환경 변수 직접 지정
docker run -e명령줄에서 환경 변수 전달

예를 들어 .env 파일의 WEB_PORT 값을 Compose 포트 설정에 사용할 수 있습니다.

WEB_PORT=8080
services:
  web:
    image: nginx
    ports:
      - "${WEB_PORT}:80"

반면 컨테이너 내부에서 직접 사용해야 하는 값은 environment 또는 env_file로 전달합니다.

환경 변수 우선순위 이해하기

같은 환경 변수가 여러 위치에 설정되어 있으면 나중에 전달되는 값이나 실행 시 지정한 값이 우선하는 경우가 많습니다.

예를 들어 Dockerfile에는 다음 값이 있습니다.

ENV APP_ENV=development

Compose 파일에는 다음 값이 있습니다.

environment:
  APP_ENV: staging

실행 시 명령줄에서 값을 다시 전달합니다.

docker compose run \
-e APP_ENV=production \
web \
printenv APP_ENV

출력 결과는 다음과 같습니다.

production

실무에서는 같은 변수의 정의 위치가 너무 많아지지 않도록 관리 기준을 정하는 것이 중요합니다.

컨테이너 환경 변수 확인 방법

실행 중인 컨테이너의 전체 환경 변수를 확인합니다.

docker exec web env

특정 변수만 확인합니다.

docker exec web printenv DB_HOST

또는 Shell을 통해 확인할 수 있습니다.

docker exec web sh -c 'echo $DB_HOST'

Docker Inspect를 사용해 설정된 환경 변수를 확인할 수도 있습니다.

docker inspect web

출력 내용이 많다면 다음처럼 필요한 부분만 조회합니다.

docker inspect \
--format='{{range .Config.Env}}{{println .}}{{end}}' \
web

애플리케이션에서 환경 변수 읽기

Node.js에서는 다음과 같이 읽습니다.

const port = process.env.APP_PORT || 8080;
const environment = process.env.APP_ENV || "development";

Python에서는 다음과 같이 사용합니다.

import os

app_env = os.getenv("APP_ENV", "development")
app_port = os.getenv("APP_PORT", "8080")

Java Spring Boot에서는 다음 형식으로 참조할 수 있습니다.

spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}

애플리케이션 코드에 값을 고정하지 않고 환경 변수로 외부에서 전달하는 것이 핵심입니다.

환경 변수와 비밀번호 보안

환경 변수는 설정값을 분리하는 데 유용하지만 완전한 비밀 저장소는 아닙니다.

다음 명령을 통해 환경 변수가 노출될 수 있습니다.

docker inspect web

또는 컨테이너 내부에서 확인할 수 있습니다.

docker exec web env

따라서 중요한 운영 비밀번호와 API 키는 다음과 같은 방식으로 관리하는 것이 좋습니다.

  • 환경 변수 파일을 Git에 올리지 않기
  • .gitignore.env 추가
  • 운영 서버의 접근 권한 제한
  • CI/CD Secret 기능 사용
  • Docker Secrets 또는 외부 비밀 관리 도구 사용
  • 이미 빌드된 이미지에 비밀번호 포함하지 않기

.gitignore 예시는 다음과 같습니다.

.env
*.env
secrets/

Dockerfile에 비밀번호를 넣으면 안 되는 이유

다음과 같은 Dockerfile 작성은 피해야 합니다.

ENV DB_PASSWORD=my-secret-password

이 값은 이미지 설정과 빌드 기록에 남을 수 있으며, 이미지를 공유하면 다른 사용자에게 노출될 수 있습니다.

민감한 값은 이미지 빌드 단계가 아니라 컨테이너 실행 단계에서 전달하는 것이 좋습니다.

docker run -d \
-e DB_PASSWORD="$DB_PASSWORD" \
myapp

환경 변수가 적용되지 않을 때 확인할 사항

환경 변수가 정상적으로 적용되지 않는다면 다음 순서로 확인합니다.

1. 컨테이너 내부 값 확인

docker exec web printenv APP_ENV

2. Compose 설정 검증

docker compose config

변수 치환이 완료된 최종 설정을 확인할 수 있습니다.

3. 컨테이너 재생성

Compose 파일이나 환경 변수를 수정한 뒤 단순 재시작만 하면 새로운 설정이 적용되지 않을 수 있습니다.

docker compose up -d --force-recreate

또는 다음 명령으로 컨테이너를 다시 생성합니다.

docker compose down
docker compose up -d

4. 변수 이름 확인

다음처럼 변수 이름의 오타를 점검합니다.

DB_HOST
DBHOST
DATABASE_HOST

애플리케이션이 기대하는 변수 이름과 Docker에서 전달한 이름이 같아야 합니다.

5. 따옴표와 공백 확인

환경 변수 값에 공백이나 특수문자가 포함되면 따옴표 처리가 필요할 수 있습니다.

environment:
  APP_MESSAGE: "hello docker"

실무에서 자주 사용하는 명령어

환경 변수 직접 전달

docker run -d \
-e APP_ENV=production \
myapp

여러 환경 변수 전달

docker run -d \
-e APP_ENV=production \
-e APP_PORT=8080 \
-e DB_HOST=mysql \
myapp

환경 변수 파일 사용

docker run -d \
--env-file app.env \
myapp

환경 변수 확인

docker exec web env

특정 변수 확인

docker exec web printenv APP_ENV

Compose 설정 확인

docker compose config

Compose에서 특정 환경 변수 전달

docker compose run \
-e APP_ENV=production \
web

실무 사례

온라인 쇼핑몰 애플리케이션을 Docker로 운영한다고 가정해 보겠습니다.

개발 환경에서는 다음 값을 사용합니다.

APP_ENV=development
DB_HOST=mysql-dev
DB_NAME=shop_dev

운영 환경에서는 다음 값을 사용합니다.

APP_ENV=production
DB_HOST=mysql-prod
DB_NAME=shop

애플리케이션 이미지는 동일하게 사용하고 환경 변수 파일만 구분합니다.

.env.development
.env.production

개발 환경 실행 명령은 다음과 같습니다.

docker run -d \
--env-file .env.development \
myapp

운영 환경은 다음처럼 실행합니다.

docker run -d \
--env-file .env.production \
myapp

이렇게 구성하면 환경별로 이미지를 다시 빌드하지 않아도 되며, 배포 과정도 단순해집니다.

자주 묻는 질문

Dockerfile의 ENV와 docker run의 -e는 무엇이 다른가요?

ENV는 이미지에 기본 환경 변수를 설정하고, docker run -e는 컨테이너를 실행할 때 값을 전달하거나 기본값을 변경합니다.

.env 파일은 자동으로 컨테이너에 전달되나요?

항상 그런 것은 아닙니다. Docker Compose의 .env 파일은 주로 Compose 설정의 변수 치환에 사용됩니다. 컨테이너에 값을 전달하려면 environmentenv_file 설정을 사용해야 합니다.

환경 변수에 비밀번호를 저장해도 되나요?

가능하지만 환경 변수는 docker inspect나 컨테이너 내부에서 확인될 수 있습니다. 중요한 비밀번호는 전용 Secret 관리 기능을 사용하는 것이 더 안전합니다.

환경 변수를 수정했는데 적용되지 않는 이유는 무엇인가요?

이미 실행 중인 컨테이너의 환경 변수는 자동으로 변경되지 않습니다. 컨테이너를 재생성해야 새로운 값이 적용됩니다.

Docker 환경 변수는 컨테이너 삭제 후 유지되나요?

환경 변수 자체는 컨테이너 설정에 포함됩니다. 컨테이너를 삭제하고 새로 생성하면 실행 명령이나 Compose 설정에 따라 다시 전달해야 합니다.

마무리

Docker 환경 변수는 애플리케이션 설정과 Docker 이미지를 분리하는 핵심 기능입니다.

Dockerfile의 ENV로 기본값을 설정하고, 실행 시 -e 또는 --env-file을 사용하면 환경에 따라 다른 값을 전달할 수 있습니다.

Docker Compose에서는 environment, env_file, .env 파일을 적절히 구분해 사용해야 합니다.

다만 비밀번호와 API 키 같은 민감한 정보는 이미지에 직접 포함하지 말고, 접근 권한이 제한된 환경 변수 파일이나 Secret 관리 기능을 사용하는 것이 좋습니다.

댓글 남기기