Docker 파일 이미지 빌드

2026. 6. 12. 23:00Docker


Ⅰ. Dockerfile을 이용한 이미지 생성

Dockerfile 설명
Docker 이미지 생성을 자동화하기 위한 설정 파일 (Build Script)
컨테이너 실행에 필요한 기반 이미지, 패키지 설치, 환경변수, 실행 명령 등을 코드 형태로 정의하여,

동일한 환경을 손쉽게 재현 가능

Ⅰ - Ⅰ. Dockerfile에 들어갈 주요 내용

명령어 설명 비고
FROM 베이스 이미지 (기반 환경) 지정 공식 이미지 또는 사내 레지스트리 이미지 사용
모든 Dockerfile은 반드시 FROM으로 시작
RUN Docker 이미지 빌드 과정 중 컨테이너 내부에서 실행 여러 RUN 명령을 하나로 합치는 것이 효율적

(레이어 최소화)
패키지 설치나 설정 변경 등에 사용
ENV 환경 변수 (Environment Variable) 설정 빌드 및 런타임 환경 모두에 영향
이후 단계와 컨테이너 실행 시 참조 가능
CMD 컨테이너가 시작될 때 실행할 기본 명령어 또는 프로세스 지정

(컨테이너의 main 프로세스 역할)
docker run 명령에 다른 커맨드가 있으면

덮어씌워짐

 


Ⅰ - Ⅱ. 자주 쓰이는 Dockerfile 명령어

명령어 설명
WORKDIR 작업 디렉터리 설정 (cd 역할)
COPY 호스트의 파일을 이미지 내부로 복사
ADD COPY와 유사하지만 URL 또는 압축 파일도 가능
EXPOSE 컨테이너가 외부에 노출할 포트 지정
USER 명령 실행 시 사용할 사용자 지정
ENTRYPOINT CMD와 유사하지만 항상 실행되는 명령 지정 (고정 실행)

 

 

# testos 컨테이너 생성 및 실행

 

docker container run --name testos ubuntu 명령을 통해 Ubuntu 이미지 사용하여 testos 컨테이너 생성 및 실행

 

-it 옵션을 통해 testos 컨테이너에 직접 접근할 수 있는 쉘을 실행하도록 설정

 

apt update 명령을 통해 패키지 목록 업데이트

 

 

apt -y install iputils-ping bind9-dnsutils htop 명령을 통해 ping, nslookup, htop 관련 패키지 설치

 

 

apt -y install nginx 명령을 통해 Nginx 이미지 관련 패키지 설치

 

 

ls /usr/share/nginx/ 명령을 통해 /usr/share/nginx/ 디렉터리 내 목록 확인

 

 

echo “<h1>Test Web Server</h1>” > /usr/share/nginx/index.html 명령을 통해

 

/usr/share/nginx/index.html 파일의 내용이 <h1>Test Web Server</h1>라는

 

제목 태그가 포함된 HTML 코드로 대체되도록 설정

 

ctrl + p + q를 통해 컨테이너 내부에서 나옴

 

 

cls 명령을 통해 컨테이너가 잘 생성되었는지 확인

 

# nayeo0n/webserver:1.0 이미지 생성

 

docker container commit testos nayeo0n/webserver:1.0 명령을 통해

 

testos 컨테이너의 현재 상태를 기반으로 nayeo0n/webserver:1.0 이미지 생성

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# testos 컨테이너 삭제 

 

 crm 명령을 통해 컨테이너 삭제

 

# Ubuntu, nayeo0n/webserver:1.0 이미지 삭제

 

 irm 명령을 통해 이미지 모두 삭제

 

docker container ls –a 명령을 통해 컨테이너가 잘 삭제되었는지 확인

 

docker image ls -a 명령을 통해 이미지가 잘 삭제되었는지 확인

 

 

cd 명령을 통해 test 디렉터리에서 홈 디렉터리로 복귀

 

mkdir –p Dockerfile 명령을 통해 Dockerfile 디렉터리 생성

 

(-p 옵션으로 인해 상위 디렉터리 없을 경우, 같이 생성)

 

cd Dockerfile/ 명령을 통해 홈 디렉터리에서 Dockerfile 디렉터리로 이동

 

vi Dockerfile 명령을 통해 vi 편집기 이용하여 Dockerfile에 내용 추가

 

cat Dockerfile 명령을 통해 내용이 잘 추가되었는지 확인

 

 

mkdir public-html 명령을 통해 public-html이라는 새로운 디렉터리 생성

 

cp /root/docker/index.html public-html/ 명령을 통해 /root/docker/ 경로에 있는

 

index.html 파일을 public-html 디렉터리 안에 복사

 

 

# mynetflix:latest 이미지 생성

 

docker image build –t mynetflix . 명령을 통해 

 

