Dockerfile

artp·2024년 9월 24일

docker

목록 보기
3/6
post-thumbnail

Dockerfile이란?

Docker 이미지는 Docker Hub에서 다운로드하여 사용할 수 있으며, 이는 다른 사람들이 Docker Hub에 업로드한 이미지입니다. 이러한 Docker 이미지는 Dockerfile을 사용하여 만들 수 있습니다.

Dockerfile은 Docker 이미지를 만드는 데 사용되는 파일로, 이미지 생성에 필요한 명령어와 설정을 정의합니다.

Dockerfile 문법

1. FROM: 베이스 이미지 생성

FROM 명령어란?

FROM 명령어는 Docker 이미지의 베이스 이미지를 설정하는 역할을 합니다. 이를 통해 Docker 컨테이너가 특정 초기 이미지를 기반으로 추가적인 설정을 진행할 수 있습니다. 즉, 생성할 이미지의 기본이 될 도커 이미지를 명시하는 부분입니다.

예를 들어, Windows 컴퓨터에는 Windows에 필요한 기본 프로그램들이 설치되어 있고, Mac 컴퓨터에는 Mac에 필요한 기본 프로그램들이 설치되어 있습니다. 베이스 이미지도 이와 비슷한 개념으로, 컨테이너 환경을 새로 구축할 때 어떤 기본 프로그램이 포함된 환경을 선택할지 결정하는 옵션이라고 생각하면 됩니다.

예를 들어, 어떤 사람은 JDK가 설치된 환경이 필요할 수 있고, 또 다른 사람은 Node가 설치된 환경이 필요할 수 있습니다. 이러한 필요에 따라 알맞은 베이스 이미지를 선택하면 됩니다.

FROM 사용법

# 문법
# 태그명을 적지 않으면 해당 이미지의 최신 버전(latest)을 사용하게 됩니다.
FROM [이미지명]
FROM [이미지명]:[태그명]

FROM 실습

임의의 폴더를 하나 생성한 후 프로젝트로 열고, 도커 파일을 생성합니다.

FROM 명령어로 도커 이미지를 JDK 17 환경으로 설정합니다.
docker build -t [도커 이미지명] . 명령어로 도커 이미지를 생성합니다.

도커 이미지가 잘 생성된 것을 확인할 수 있습니다.

2. COPY: 파일 복사(이동)

COPY 명령어란?

COPY 명령어는 호스트 컴퓨터 (즉, Docker를 실행하는 컴퓨터)에서 특정 파일이나 폴더를 컨테이너 내부로 복사하는 역할을 합니다. 이렇게 하면 Docker 이미지를 빌드할 때 필요한 파일들이 컨테이너 내부에 포함할 수 있습니다.

COPY를 사용하면 소스 코드나 설정 파일 같은 필요한 파일들을 컨테이너에 포함할 수 있습니다. 이를 통해 컨테이너가 실행될 때 이 파일들을 바로 사용할 수 있으며, 별도로 추가 작업 없이도 컨테이너 내부에서 파일에 접근할 수 있습니다.

즉, COPY호스트 컴퓨터의 파일을 컨테이너에 포함시켜 컨테이너가 이 파일을 사용할 수 있도록 해주는 명령어입니다.

COPY 사용법

# 문법
COPY [호스트 컴퓨터에 있는 복사할 폴더/파일의 경로] [컨테이너에서 폴더/파일이 위치할 경로]

# 예시
COPY app.txt /app.txt

이 명령어는 현재 호스트 컴퓨터의 app.txt 파일을 컨테이너의 /app.txt 경로에 복사합니다.

COPY 실습

1. 파일 복사

COPY 명령어를 사용한 도커 파일을 하나 생성합니다. 이미지를 빌드하고 디버깅해보면 호스트의 app.txt 파일이 컨테이너 내부에 잘 복사된 것을 확인할 수 있습니다.

ENTRYPOINT 명령어는 컨테이너가 시작될 때 기본으로 실행될 명령어를 지정하는 역할을 합니다. 이 명령어를 통해 컨테이너가 시작되면 특정 명령어가 자동으로 실행되도록 설정할 수 있습니다.
ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]의 경우, 컨테이너가 시작되면 /bin/bash -c "sleep 500" 명령어가 실행됩니다. 이를 통해 컨테이너가 바로 종료되지 않고 500초 동안 유지됩니다. sleep 500은 500초 동안 대기하라는 명령으로, 이 동안 컨테이너는 종료되지 않고 계속 실행 상태를 유지합니다.
이렇게 설정하면 컨테이너가 시작되자마자 종료되는 것을 방지하면서, 원하는 작업을 할 수 있는 시간을 확보할 수 있습니다.

2. 폴더(디렉터리) 복사

이번에는 호스트의 특정 폴더를 컨테이너로 복사하는 실습을 해보겠습니다. my-app 디렉터리를 만들고, my-app 디렉터리 안에 파일을 생성한 후 컨테이너로 복사합니다. 이미지를 빌드하고 디버깅해보면 폴더와 폴더 내의 파일까지 모두 잘 복사된 것을 확인할 수 있습니다.

