![[Docker] Dockerfile](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuT8Tk%2FbtsNXl904QP%2Fwyiue9yS1rYw7qTG64BU61%2Fimg.webp)
[Docker] DockerfileDevOps/Docker2025. 5. 14. 19:27
Table of Contents
이 글은 인프런의 지식 공유자 박재성님의 강의를 듣고 개인적으로 정리하는 글임을 알립니다.
Dockerfile
Dockerfile은 Docker 이미지를 생성하기 위한 스크립트이다.
Dockerfile이란 텍스트 파일로, Docker 엔진에게 이미지를 어떻게 빌드할지 지시하는 명령어들을 포함한다.
특징
- 일반적으로 프로젝트 루트 디렉토리에 Dockerfile이라는 이름으로 저장
- 여러 명령어(인스트럭션)로 구성
- 각 명령어는 이미지에 새로운 레이어를 추가
- 레이어 방식으로 이미지를 구성하여 캐싱과 재사용성 향상
FROM
- FROM은 베이스 이미지를 생성하는 역할을 한다.
- Docker 컨테이너를 특정 초기 이미지를 기반으로 추가적인 세팅을 할 수 있다. 여기서 얘기한 ‘특정 초기 이미지’가 곧 베이스 이미지이다.
- 누군가는 JDK가 설치되어 있는 컨테이너 환경이 세팅되기를 바랄 수도 있고, 누군가는 Node가 설치되어있는 컨테이너 환경이 셋팅되기를 바랄 수도 있다.
- 필요에 따라 베이스 이미지를 고르면 된다.
# 문법 FROM [이미지명] FROM [이미지명]:[태그명] FROM eclipse-temurin:17-jre-alpine |
- 태그명을 적지 않으면 해당 이미지의 최신(latest) 버전을 사용한다.
- eclipse-temurin:17-jre-alpine : Debian기반 리눅스 OS에 테무린 jdk 17가 설치되어있는 베이스 이미지 지정
COPY
COPY는 호스트 컴퓨터에 있는 파일을 복사해서 컨테이너로 전달한다.
# 문법 COPY [호스트 컴퓨터에 있는 복사할 파일의 경로] [컨테이너에서 파일이 위치할 경로] # 예시 COPY app.txt /app.txt # 예시 # app.txt를 복사해서 / 경로에 abc라는 이름으로 넣는다. COPY app.txt /abc.txt |
폴더 안에 있는 모든 파일 복사
# 현재 디렉터리의 my-app이라는 디렉터리를 컨테이너 루트 디렉터리로 복사 COPY my-app /my-app/ # 와일드 카드도 가능 COPY *.txt /my-app/ #예시 # *SNAPSHOT.jar를 복사해서 컨테이너 내부의 루트 경로에 app.jar라는 이름으로 넣는다. COPY build/libs/*SNAPSHOT.jar app.jar |
- /my-app라고 적으면 안 되고 /my-app/라고 적어야 my-app라는 디렉토리 안에 파일들이 정상적으로 복사된다.
.dockerignore
gitignore 처럼 특정 파일 또는 디렉터리를 영향을 받게 하고싶지 않을 수 있다.
이때 .dockerignore를 사용한다.
.dockerignore에 적힌 파일 또는 디렉터리는 빌드 컨텍스트에서 완전히 제외되어 Docker 데몬으로 전송되지 않는다.
.dockerignore
이렇게 하면 readme.txt는 copy되지 않는다.
readme.txt
COPY vs ADD
ADD는 로컬 컴퓨터의 파일이나 디렉토리를 도커 이미지 안으로 복사하는 명령어이다.
ADD는 COPY와 비슷하지만 추가 기능이 있다
- URL에서 파일을 다운로드할 수 있다
- 압축 파일(tar, zip 등)을 자동으로 풀어준다
ENTRYPOINT
- ENTRYPOINT는 컨테이너가 생성되고 최초로 실행할 때 수행되는 명령어를 뜻한다.
- 컨테이너가 생성되고 최초로 실행시키고 싶은 명령어를 적으면 된다.
- 명령어는 공백을 구분해서 배열에 넣는다.
- Docker 파일에서 ENTRYPOINT는 한 번만 정의할 수 있다. 여러 번 ENTRYPOINT를 정의하면 마지막으로 정의된 것만 적용된다.
FROM eclipse-temurin:17-jre-alpine COPY build/libs/*SNAPSHOT.jar app.jar # java -jar /app.jar 명령어 실행 ENTRYPOINT ["java", "-jar", "/app.jar"] |
ENTRYPOINT vs CMD
Entrypoint는 Cmd보다 더 강력한 역할을 하며, Entrypoint에 의해 설정된 명령은 덮어쓸 수 없다.
ENTRYPOINT: ENTRYPOINT는 컨테이너가 시작될 때 반드시 실행되는 명령어를 지정한다. 컨테이너를 실행할 때 추가 명령을 입력해도 ENTRYPOINT는 항상 실행된다.
CMD: CMD는 컨테이너가 시작될 때 실행할 기본 명령어를 지정한다. 하지만 컨테이너 실행 시 다른 명령어를 입력하면 CMD는 무시된다.
ENTRYPOINT와 CMD를 함께 사용할 수도 있다. 이 경우 ENTRYPOINT는 실행할 명령어의 고정 부분이 되고, CMD는 그 명령어의 기본 인자(파라미터)가 된다.
이 경우 실제로 실행되는 명령어는 java -jar app.jar이다.
ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]
만약 컨테이너 실행 시 다른 인자를 전달하면 CMD 부분만 대체된다.
예를 들어 docker run myimage other.jar로 실행하면 java -jar other.jar가 실행된다.
RUN
- RUN은 이미지 생성 과정에서 명령어를 실행시켜야 할 때 사용한다.
- Docker 파일에서 ENTRYPOINT는 여러 번 정의할 수 있다.
- RUN이 많아지만 각 RUN 명령이 새 레이어를 생성하므로 전체 이미지 크기가 커질 수 있다.
# 문법 RUN [명령문] # 예시 RUN npm install # 예시 RUN apt update && apt install -y git |
RUN vs ENTRYPOINT
엄연히 둘의 사용 용도는 다르다.
- RUN: 이미지 생성 과정에서 필요한 명령어를 실행시킬 때 사용
- ENTRYPOINT: 생성된 이미지를 기반으로 컨테이너를 생성한 직후에 명령어를 실행시킬 때 사용
WORKDIR
- WORKDIR으로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령문은 해당 디렉터리를 기준으로 실행된다.
- 작업 디렉터리를 굳이 지정해주는 이유는 컨테이너 내부의 폴더를 깔끔하게 관리하기 위해서이다.
- 컨테이너도 미니 컴퓨터와 같기 때문에 Dockerfile을 통해 생성되는 파일들을 특정 폴더에 정리해두는 것이 추후에 관리가 쉽다.
- 만약 WORKDIR을 쓰지 않으면 컨테이너 내부에 존재하는 기존 파일들과 뒤섞여버린다.
# 문법 WORKDIR [작업 디렉토리로 사용할 절대 경로] # 예시 WORKDIR /usr/src/app |
EXPOSE
EXPOSE는 컨테이너 내부에서 어떤 포트에 프로그램이 실행되는 지를 문서화하는 역할만 한다.
docker -p 8080:8080 … 와 같은 명령어의 -p 옵션과 같은 역할은 일체 하지 않는다.
쉽게 표현하자면 EXPOSE 명령어는 쓰나 안 쓰나 작동하는 방식에는 영향을 미치지 않는다.
# 문법 EXPOSE [포트 번호] # 예시 EXPOSE 3000 |
Dockerfile을 기반으로 이미지 생성
# docker build -t [이미지 이름][:태그] [Dockerfile이 있는 경로] docker build -t my-docker-image . docker build -t my-docker-image:v1 . # 애플 실리콘 맥북을 사용할 경우, 빌드 이미지가 ARM64로 빌드된다. # AWS EC2나 보통의 서버 컴퓨터는 AMD64이므로 AMD64 전용으로 빌드할 필요가 있다. docker build --platform linux/amd64 -t [이미지 이름[:태그]] . |
'DevOps > Docker' 카테고리의 다른 글
[Docker] 컨테이너 리소스 사용량 제한 (0) | 2025.05.15 |
---|---|
[Docker] 볼륨 (Volume) (0) | 2025.05.14 |
[Docker] 자주 사용하는 명령어 정리 (1) | 2025.05.13 |
[Docker] 애플리케이션 종료시 Compose 자동시작 (1) | 2024.10.13 |
[Docker + SpringBoot] 스프링부트 로그 파일 남기기 (1) | 2024.10.11 |