현재 디렉터리에 있는 Dockerfile을 사용하여 mynetflix:latest 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# myweb 컨테이너 생성 및 실행

 

docker container run --name myweb myneflix:latest 명령을 통해

 

mynetflix:latest 이미지 사용하여 myweb 컨테이너 생성 및 실행

 

-d 옵션을 통해 myweb 컨테이너를 백그라운드로 구동 

 

-p 80:80 옵션을 통해 호스트의 80번 포트와 컨테이너의 80번 포트 매핑

 

 cls 명령을 통해 컨테이너가 잘 생성되었는지 확인

 

 

ls 명령을 통해 컨테이너 및 파일 목록 확인

 

ls public-html/ 명령을 통해 public-html 디렉터리 내 생성된 파일 및 디렉터리 확인

 

cat Dockerfile 명령을 통해 Dockerfile 파일의 내용 확인

 

 

# myweb 컨테이너 삭제

 

crm 명령을 통해 컨테이너 삭제

 

 

# mynetfilx:latest 이미지 삭제

 

 irm 명령을 통해 이미지 삭제

 

docker container ls –a 명령을 통해 컨테이너가 잘 삭제되었는지 확인

 

docker image ls 명령을 통해 이미지가 잘 삭제되었는지 확인

 

 

vi Dockerfile 명령을 통해 vi 편집기 사용하여 Dockerfile에 내용 추가

 

cat Dockerfile 명령을 통해 내용이 잘 추가되었는지 확인

 

[Dockerfile 파일의 내용]

 

FROM httpd:2.4 명령을 통해 Dockerfile 파일의 베이스 이미지를

 

Apache HTTP 서버의 버전 2.4 공식 이미지로 지정

 

 

# mynetflix:latest 이미지 생성

 

docker image build –t mynetflix . 명령을 통해

 

현재 디렉터리에 있는 Dockerfile을 사용하여 mynetflix:latest 이미지 빌드

 

docker image ls 명령을 통해 새로운 이미지가 잘 생성되었는지 확인

 

 

# myweb 컨테이너 생성 및 실행

 

docker container run --name myweb myneflix:latest 명령을 통해 

 

myneflix:latest 이미지 사용하여 myweb컨테이너 생성 및 실행

 

-d 옵션을 통해 myweb 컨테이너를 백그라운드에서 구동

 

-p 80:80 옵션을 통해 호스트의 80번 포트와 컨테이너의 80번 포트 매핑

 

cls 명령을 통해 컨테이너가 잘 생성되었는지 확인

 

cat Dockerfile 명령을 통해 Dockerfile 파일의 내용 확인

 

 

# myweb 컨테이너 삭제

 

 crm 명령을 통해 컨테이너  삭제

 

docker container ls –a 명령을 통해 컨테이너가 잘 삭제되었는지 확인

 

 

# myweb 컨테이너 생성 및 실행

 

docker container run --name myweb httpd:2.4 명령을 통해

 

Apache 웹 서버의 공식 이미지인 HTTPD:2.4 이미지 사용하여 myweb 컨테이너 생성 및 실행

 

-d 옵션을 통해 myweb 컨테이너를 백그라운드에서 구동

 

-v ./public-html:/usr/local/apache2/htdocs 옵션을 통해 /public-html/ 폴더에 볼륨 마운트 설정

 

-p 80:80 옵션을 통해 호스트의 80번 포트와 컨테이너의 80번 포트 매핑

 

cls 명령을 통해 컨테이너가 잘 생성되었는지 확인

 

cat Dockerfile 명령을 통해 Dockerfile 파일의 내용 확인

 

 

# myweb 컨테이너 삭제

 

crm 명령을 통해 컨테이너 삭제

 

 

# myneflix:latest, httpd:2.4 이미지 삭제

 

 irm 명령을 통해 이미지 모두 삭제

 

docker container ls –a 명령을 통해 컨테이너가 잘 삭제되었는지 확인

 

docker image ls 명령을 통해 이미지가 잘 삭제되었는지 확인

 

cd 명령을 통해 Dockerfile 디렉터리에서 홈 디렉터리로 이동


Ⅱ. Dockerfile을 이용한 Docker 이미지 생성

 

- Dockerfile은 이미지 빌드 자동화 스크립트이고, docker build 명령을 통해 이 Dockerfile을 기반으로

 

사용자 정의 이미지 (Custom Image) 생성 가능

 


Ⅱ - Ⅰ. 명령어 형식

명령어

형식
명령어 설명
docker build [옵션] [경로] 지정된 경로 내 Dockerfile을 이용해 이미지 생성
docker build [옵션] [URL] 원격 Git 리포지토리 URL에서 직접 Dockerfile을

읽어 이미지 생성
docker image build [옵션] [경로] docker build 명령과 동일