COPY my-app /my-app/에서 마지막 /명확하게 디렉토리(폴더)로 복사하겠다는 의미를 전달합니다. 이 /가 없으면 Docker는 복사 대상이 파일인지 디렉토리인지 명확하지 않게 될 수 있으며, 이로 인해 의도하지 않은 동작이나 에러가 발생할 수 있습니다.
예를 들어, 다음과 같은 차이가 있습니다:

  • COPY my-app /my-app/my-app 디렉토리 전체를 컨테이너의 /my-app/ 디렉토리에 복사합니다.
  • COPY my-app /my-app → Docker는 /my-app을 파일로 간주할 수 있으며, 때에 따라 파일 이름을 my-app으로 지정해 복사할 가능성이 있습니다. 이는 Docker가 항상 디렉토리로 처리한다고 보장되지 않으므로, 명확성을 위해 /를 추가하는 것이 좋습니다.
    즉, 마지막 /를 추가하면 명확하게 디렉토리로 인식되어 예기치 않은 오류를 피할 수 있습니다.

3. 와일드카드(*) 사용

이번에는 와일드카드(*)를 사용하여 특정 패턴을 가진 파일이나 디렉터리를 복사하는 실습을 해보겠습니다. .txt 확장자를 가진 파일을 복사하는 명령어를 작성 후, 이미지를 빌드하고 디버깅해보면 .txt 확장자를 가진 파일들이 잘 복사된 것을 확인할 수 있습니다.

*.txt -> 모든 .txt 확장자를 가진 파일을 선택합니다.
file* -> file 로 시작하는 모든 파일을 선택합니다.
* -> 모든 파일을 의미합니다.

4. .dockerignore 사용

.dockerignore 파일은 Docker가 이미지를 빌드할 때 특정 파일이나 폴더를 제외할 수 있도록 해줍니다. 이 파일은 .gitignore와 비슷하게 작동하며, 빌드 과정에서 복사하고 싶지 않은 파일을 지정할 수 있습니다.

예를 들어, 프로젝트에는 소스 코드 외에 로그 파일이나 캐시 파일, 테스트 결과 파일 등이 있을 수 있습니다. 이런 불필요한 파일들이 포함되면 이미지의 용량이 커지고 빌드 시간이 길어질 수 있습니다. .dockerignore 파일을 사용하면 이런 파일들을 빌드 대상에서 제외할 수 있어 효율을 높일 수 있습니다.

# .dockerignore
# 도커 이미지 빌드 시 readme.txt, text.txt 파일을 제외
readme.txt
text.txt

위처럼 .dockerignore 코드를 작성 후 이미지를 빌드하고 디버깅해보면 readme.txt 파일과 text.txt 파일은 빌드 대상에서 제외되어 컨테이너 내부에 위 파일들이 존재하지 않음을 확인할 수 있습니다.

3. ENTRYPOINT : 컨테이너가 시작할 때 실행되는 명령어

ENTRYPOINT 명령어란?

ENTRYPOINT는 Docker 컨테이너가 시작될 때 가장 먼저 실행되는 명령어를 지정하는 것입니다. 컨테이너는 일종의 가상 환경(미니 컴퓨터)처럼 작동하므로, ENTRYPOINT에 설정된 명령어는 이 "미니 컴퓨터"가 전원을 켜고 처음 실행할 프로그램이나 명령어라고 생각할 수 있습니다.

이 설정은 컨테이너가 시작될 때 자동으로 어떤 특정 작업을 하도록 만들어 주기 때문에, 특정 작업을 계속 실행하거나 유지해야 할 때 매우 유용합니다.

즉, ENTRYPOINT는 컨테이너가 켜질 때 자동으로 실행할 명령어를 지정하는 기능으로, 시작과 동시에 수행해야 할 작업을 설정할 수 있습니다.

ENTRYPOINT 사용법

# 문법
ENTRYPOINT [명령문...]

# 예시
ENTRYPOINT ["node", "dist/main.js"]

ENTRYPOINT 실습

컨테이너를 실행하면 hello 문자를 출력하도록 작성합니다. 도커 파일의 모든 명령어를 수행하면 컨테이너는 자동으로 종료되므로 docker ps -a 명령어와 docker logs [컨테이너 아이디] 명령어를 통해 결과를 확인할 수 있습니다.

4. RUN : 이미지를 생성하는 과정에서 사용할 명령문 실행

RUN 명령어란?

RUN 명령어는 Docker 이미지 생성 과정에서 필요한 명령어를 실행하고 그 결과를 이미지에 포함시키는 역할을 합니다.

이 명령어는 이미지를 빌드할 때만 실행되며, 주로 소프트웨어 설치나 환경 설정을 할 때 사용됩니다. RUN을 사용하면 설치된 프로그램이나 설정된 환경이 Docker 이미지에 영구적으로 저장됩니다. 이로 인해, 컨테이너가 실행될 때마다 다시 설치할 필요 없이, 설정된 상태로 바로 시작할 수 있습니다.

