Docker ARGs랑 ENV, 진짜 실무에서 유용했던 이야기
요즘 개발 하면서 느끼는 거지만, 세상 너무 빨리 변하잖아요. 그래서 뭔가를 만들 때도 딱딱하게 굳어있는 것보다 유연하게, 상황에 맞게 바로바로 바꿀 수 있어야 훨씬 편하더라고요. Docker 쓰다 보면 그런 유연함을 가능하게 해주는 두 가지 꿀기능이 있어요. 바로 ARG랑 ENV에요. 처음엔 그냥 설정 값 같아 보여도, 써보면 "와 이거 진짜 편하네?" 싶을 정도로 다릅니다. 오늘은 제가 직접 써보면서 느낀 ARG랑 ENV의 매력을 풀어볼게요.

볼륨이랑 파일은 이제 손에 익었죠?
- Docker 초보 때는 파일 복사나 볼륨 설정부터 배우지만, 시간이 지나면 더 유연한 설정이 필요해짐
- 같은 이미지를 다양한 환경에서 쓰려면 ARG와 ENV 같은 기능이 꼭 필요함
- 처음엔 헷갈릴 수 있지만 쓰다 보면 정말 편리하고 효율적인 도구임
Docker 입문할 땐 파일 복사하고 볼륨 연결하는 게 제일 먼저잖아요. 근데 어느 순간 그 이상이 필요하더라고요. 같은 이미지인데 설정만 바꿔서 다른 환경에서도 써야 할 때요. 그럴 때 등장하는 게 바로 ARG랑 ENV! 사실 처음엔 헷갈리기도 했는데, 막상 써보면 생각보다 간단하고 효과는 확실해요.
ARG랑 ENV? 뭐가 다르냐고요?
Docker에선 두 가지 방식으로 외부 값을 받아요:
- ARG: 이미지 만들 때 한 번 쓰고 마는 일회성 설정값. --build-arg로 넣고, 빌드 끝나면 앱 안에서는 못 씁니다.
- ENV: 컨테이너가 실행될 때 적용되는 설정. --env, -e, Dockerfile 안의 ENV 명령어로 설정하고, 앱 코드에서도 접근할 수 있어요.
즉, 둘 다 설정값을 코드에 박아넣지 않아도 돼서 참 편해요.
ENV는 실전에서 이렇게 써요
- Node.js 앱에서 포트를 ENV로 설정하면 코드 수정 없이 다양한 환경에서 운영 가능
- Dockerfile에서 기본값을 주고, 실행 시에 필요한 포트를 ENV로 오버라이드 가능
- EXPOSE도 ENV를 통해 동적으로 설정할 수 있어 활용도가 높음
Node.js 앱 만들다가 포트를 바꿔야 했는데, 코드에서 이렇게 써놨었죠:
const port = process.env.PORT || 80;
근데 이걸 고정해두면 나중에 개발환경, 운영환경 다 바꿔야 해서 귀찮잖아요? 그래서 Dockerfile에 기본값을 주고:
ENV PORT 80
컨테이너 실행할 때 이렇게 바꿔줘요:
docker run -p 8000:8000 --env PORT=8000 my-image
그리고 EXPOSE 할 때도 그냥 숫자 박지 말고 이렇게 쓰면 좋죠:
EXPOSE $PORT
이러면 어디서 돌리든 설정 하나만 바꿔서 유연하게 쓸 수 있어요.