(명시적 image 서브 명령)
docker image build [옵션] [URL] 원격 Dockerfile을 참조하여 이미지 생성
docker image build -t [이미지 이름 : 태그명] [Dockerfile 위치] Dockerfile의 경로를 지정하고 이미지 이름 및 태그 부여

 

● 빌드 옵션 요약

옵션 설명
-t 이미지 이름 및 태그 지정
-f Dockerfile 이름 또는 경로 지정
--no-cache 캐시 사용하지 않고 새로 빌드
--build-arg Dockerfile 내 ARG 변수 전달
--progress=plain 빌드 로그 상세하게 출력

Ⅱ - Ⅱ. 명령어 사용 예시

명령어

사용 예시
예시 설명
docker image build -t buildtest . 현재 디렉터리에 있는 Dockerfile을 이용하여

빌드 및 buildtest 이미지 생성
docker image build -t buildtest /home/user1/build/ /home/user1/build/Dockerfile을 이용하여 

빌드 및 buildtest 이미지 생성
docker image build -t buildtest . -f Dockerfile1 현재 디렉터리에 있는 Dockerfile1을 이용하여

빌드 및 buildtest 이미지 생성
docker image build -t buildtest -f /home/user1/build/Dockerfile1 /home/user1/build/Dockerfile1을 이용하여

빌드 및 buildtest 이미지 생성

 

 

 

docker image build -help 명령을 통해 docker image build 명령의 옵션 확인


Ⅱ - Ⅲ. Dockerfile을 이용하여 Docker 베이스 이미지 생성

 

cd 명령을 통해 /root 디렉터리로 이동

 

pwd 명령을 통해 현재 작업 중인 디렉터리의 전체 경로 확인

 

ls 명령을 통해 현재 디렉터리에 있는 파일과 디렉터리 목록 확인

 

cd docker/ 명령을 통해 /root 디렉터리에서 docker/ 디렉터리로 이동

 

ls 명령을 통해 현재 디렉터리에 있는 파일과 디렉터리 목록 확인

 

cd 01_sample/ 명령을 통해 docker/ 디렉터리에서 01_sample/ 디렉터리로 이동

 

 

cat << EOF > Dockerfile 명령을 통해 Dockerfile 파일에 EOF라는 문자가 나타나기 전까지 입력된 내용 저장

 

cat Dockerfile 명령을 통해 내용이 잘 저장되었는지 확인

 

[Dockerfile 파일의 내용]

 

FROM nginx 명령을 통해 Dockerfile 파일의 베이스 이미지를 Nginx 웹 서버의 공식 이미지로 지정

 

EOF 명령을 통해 입력 종료 및 입력 내용 저장

 

 

# sample:1.0 이미지 빌드

 

docker image build –t sample:1.0 . 명령을 통해 현재 디렉터리에 sample:1.0 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# sample:2.0 이미지 빌드

 

docker image build –t sample:2.0 . 명령을 통해 현재 디렉터리에 sample:2.0 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

vi Dockerfile 명령을 통해 vi 편집기 사용하여 Dockerfile에 내용 추가

 

cat Dockerfile 명령을 통해 내용이 잘 추가되었는지 확인

 

[ Dockerfile 파일의 내용 ]

 

FROM nginx 명령을 통해 Dockerfile 파일의 베이스 이미지를 Nginx 웹 서버의 공식 이미지로 지정

 

COPY ./testfile /tmp 명령을 통해

 

현재 디렉터리에 있는 testfile 파일을 Docker 이미지 내부인 /tmp 디렉터리로 복사

 

EOF 명령을 통해 입력 종료 및 입력 내용 저장

 

 

echo “1234” > testfile 명령을 통해 새로운 빈 파일인 testfile에 1234라는 내용 입력

 

ls 명령을 통해 새로운 파일이 잘 생성되었는지 확인

 

 

# sample:3.0 이미지 빌드

 

docker image build –t sample:3.0 . 명령을 통해 현재 디렉터리에 sample:3.0 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# 컨테이너 생성 및 실행

 

docker container run sample:3.0 명령을 통해 sample:3.0 이미지 사용하여 컨테이너 생성 및 실행

 

--rm 옵션을 통해 실행이 끝나면 컨테이너가 자동으로 삭제되도록 설정

 

ls /tmp 명령을 통해 생성된 컨테이너 내부 /tmp 디렉터리에 있는 파일 목록 확인

 

 

# 컨테이너 생성 및 실행

 

docker container run sample:3.0 명령을 통해 sample:3.0 이미지 사용하여 컨테이너 생성 및 실행

 

--rm 옵션을 통해 실행이 끝나면 컨테이너가 자동으로 삭제되도록 설정

 

cat /tmp/testfile 명령을 통해 컨테이너 내부 /tmp 디렉터리에 있는 testfile 파일의 내용 확인

 

tar czf docker.tar.gz Dockerfile testfile 명령을 통해

 

 