RUN vs ENTRYPOINT

  • RUN 명령어: Docker 이미지를 빌드하는 과정에서 필요한 설정이나 프로그램 설치 등을 위해 사용됩니다. 이미지 생성이 끝나면 RUN으로 실행한 명령어의 결과는 이미지에 영구적으로 포함됩니다.
  • ENTRYPOINT 명령어: 컨테이너가 시작될 때마다 자동으로 실행되는 명령어입니다. ENTRYPOINT에 지정한 명령어는 컨테이너가 시작되자마자 매번 실행되므로, 주로 컨테이너가 수행할 기본 작업이나 서비스를 설정하는 데 유용합니다. 예를 들어, 웹 서버를 실행하는 명령어를 ENTRYPOINT로 설정하면 컨테이너가 켜질 때마다 자동으로 웹 서버가 시작됩니다.
  • 즉, RUN은 이미지를 빌드할 때 필요한 설정을, ENTRYPOINT는 컨테이너가 실행될 때 수행할 작업을 설정하는 명령어입니다.

RUN 사용법

# 문법
RUN [명령문]

# 예시
RUN npm install

RUN 실습

이미지를 빌드할 때 git을 설치하도록 코드를 작성한 후 이미지를 빌드하여 실행한 컨테이너 내부에서 깃 설치 여부를 확인합니다. 컨테이너 내부에서 git -v 명령어를 통해 확인해보니 깃이 설치되어 있는 것을 확인할 수 있습니다.

5. WORKDIR : 작업 디렉토리를 지정

WORKDIR 명령어란?

WORKDIR 명령어는 Dockerfile에서 작업 디렉터리를 설정하는 역할을 합니다. WORKDIR로 작업 디렉터리를 지정하면, 그 이후에 나오는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령어는 해당 디렉터리를 기준으로 실행됩니다.

이렇게 작업 디렉터리를 지정하는 이유는 컨테이너 내부의 파일을 체계적으로 관리하기 위해서입니다. 컨테이너는 미니 컴퓨터와 비슷하게 동작하므로, Dockerfile로 생성되는 파일이나 디렉터리를 특정 폴더 안에 정리해두면, 구조를 깔끔하게 유지할 수 있어 추후 관리와 유지보수가 훨씬 쉬워집니다.

예를 들어, WORKDIR /app을 지정한 후 COPY . .을 사용하면, 현재 디렉터리의 파일들이 /app 디렉터리 아래에 복사됩니다. 만약 WORKDIR을 설정하지 않고 파일을 복사하면, 컨테이너 내부의 루트 디렉터리나 다른 위치에 파일이 섞여 저장될 수 있습니다.

즉, WORKDIR은 작업할 디렉터리를 명확히 지정하여, 컨테이너 내 파일이 흩어지지 않게 정리하고, 모든 작업을 일관된 경로에서 실행할 수 있도록 도와주는 명령어입니다.

WORKDIR 사용법

# 문법
WORKDIR [작업 디렉터리로 사용할 절대 경로]

# 예시
WORKDIR /usr/src/app

WORKDIR 실습

WORKDIR /my-dir 명령어를 작성하여 컨테이너 내부에 my-dir 폴더를 자동 생성하여 컨테이너 기본 시작 디렉터리 및 작업 디렉터리로 설정합니다. 이미지 빌드 후 확인해보면, my-dir 디렉터리가 잘 생성되었고, 디렉터리 내부에 파일들이 복사된 것을 확인할 수 있습니다.

5. EXPOSE : 컨테이너 내부에서 사용 중인 포트를 문서화하기

EXPOSE 명령어란?

EXPOSE 명령어는 Dockerfile에서 컨테이너가 사용하는 포트를 표시하여 해당 포트가 외부와 통신에 사용된다는 것을 문서화하는 역할만 합니다. 예를 들어 EXPOSE 8080이라고 지정하면, 이는 컨테이너 내부에서 8080 포트로 프로그램이 실행된다는 정보를 나타내지만, 실제로 호스트와 컨테이너 간의 포트 연결에는 영향을 미치지 않습니다.

컨테이너와 호스트 간의 포트를 연결하려면 docker run -p 8080:8080과 같이 -p 옵션을 사용해야 합니다. -p 옵션은 호스트와 컨테이너의 포트를 실제로 매핑하여, 호스트의 8080 포트를 통해 컨테이너의 8080 포트에 접근할 수 있도록 설정합니다.

쉽게 말해, EXPOSE어떤 포트를 사용할지를 기록하는 용도이고, 포트 매핑을 통해 외부 접근을 허용하려면 -p 옵션을 사용해야 합니다. 따라서 EXPOSE 명령어는 사용해도 실제 작동에는 영향을 미치지 않으며, 기록과 명확한 문서화를 위해 주로 사용됩니다.

EXPOSE 사용법

# 문법
EXPOSE [포트 번호]

# 예시
EXPOSE 3000
profile
donggyun_ee

0개의 댓글