매번 치는 게 귀찮다? .env 파일이 답이에요
- 환경 변수 매번 입력하는 게 번거로울 땐 .env 파일로 깔끔하게 관리 가능
- 실행 시 --env-file 옵션으로 파일 불러오면 끝
- 다만 .env 파일에 민감한 정보가 들어있다면 절대 Git에 커밋하지 말고 .gitignore로 제외해야 함
환경변수 매번 타이핑하기 귀찮은 분들 많죠. 저도 그랬어요. 그래서 .env 파일 하나 만들어서 이렇게 써요:
PORT=8000
그다음 실행할 때는:
docker run --env-file ./.env my-image
끝. 너무 간단해서 감동했어요. 근데 한 가지 조심할 건 있어요. 이 파일 안에 민감한 정보(예: DB 비번, API 키) 넣었으면 절대 깃에 올리면 안 됩니다! .gitignore 꼭 해두세요.
ARG는 빌드할 때 요긴하게 써요
- ENV는 실행 시 사용하는 반면, ARG는 빌드할 때 한 번 설정하는 용도
- Dockerfile의 설정값을 유동적으로 바꾸고 싶을 때 유용함
- 같은 Dockerfile로 서로 다른 설정을 가진 이미지를 만들 수 있어 개발과 운영에 유리함
ENV는 실행 중에 쓰고, ARG는 빌드할 때 설정을 바꾸고 싶을 때 씁니다. 예를 들어 기본 포트를 Dockerfile에 아예 고정하지 말고, 이렇게 ARG로 처리하면:
ARG DEFAULT_PORT=80
ENV PORT=$DEFAULT_PORT
이미지 만들 때는:
docker build -t feedback-node:web-app .
개발용 포트 다르게 주고 싶으면:
docker build -t feedback-node:dev --build-arg DEFAULT_PORT=8000 .
이렇게 똑같은 Dockerfile로 상황에 따라 다르게 구성할 수 있어요. 진짜 깔끔.
ARG vs ENV 간단 정리표
| 구분 | ARG | ENV |
| 언제 쓰나 | 이미지 만들 때 | 컨테이너 실행할 때 |
| 코드에서 접근? | 못함 | 가능함 |
| 설정 방식 | --build-arg | --env / -e / 파일 |
| Dockerfile에 사용 가능? | 가능 | 가능 |
| 이미지에 저장? | 안 됨 | 됨 |
요약하자면:
- 이미지 자체에 따라 다르게 만들고 싶다면 ARG
- 앱에서 직접 값을 읽어야 한다면 ENV 쓰세요
실전 예: 포트 유연하게 바꾸기
- 코드와 Dockerfile 모두 포트를 ENV로 받아 설정하면, 환경에 따라 유연하게 대응 가능
- ARG를 통해 빌드 시 기본 포트를 설정하고, ENV로 실행 시 포트를 재설정 가능
- 매번 이미지 다시 빌드하거나 코드 고칠 필요 없이 손쉽게 포트 변경 가능
Node.js 서버는 이렇게 포트 받아오고,
const port = process.env.PORT || 80;
Dockerfile은 아래처럼 설정:
ARG DEFAULT_PORT=80
ENV PORT=$DEFAULT_PORT
EXPOSE $PORT
그리고 실행은:
docker build -t feedback-node:dev --build-arg DEFAULT_PORT=8000 .
docker run -p 8000:8000 -e PORT=8000 feedback-node:dev
이게 진짜 편해요. 매번 코드 건드릴 필요도 없고.
빌드 성능 높이는 꿀팁
- Dockerfile에서 ARG나 ENV의 위치에 따라 캐시 활용이 달라짐
- 필요 없는 곳에 ARG/ENV 설정을 두면 이후 명령어까지 전부 다시 실행될 수 있음
- 성능을 높이려면 필요한 위치 근처에 명령어를 배치하는 것이 핵심
Dockerfile 작성할 때 순서 잘못 잡으면 매번 npm install 다시 돌게 됩니다. 괜히 시간 낭비죠. ARG나 ENV는 꼭 필요한 위치 근처에 넣어야 캐시도 잘 되고, 시간도 아껴요. 저도 처음엔 몰라서 매번 다시 설치했는데, 순서만 바꿔도 금방 해결됐어요.

보안 관련 중요한 얘기 하나
- Dockerfile에 ENV로 민감 정보를 직접 넣으면 이미지에 그대로 남아 위험함
- docker history 명령어로 누구나 확인 가능하기 때문에 보안상 매우 취약함
- 실행 시점에 ENV로 전달하거나, 보안 도구(예: Docker secrets, 클라우드 키 관리)를 사용하는 것이 안전
ENV로 비밀번호 같은 거 Dockerfile에 쓰면 안 되는 이유? 그 값이 이미지에 그대로 남아요. 그리고 누구든지 아래 명령어로 다 볼 수 있어요:
docker history your-image-name
무서워요. 그래서 민감한 정보는 무조건 .env 파일이나, 실행 시점에 넣으세요. 아니면 아예 Docker secrets나 클라우드 비밀 관리 도구 쓰는 게 낫죠.
마무리하면서...
- ARG와 ENV를 활용하면 Docker 작업이 훨씬 유연하고 편리해짐
- 코드 수정 없이 다양한 환경 설정이 가능해지고, 민감 정보도 더 안전하게 관리 가능
- 처음엔 조금 복잡해 보일 수 있지만, 실제 써보면 실무에서 정말 많은 도움이 됨
ARG랑 ENV 쓰기 시작한 이후로 Docker 다루는 게 훨씬 수월해졌어요. 똑같은 이미지로 다양한 환경에 대응할 수 있고, 설정값만 바꿔서 바로 다른 모드로 돌릴 수 있고요. 무엇보다 민감한 값도 안전하게 관리할 수 있으니 마음도 놓여요.
Docker 처음 시작할 땐 좀 낯설었지만, 이제는 이 두 기능 없으면 불편해서 못 씁니다. 아직 안 써보셨다면 꼭 한 번 써보세요. 진짜 실무에서 체감 큰 꿀기능입니다.
'SW > Kubernetes, Docker' 카테고리의 다른 글
| Docker로 Node.js와 MongoDB 연결하는 법 (초보자도 가능한 실습 가이드) (0) | 2025.09.10 |
|---|---|
| Docker Networking 개념 쉽게 배우기: 실습 기반 설명과 팁 (0) | 2025.09.09 |
| Dockerfile COPY 꼭 써야 할까? Bind Mount만으로 충분할지 완전 정리! (0) | 2025.09.07 |
| Docker에서 read-only mount 설정하는 이유와 실전 적용 팁 (0) | 2025.09.06 |
| Nodemon으로 Docker 개발환경 자동화하는 법 (Node.js 개발자 필독!) (0) | 2025.09.05 |