# docker.tar.gz 아카이브 파일 생성

 

Dockerfile과 testfile 두 파일을 gzip 압축을 사용하여 압축한 뒤, docker.tar.gz 아카이브 파일 생성

 

ls 명령을 통해 새로운 아카이브 파일이 잘 생성되었는지 확인

 

tar tf docker.tar.gz 명령을 통해 docker.tar.gz 아카이브 파일의 압축을 풀지 않고 그 안에 포함된 파일 목록 확인

 

 

# Dockerfile, testfile 삭제

 

rm –rf Dockerfile testfile 명령을 통해 Dockerfile과 testfile 삭제

 

ls 명령을 통해 파일이 잘 삭제되었는지 확인

 

 

# sample:4.0 이미지 빌드

 

docker image build –t sample:4.0 - < docker.tar.gz 명령을 통해 docker.tar.gz 파일의 내용을

 

표준 입력으로 빌드 명령어를 전달하고, sample:4.0이라는 이름으로 새로운 도커 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# 컨테이너 생성 및 실행

 

docker container run sample:4.0 명령을 통해 sample:4.0 이미지 사용하여 컨테이너 생성 및 실행

 

--rm 옵션을 통해 실행이 끝나면 컨테이너가 자동으로 삭제되도록 설정

 

cat /tmp/tesfile 명령을 통해 컨테이너 내부 /tmp 디렉터리에 있는 testfile 파일의 내용 확인

 

 

cd .. 명령을 통해 01_sample 디렉터리에서 /docker 디렉터리로 이동

 

ls 명령을 통해 디렉터리 내에 생성된 파일과 디렉터리 목록 확인


Ⅲ. Docker 이미지 레이어 구조

Docker 이미지 레이어 구조 설명
Docker 이미지는 단일 파일이 아닌 여러 개의 레이어 (Layer)로 구성된 계층형 구조를 가짐
Dockerfile에서 정의된 각 명령어 (RUN, COPY, ADD 등)가 각각 하나의 레이어로 저장
저장된 레이어들이 쌓여 최종 이미지 구성

 


Ⅲ - Ⅰ. 레이어 구조

레이어 구조 구분 설명
기본 개념 Docker 이미지 = 여러 개의 읽기 전용 (Read - Only) 레이어들의 조합
생성 방식 Dockerfile의 각 명령어 (FROM, RUN, COPY, ADD 등) 실행 시 새로운 레이어 생성
저장 방식
 해시 (Hash) 값으로 확인 가능
/var/lib/docker/overlay2/ 등 Docker 엔진 스토리지에 저장
공유 구조 동일한 레이어는 여러 이미지 간에 공유되어 디스크 공간 절약 및 캐싱 효율 향상
레이어 병합

(Union FS)
OverlayFS / AUFS를 통해 여러 레이어를 하나의 파일 시스템으로 합쳐 컨테이너 내부에 제공
컨테이너와의 관계 컨테이너는 이미지 읽기 전용 레이어 위에 쓰기 가능 (Writeable) 레이어 추가하여 실행

 


Ⅲ - Ⅱ. 레이어의 특징

레이어의 특징 특징 내용
불변성 (Immutable) 한 번 생성된 레이어는 수정 불가
변경 시 새 레이어 생성
공유성 (Shared) 동일한 기반 이미지 사용 시 레이어 재활용 (중복 저장 방지)
캐싱 (Caching) 이전 빌드 결과를 재사용하여 빌드 속도 향상 (RUN, COPY 등 동일 시 캐시 사용)
효율성 (Efficiency) 다중 이미지 간 중복 레이어를 공용으로 사용하여 저장 공간 절감
독립성 (Independence) 각 레이어는 서로 독립적
상위 레이어에서 하위 레이어 수정 불가

 


Ⅲ - Ⅲ. 레이어와 컨테이너의 관계

구분 이미지 컨테이너
구조 여러 개의 읽기 전용 (Read - Only) 레이어 이미지 위에 추가되는 쓰기 가능 (Writeable) 레이어
기능 실행 환경 제공 실행 중 상태 변화, 로그 , 임시 파일 저장
저장 위치 /var/lib/docker/overlay2/ 동일 디렉터리 내 임시 레이어
삭제 시 영향 이미지 삭제 시 해당 레이어 모두 제거 컨테이너 삭제 시 Write Layer만 제거
예시 명령어 ex) docker image inspect ex) docker container inspect

 

 

cd 02_imagelayer/ 명령을 통해 /docker 디렉터리에서 02_imagelayer/ 디렉터리로 이동

 

vi Dockerfile 명령을 통해 vi 편집기 사용하여 Dockerfile 파일에 내용 추가

 

cat Dockerfile 명령을 통해 Dockerfile 파일에 추가된 내용 확인

 

[ Dockerfile 파일의 내용 ]

 

FROM ubuntu 명령을 통해 Dockerfile 파일의 베이스 이미지를

 

데비안 계열의 리눅스 배포판인 우분투의 공식 이미지 Ubuntu 로 지정

 

RUN apt-get update && apt-get –y install nginx 명령을 통해 이미지가 빌드되는 동안

 

컨테이너 내부에서 패키지 목록을 최신 상태로 업데이트하고, Nginx 패키지 설치

 

COPY ./index.html /var/www/html 명령을 통해 현재 디렉터리에 있는 index.html 파일을

 

Nginx의 기본 웹 문서 디렉터리인 /var/www/html로 복사하여 웹 서버가 해당 파일을 제공하도록 설정

 

CMD [“nginx”, “-g”, “daemon off;”] 명령을 통해 nginx를 실행하는데 포그라운드에서 실행되도록 설정

 

 

cp /root/docker/index.html . 명령을 통해 /root/docker 디렉터리에 있는 index.html 파일을 현재 디렉터리로 복사

 

tar czf docker.tar.gz Dockerfile index.html 명령을 통해 Dockerfile과 index.html

 

두 파일을 gzip 압축을 사용하여 압축한 뒤, docker.tar.gz 아카이브 파일 생성

 

ls 명령을 통해 새로운 아카이브 파일이 잘 생성되었는지 확인

 

 

# myweb1 이미지 생성

 

docker image build 명령을 통해 Docker 이미지 빌드

 

-t myweb1 옵션을 통해 빌드된 이미지에 myweb1이라는 이름 지정

 

옵션을 통해 입력을 통해 들어오는 데이터를 사용하도록 설정

 

< docker.tar.gz 옵션을 통해 docker.tar.gz 파일의 내용을 표준 입력으로 전달

 

 

docker image pull ubuntu 명령을 통해 Docker Hub에 있는 Ubuntu 이미지를 로컬 컴퓨터로 가져오도록 함

 

 

docker image ls 명령을 통해 생성된 이미지 목록 확인

 

docker image inspect ubuntu:latest 명령을 통해 Ubuntu:latest 이미지의 상세 정보 확인

 

 

docker image inspect testweb1:latest 명령을 통해 testweb1:latest 이미지의 상세 정보 확인 후,

 

Ubuntu 이미지의 RootFS 부분과 testweb1 이미지의 RootFS 부분 비교

 

 

# myweb 컨테이너 생성 및 실행

 

docker container run --name myweb testweb1 명령을 통해

 

testweb1 이미지를 사용하여 myweb 컨테이너 생성 및 실행

 

-d 옵션을 통해 myweb 컨테이너를 백그라운드로 구동

 

-p 80:80 옵션을 통해 호스트의 80번 포트와 컨테이너의 80번 포트 매핑

 

 

# myweb 컨테이너 삭제

 

crm 명령을 통해 컨테이너  삭제

 

cls 명령을 통해 컨테이너가 잘 삭제되었는지 확인

 

cd .. 옵션을 통해 02_imagelayer 디렉터리에서 /docker 디렉터리로 이동


Ⅳ. 멀티스테이지 빌드를 이용하여 이미지 용량 축소

구분 설명
개념 Dockerfile 내에서 여러 개의 FROM 명령을 사용해 빌드 단계 (Stage) 분리
최종 이미지에는 필요한 결과물만 복사하여 이미지 용량을 최소화하는 방법
필요성 빌드 도구, 의존성 파일, 캐시 등 불필요한 요소가 포함되면 이미지 크기가 커지므로,

빌드 과정과 실행 환경을 분리하여 경량화
기본 원리 항목 설명
첫 번째 스테이지 빌드용 이미지 (Build Stage)
두 번째 스테이지 실행용 이미지 (Final Stage)
=> COPY --from으로 필요한 산출물만 복사
장점 최종 이미지 용량 대폭 감소
보안 향상 (빌드 도구 제거)
빌드 / 운영 환경 분리로 유지보수 용이
적용 대상 Go, Java, Node.js, Python 등 컴파일 또는 빌드 후 실행하는 프로젝트
단계 단계 내용
Stage 1 (builder) Go 언어의 공식 이미지 (golang : 1.20)를 사용하여 애플리케이션 빌드
빌드 도구 (gcc, make 등) 포함
Stage 2 (final) 경량 OS 이미지 (alpine)에 빌드된 결과물만 복사하여 실행 환경 구성
결과 최종 이미지는 필요한 실행 파일만 포함
빌드 도구는 여전히 포함되지 않음
사용

명령어
명령어 설명
AS 각 스테이지에 이름 부여 (빌더명 지정)
COPY --from 다른 스테이지에서 생성된 파일 복사
RUN 각 스테이지 내부에서 필요한 빌드 명령 실행
주의사항 항목 설명
COPY 경로 주의 COPY --from은 스테이지 이름 또는 인덱스 (--from=0)로 참조 가능
환경변수 불연속 각 스테이지는 독립된 환경이므로 ENV 변수는 다시 설정 필요
빌드 캐시 관리 빌드 캐시는 스테이지별로 따로 저장되므로, 자주 바뀌는 부분은 하단으로 배치

 

 

cd 03_multistage/ 명령을 통해 /docker 디렉터리에서 03_multistage 디렉터리로 이동

 


Ⅳ - Ⅰ. 싱글 스테이지 사용 

구분 설명
개념 하나의 Dockerfile에서 단일 FROM 명령어만 사용하는 기본 빌드 방식
빌드 + 실행 환경이 모두 하나의 이미지에 포함됨
특징 모든 의존성, 빌드 도구, 실행 파일, 캐시 등이 한 이미지 안에 존재
장점 단순하고 이해하기 쉬움
빌드 과정이 한눈에 보임
단점 불필요한 빌드 도구와 임시 파일이 포함되어 이미지 용량이 커짐
보안 및 유지보수 측면에서 비효율적
적용 대상 단순한 애플리케이션 (ex. 단일 Python 스크립트)
테스트용 환경
내부 개발용 컨테이너
주요 명령어 명령어 설명
FROM 베이스 이미지 지정 (모든 Dockerfile은 이 명령어로 시작)
WORKDIR 컨테이너 내부의 작업 디렉터리 지정
COPY 호스트의 파일을 컨테이너 내부로 복사
RUN 이미지 빌드 과정에서 실행할 명령어 지정 (패키지 설치 등)
CMD 컨테이너 실행 시 실행할 기본 명령 지정
동작 흐름 단계 설명
1단계 : 기반 이미지 설정 (FROM) Python, Ubuntu 등 기본 환경 지정
2단계 : 작업 디렉터리 설정 (WORKDIR) 애플리케이션 실행 경로 설정
3단계 : 코드 복사 (COPY) 호스트의 앱 파일을 컨테이너 내부로 복사
4단계 : 빌드 명령 실행 (RUN) 의존성 설치, 환경 구성 등 빌드 수행
5단계 : 실행 명령 지정 (CMD) 컨테이너가 실행될 때 자동으로 실행할 명령어 지정
모든 빌드, 설치, 실행 과정을 처리하기 때문에 이미지에는 빌드 도구와 캐시가 그대로 남음
문제점 (한계) 항목 설명
이미지 크기 증가 빌드 시 사용된 도구 (ex. gcc, make, pip cache 등)가 남아있음
보안 취약점 증가 불필요한 빌드 유틸리티가 포함되어 공격 표면 확대
빌드 시간 증가 빌드 캐시 재사용이 어려워질 수 있음
환경 분리 불가 빌드 환경과 실행 환경이 동일하여 관리 어려움
주의사항 항목 설명
이미지 용량 증가 빌드 도구 (gcc, make, pip cache)가 이미지에 포함되어 용량이 커짐
보안 취약성 개발용 도구와 설정 파일이 남아 보안 리스크 증가
캐시 불필요 누적 RUN apt update 등 캐시가 남아 빌드 속도 및 공간 낭비 발생
환경 분리 불가능 빌드 환경과 실행 환경이 동일하여 운영환경 테스트 어려움
불필요한 로그 및 설정 파일 포함 /root/.cache, /var/lib/apt/lists 등이 그대로 남음
요약 하나의 Dockerfile에서 모든 과정을 처리하는 가장 단순한 빌드 방식
구조 단순하지만 결과 이미지에 불필요한 빌드 파일과 패키지가 포함되어 용량 커지고 보안성 낮음
실제 배포 환경에서는 멀티스테이지 빌드 (Multi - Stage Build)로 전환하여

실행에 필요한 최소 요소만 포함하는 것이 권장됨

 

 

yum –y install golang-bin 명령을 통해 Go 패키지 설치

 

 

vi main.go 명령을 통해 vi 편집기 이용하여 main.go 파일에 코드 작성

 

cat main.go 명령을 통해 main.go 파일에 작성한 코드 내용 확인

 

[ main.go 파일의 내용 ]

 

package main 명령을 통해 이 코드가 실행 가능한 프로그램임을 나타내는 Go 언어의 패키지 선언

 

import “fmt” 명령을 통해 입출력 함수들을 제공하는 Go의 표준 라이브러리인 fmt 패키지 임포트

 

func main(){} 메인 함수

 

fmt.Println(“Hello Docker”) 명령을 통해 인자로 주어진 문자열인 “Hello Docker”를 화면에 출력하고 줄바꿈 실행

 

 

go run main.go 명령을 통해 main.go 파일을 컴파일하고 바로 실행

 

go run main.go 명령을 통해 main.go 파일을 컴파일하고 바로 실행

 

go build main.go 명령을 통해 main.go 파일을 컴파일하여 실행 파일 생성

 

ls 명령을 통해 파일이 잘 생성되었는지 확인

 

ls –l 명령을 통해 생성된 파일들의 상세한 정보 확인

 

file main 명령을 통해 main 파일의 유형 확인

 

./main 명령을 통해 현재 디렉터리에서 main 실행 파일 실행

 

rm –rf main 명령을 통해 main 실행 파일 삭제

 

ls 명령을 통해 실행 파일이 잘 삭제되었는지 확인

 

 

vi Dockerfile1 명령을 통해 vi 편집기를 사용하여  Dockerfile1 생성하고 내용 입력

 

ls 명령을 통해 파일이 잘 생성되었는지 확인

 

cat Dockerfile1 명령을 통해 파일에 추가된 내용 확인

 

[ Dockerfile1 파일의 내용 ]

 

FROM golang:1.16 명령을 통해 Docker의 베이스 이미지로

 

Go 언어의 개발 환경이 포함된 공식 이미지인 golang:1.16으로 지정

 

WORKDIR /go/src/github.com/test/hello 명령을 통해 명령어들이 실행될 작업 디렉터리 설정

 

RUN go get -d –v github.com/urfave/cli 명령을 통해 이미지가 빌드되는 동안

 

컨테이너 내부에서 Go 애플리케이션의 외부 종속성 다운로드

 

COPY main.go /go/src/github.com/test/hello 명령을 통해

 

로컬의 main.go 파일을 컨테이너 내부의 작업 디렉터리로 복사

 

RUN main.go 명령을 통해 Go 소스 코드를 실행 파일로 컴파일

 

CGO_ENABLE=0 옵션을 통해 C언어 라이브러리와 동적 연결을 비활성화하여

 

외부 종속성을 갖지 않은 정적 바이너리가 되도록 하여 이식성을 높임

 

GOOS=linux 옵션을 통해 컴파일될 운영체제를 리눅스로 지정

 

go build 옵션을 통해 Go 컴파일러 실행

 

-a 옵션을 통해 모든 패키지 다시 빌드

 

-o hello 옵션을 통해 컴파일된 실행 파일의 이름을 hello로 지정

 

ENTRYPOINT ["./hello"] 명령을 통해 컨테이너가 실행되는 즉시 항상 이 Go 프로그램이 구동되도록 설정

 

 

# singlestage 이미지 생성

 

docker image build 명령을 통해 Docker 이미지 빌드

 

-t singlestage 옵션을 통해 빌드된 이미지에 singlestage라는 이름 지정

 

-f Dockerfile1 옵션을 통해 Dockerfile1을 사용하여 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# 컨테이너 생성 및 실행

 

docker container run singlestage:latest 명령을 통해 singlestage:latest 이미지 사용하여 컨테이너 생성 및 실행

 

--rm 옵션을 통해 실행이 끝나면 컨테이너가 자동으로 삭제되도록 설정

 

vi Dockerfile2 명령을 통해 vi 편집기 사용하여 Dockerfile2 파일 생성 및 파일 내용 입력

 

cat Dockerfile2 명령을 통해 Dockefile2 파일의 내용 확인

 

[ Dockerfile2 파일의 내용 ]

 

FROM golang:1.16 명령을 통해 Docker 베이스 이미지로 Go 언어 개발 환경이

 

포함된 공식 이미지인 golang:1.1 사용하도록 설정

 

AS builder 옵션을 통해 builder 별칭을 부여해 이후 단계에서 --from=builder 형태로 참조할 수 있도록 지정

 

WORKDIR /go/src/github.com/test/hello 명령을 통해 명령어들이 실행될 작업 디렉터리 설정

 

RUN go get -d –v github.com/urfave/cli 명령을 통해 이미지가 빌드되는 동안

 

컨테이너 내부에서 Go 애플리케이션의 외부 종속성 다운로드

 

COPY main.go main.go 명령을 통해 호스트의 main.go 파일을 복사

 

RUN main.go 명령을 통해 Go 소스 코드를 실행 파일로 컴파일

 

CGO_ENABLE=0 옵션을 통해 C언어 라이브러리와 동적 연결을 비활성화하여 외부 종속성을 갖지 않은

 

정적 바이너리가 되도록 하여 이식성을 높임

 

GOOS=linux 옵션을 통해 컴파일될 운영체제를 리눅스로 지정

 

go build 옵션을 통해 Go 컴파일러 실행

 

-a 옵션을 통해 모든 패키지 다시 빌드

 

-o hello 옵션을 통해 컴파일된 실행 파일의 이름을 hello로 지정

 

FROM busybox 명령을 통해 Docker의 두 번째 스테이지의 베이스 이미지를 매우 작고 기본적인

 

리눅스 환경을 제공하는 이미지이고, 크기를 최소화할 수 있는 busybox 이미지로 지정

 

WORKDIR /go/greet/bin 명령을 통해 작업 디렉터리를 /go/greet/bin으로 설정

 

COPY —from=builder /go/src/github.com/test/hello/hello . 명령을 통해 현재 디렉터리에

 

첫 번째 스테이지에서 생성된 빌드의 결과물을 가져오도록 설정

 

ENTRYPOINT ["./hello"] 명령을 통해 컨테이너가 실행되는 즉시 항상 이 Go 프로그램이 구동되도록 설정

 


Ⅳ - Ⅱ. 멀티 스테이지 사용

구분 설명
개념 하나의 Dockerfile 안에서 여러 개의 FROM 명령을 사용하여 빌드 단계를 분리하고,

최종 실행 환경에는 필요한 결과물만 포함시키는 빌드 방식
동작 흐름 구분
단계 설명 역할 결과
첫 번째

스테이지
빌드 단계

(Build Stage)
컴파일과 패키징 수행 개발 도구, 라이브러리, 의존성 등을

포함하여 앱을 컴파일 또는 빌드
실행 파일, 

결과물 생성
두 번째

스테이지
실행 단계

(Final Stage)
완성된 결과물만 복사하여

경량 이미지 생성
경량 베이스 이미지에서

빌드 결과물만 복사
최종 배포용

이미지 완성
목적 불필요한 빌드 도구나 캐시 파일을 최종 이미지에서 제외해 이미지 용량을 줄이고 보안성을 높이는 것
장점 이미지 크기 감소
보안 강화
빌드와 실행 환경 분리로 유지보수 용이
캐시 재사용으로 빌드 효율성 향상
적용 대상 Go, Java, Node.js, Python 등 빌드 도구가 필요한 언어 기반 프로젝트
주요 명령어 명령어 설명
AS 각 스테이지에 별칭 부여
COPY --from 다른 스테이지의 산출물 복사
RUN 각 스테이지 내부에서 필요한 명령 실행
WORKDIR 각 스테이지의 작업 디렉터리 지정
주의사항 항목 설명
COPY 경로

정확히 지정
COPY --from=builder 사용 시 절대경로 주의
환경 변수

불연속
각 스테이지는 독립된 환경이므로 ENV는 다시 선언 필요
빌드 캐시 관리 빌드 단계 변경 시 캐시 무효화 발생 가능
최종 스테이지

최소화
불필요한 파일 (node_modules, cache) 제외 권장

 

 

# multistage 이미지 생성

 

docker image build 명령을 통해 Docker 이미지 빌드

 

-t multistage 옵션을 통해 빌드된 이미지에 multistage라는 이름 지정

 

-f Dockerfile2 옵션을 통해 Dockerfile2을 사용하여 이미지 빌드

 

docker image ls 명령을 통해 이미지가 잘 생성되었는지 확인

 

 

# 컨테이너 생성 및 실행

 

docker container run multistage:latest 명령을 통해 multistage:latest 이미지 사용하여 컨테이너 생성 및 실행

 

--rm 옵션을 통해 실행이 끝나면 컨테이너가 자동으로 삭제되도록 설정

 

 

# multistage:latest 이미지 삭제

 

docker image rm multistage:latest 명령을 통해 multistage:latest 이미지 삭제

 

docker image ls 명령을 통해 이미지가 잘 삭제되었는지 확인

 

 

# Dockerfile2 파일 삭제

 

rm –rf Dockerfile2 명령을 통해 Dockerfile2 파일 삭제

 

 

# 컨테이너 삭제

 

crm 명령을 통해 컨테이너 모두 삭제

 

 

# 이미지 삭제

 

irm 명령을 통해 이미지 모두 삭제

 

docker container ls –a 명령을 통해 컨테이너가 잘 삭제되었는지 확인

 

docker image ls 명령을 통해 이미지가 잘 삭제되었는지 확인

 

● 싱글 스테이지 vs 멀티 스테이지

구분 싱글 스테이지 빌드 멀티 스테이지 빌드
FROM 개수 1개  2개 이상
구조 빌드 + 실행 환경 통합 빌드용 / 실행용 단계 분리
이미지 용량 큼 (불필요한 도구 포함) 작음 (필요한 파일만 포함)
보안성 낮음 (빌드 도구 포함) 높음 (최소 구성)
관리 효율성 낮음 높음
적합한 용도 테스트용 배포용
간단한 앱 상용 서비스용

'Docker' 카테고리의 다른 글

Docker 로컬 레지스트리  (0) 2026.06.13
Dockerfille 명령어 이해  (0) 2026.06.12
Docker 이미지 생성  (0) 2026.06.12
Docker 리소스 제한 및 모니터링  (0) 2026.06.12
Docker 컨테이너 운용  (0) 2026.06.12