Dockerfile overview
Learn about Dockerfiles and how to use them with Docker Images to build and package your software
docs.docker.com
Docker는 Dockerfile에서 명령어를 읽어 이미지를 빌드한다. Dockerfile은 소스코드를 빌드하기 위한 명령어가들어 있는 텍스트 파일이다.
Dockerfile에 사용되는 명령어
`FROM <image>` : 이미지의 기준이 되는 것을 정의
`RUN <command>` : 현재 이미지 위의 새 레이어에서 모든 명령을 실행하고 결과를 커밋.
`WORKDIR <directory>`: `RUN`, `CMD`, `ENTRYPOINT`, `COPY`, `ADD` 명령어에 대한 작업 디렉터리를 설정
'`COPY <src> <dest>`: `<src>` 에 위치한 새 파일이나 경로를 컨테이너 파일 시스템인 컨테이너 경로 `<dest>` 에 추가한다.
`CMP <command>`: 이 이미지를 기반으로 컨테이너를 시작하면 실행되는 기본 프로그램을 정의할 수 있다. 각 Dockerfile에는 하나의 `CMD`만 있으며, `CMD` 인스턴스가 여러개 있을 경우 마지막 인스턴스만 취급한다.
Dockerfile 이름 지정
`docker build` 명령어에 `--file` 플래그를 사용해서 Dockerfile 이름을 지정할 수 있다. 자세한 내용을 docker build CLI reference를 참고.
공식 문서에서는 이름 지정하는 것보단 기본 Dockerfile을 사용하는걸 권장하고 있다.
Docker 사용하는 이유
Docker 이미지는 레이어로 구성되어 있다. 각 레이어는 Dockerfile 의 빌드 명령의 결과.
레이어는 순차적으로 쌓이고, 각각은 이전 레이어에 적용된 변경 사항을 나타낸다.
다음은 Flask 프레임워크를 사용해서 "Hellow World" 애플리케이션을 보여준다.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
만일 도커를 사용하지 않고 배포하려면 아래와 같은 과정을 따라야함
- 필수 런타임 종속성을 서버에 설치
- Python 코드를 서버의 파일 시스템에 업로드
- 서버를 필요한 매개변수를 사용해서 애플리키이션을 시작
Dockerfile을 사용한다면
- 모든 종속성이 설치되어 있고
- 애플리케이션을 자동으로 시작하는 컨테이너 이미지를 만든다.
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip install flask==3.0.*
# install app
COPY hello.py /
# final configuration
ENV FLASK_APP=hello
EXPOSE 8000
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
Dockerfile의 살펴보기
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip install flask==3.0.*
# install app
COPY hello.py /
# final configuration
ENV FLASK_APP=hello
EXPOSE 8000
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
위 도커 파일의 레이어를 하나씩 살펴보자
Dockerfile syntax
# syntax=docker/dockerfile:1
Dockerfile 첫번째 줄에는 `# syntax` 지시문이 온다.
이 지시문은 선택사항이지만 Dockerfile을 파싱할때 사용할 구문을 Docker 빌더에게 지시하고, BuildKit 의 활성화된 이전 Docker 버전이 빌드를 시작하기 전에 특정 Dockerfile 프런트엔드를 사용할 수 있도록 한다.
이 지시문은 Dockerfile 첫번째 줄에 위치해야한다.
공식 문서 왈)
# syntax 지시문에 docker/dockerfile:1 을 사용하는걸 추천
-> version 1의 최신 버전을 가르킨다.
Buildkit가 빌드하기 전에 syntax의 업데이트를 자동으로 확인해서 최신 버전을 사용하고 있는지 확인한다.
Base Image
FROM ubuntu:22.04
기본 이미지를 Ubuntu 22.04 릴리스로 설정하는 명령어
다음 명령어가 모두 이 기본 이미지에서 실행된다.
이미지를 빌드할 때 태그를 붙여줄 때 이 표기법을 사용해서 이미지 이름을 지정하기도한다. 아래 명령어 참고
docker build name -t ubuntu:22.04 .
FROM 명령어에서 사용하는 이미지(여기서는 ubuntu)는 퍼블릭 이미지로 존재한다.
Environments setup
# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
위 명령어는 기본 이미지(여기서는 ubuntu:22.04) 내에서 명령을 실행
위 `RUN` 명령어는 Ubuntu 에서 shell을 실행하여 APT 패키지 인덱스를 업데이트하고 컨테이너에 Python 도구를 설치하는 과정을 진행한다.
Comments
# install app dependencies
`RUN` 명령어 위에 위와 같은 코멘트를 볼 수 있다. Dockerfile에서 주석은 `#` 심볼을 사용한다.
Docker Syntax 도 `#`으로 시작하는데 주석으로 처리되지 않은가?
-> Dockerfile 시작 부분에 나타나는 경우 지시문으로 해석된다.
Installing dependencies
RUN pip install flask==3.0.*
Python 애플리케이션에 필요한 종속성을 설치하는 명령이다.
위 명령어의 전제조건은 `pip`가 빌드 컨테이너 내에 설치된다.
첫번째 `RUN` 명령은 Flask 웹 프레임워크를 설치하기 위한 `pip`를 설치하는 명령이다.
그럼 첫번째 run명령어는 컨테이너에 설치되지 않는가?
Copy files
COPY hello.py /
`hello.py` 파일을 local build context로부터 우리 이미지의 root directory에 복사한다.
`COPY` 명령어 이후에 `hello.py` 파일은 빌드 컨테이너 파일 시스템에 추가된다. -> docker build 명령어 입력시 copy를 만나면 컨테이너 만들면서 파일 시스템에 추가?
Setting environment variables
ENV FLASK_APP=hello
우리 애플리케이션이 환경변수를 사용한다면 (application.yml에서 민감정보 노출을 막기 위해 환경변수로 사용) `ENV` 명령어를 사용해서 도커 빌드시 환경변수로 사용할 수 있다.
Exposed ports
`EXPOSE` 명령어는 최종 이미지가 listening 할 포트를 지정해준다.
EXPOSE 8000
공식 문서 왈)
위 명령어는 필수는 아니지만 좋은 관행이다.
팀원이 위 명령어를 보고 해당 애플리케이션의 기능을 이해하는 데 도움을 준다.
Starting the application
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
`CMD` 명령어는 해당 이미지를 build 해서 컨테이너화할 때 실행되는 명령어를 설정할 수 있다.
위 명령어를 해석해보면 모든 주소에 대한 8000 포트로 접속하면 Flask 서버를 시작할 수 있다. 위의 예시에서는 `exec` 형식을 사용했고, `shell` 형식으로도 사용할 수 있다. 아래코드 참고
CMD flask run --host 0.0.0.0 --port 8000
Docker Image Build
docker build -t test:latest .
`-t test:latest`: 이미지의 태그와 이름을 명시해준 옵션이다.
명령어 끝에 있는 구두점(`.`) 은 현재 디렉토리를 빌드 컨텍스트로 설정하는 것이다.
즉, 빌드는 Dockerfile 과 hello.py 파일을 명령어가 호출된 디렉토리에서 찾을 것으로 예상한다. 해당 파일이 없으면 빌드가 실패한다.
-> docker build 하는 명령어는 Dockerfile이 있는 디렉토리에서 수행해야한다.
이미지가 빌드된 후에는 `docker run` 명령어로 컨테이너오 애플리케이션을 실행할 수 있다.(이미지 이름 명시해서 실행 가능)
docker run -p 127.0.0.1:8000:8000 test:latest
해당 명령어는 8000포트로 컨테이너를 실행하고, local의 8000포트를 통해 8000 포트로 열린 컨테이너로 포트포워딩 된다.
'DevOps > Docker' 카테고리의 다른 글
[Gitub Action] Pull Requst 했을 때 프로젝트 빌드 테스트하기 (1) | 2024.10.29 |
---|---|
[Docker] Multi-Stage (0) | 2024.10.23 |
[Docker] Build Context (0) | 2024.10.23 |
[Docker] 캐시를 사용한 효율적인 빌드 수행 방법(1) - Docker Build Cache 무효화 (3) | 2024.10.19 |
Dockerfile overview
Learn about Dockerfiles and how to use them with Docker Images to build and package your software
docs.docker.com
Docker는 Dockerfile에서 명령어를 읽어 이미지를 빌드한다. Dockerfile은 소스코드를 빌드하기 위한 명령어가들어 있는 텍스트 파일이다.
Dockerfile에 사용되는 명령어
FROM <image>
: 이미지의 기준이 되는 것을 정의
RUN <command>
: 현재 이미지 위의 새 레이어에서 모든 명령을 실행하고 결과를 커밋.
WORKDIR <directory>
: RUN
, CMD
, ENTRYPOINT
, COPY
, ADD
명령어에 대한 작업 디렉터리를 설정
'COPY <src> <dest>
: <src>
에 위치한 새 파일이나 경로를 컨테이너 파일 시스템인 컨테이너 경로 <dest>
에 추가한다.
CMP <command>
: 이 이미지를 기반으로 컨테이너를 시작하면 실행되는 기본 프로그램을 정의할 수 있다. 각 Dockerfile에는 하나의 CMD
만 있으며, CMD
인스턴스가 여러개 있을 경우 마지막 인스턴스만 취급한다.
Dockerfile 이름 지정
docker build
명령어에 --file
플래그를 사용해서 Dockerfile 이름을 지정할 수 있다. 자세한 내용을 docker build CLI reference를 참고.
공식 문서에서는 이름 지정하는 것보단 기본 Dockerfile을 사용하는걸 권장하고 있다.
Docker 사용하는 이유
Docker 이미지는 레이어로 구성되어 있다. 각 레이어는 Dockerfile 의 빌드 명령의 결과.
레이어는 순차적으로 쌓이고, 각각은 이전 레이어에 적용된 변경 사항을 나타낸다.
다음은 Flask 프레임워크를 사용해서 "Hellow World" 애플리케이션을 보여준다.
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!"
만일 도커를 사용하지 않고 배포하려면 아래와 같은 과정을 따라야함
- 필수 런타임 종속성을 서버에 설치
- Python 코드를 서버의 파일 시스템에 업로드
- 서버를 필요한 매개변수를 사용해서 애플리키이션을 시작
Dockerfile을 사용한다면
- 모든 종속성이 설치되어 있고
- 애플리케이션을 자동으로 시작하는 컨테이너 이미지를 만든다.
# syntax=docker/dockerfile:1 FROM ubuntu:22.04 # install app dependencies RUN apt-get update && apt-get install -y python3 python3-pip RUN pip install flask==3.0.* # install app COPY hello.py / # final configuration ENV FLASK_APP=hello EXPOSE 8000 CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
Dockerfile의 살펴보기
# syntax=docker/dockerfile:1 FROM ubuntu:22.04 # install app dependencies RUN apt-get update && apt-get install -y python3 python3-pip RUN pip install flask==3.0.* # install app COPY hello.py / # final configuration ENV FLASK_APP=hello EXPOSE 8000 CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
위 도커 파일의 레이어를 하나씩 살펴보자
Dockerfile syntax
# syntax=docker/dockerfile:1
Dockerfile 첫번째 줄에는 # syntax
지시문이 온다.
이 지시문은 선택사항이지만 Dockerfile을 파싱할때 사용할 구문을 Docker 빌더에게 지시하고, BuildKit 의 활성화된 이전 Docker 버전이 빌드를 시작하기 전에 특정 Dockerfile 프런트엔드를 사용할 수 있도록 한다.
이 지시문은 Dockerfile 첫번째 줄에 위치해야한다.
공식 문서 왈)
# syntax 지시문에 docker/dockerfile:1 을 사용하는걸 추천
-> version 1의 최신 버전을 가르킨다.
Buildkit가 빌드하기 전에 syntax의 업데이트를 자동으로 확인해서 최신 버전을 사용하고 있는지 확인한다.
Base Image
FROM ubuntu:22.04
기본 이미지를 Ubuntu 22.04 릴리스로 설정하는 명령어
다음 명령어가 모두 이 기본 이미지에서 실행된다.
이미지를 빌드할 때 태그를 붙여줄 때 이 표기법을 사용해서 이미지 이름을 지정하기도한다. 아래 명령어 참고
docker build name -t ubuntu:22.04 .
FROM 명령어에서 사용하는 이미지(여기서는 ubuntu)는 퍼블릭 이미지로 존재한다.
Environments setup
# install app dependencies RUN apt-get update && apt-get install -y python3 python3-pip
위 명령어는 기본 이미지(여기서는 ubuntu:22.04) 내에서 명령을 실행
위 RUN
명령어는 Ubuntu 에서 shell을 실행하여 APT 패키지 인덱스를 업데이트하고 컨테이너에 Python 도구를 설치하는 과정을 진행한다.
Comments
# install app dependencies
RUN
명령어 위에 위와 같은 코멘트를 볼 수 있다. Dockerfile에서 주석은 #
심볼을 사용한다.
Docker Syntax 도#
으로 시작하는데 주석으로 처리되지 않은가?
-> Dockerfile 시작 부분에 나타나는 경우 지시문으로 해석된다.
Installing dependencies
RUN pip install flask==3.0.*
Python 애플리케이션에 필요한 종속성을 설치하는 명령이다.
위 명령어의 전제조건은 pip
가 빌드 컨테이너 내에 설치된다.
첫번째 RUN
명령은 Flask 웹 프레임워크를 설치하기 위한 pip
를 설치하는 명령이다.
그럼 첫번째 run명령어는 컨테이너에 설치되지 않는가?
Copy files
COPY hello.py /
hello.py
파일을 local build context로부터 우리 이미지의 root directory에 복사한다.
COPY
명령어 이후에 hello.py
파일은 빌드 컨테이너 파일 시스템에 추가된다. -> docker build 명령어 입력시 copy를 만나면 컨테이너 만들면서 파일 시스템에 추가?
Setting environment variables
ENV FLASK_APP=hello
우리 애플리케이션이 환경변수를 사용한다면 (application.yml에서 민감정보 노출을 막기 위해 환경변수로 사용) ENV
명령어를 사용해서 도커 빌드시 환경변수로 사용할 수 있다.
Exposed ports
EXPOSE
명령어는 최종 이미지가 listening 할 포트를 지정해준다.
EXPOSE 8000
공식 문서 왈)
위 명령어는 필수는 아니지만 좋은 관행이다.
팀원이 위 명령어를 보고 해당 애플리케이션의 기능을 이해하는 데 도움을 준다.
Starting the application
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
CMD
명령어는 해당 이미지를 build 해서 컨테이너화할 때 실행되는 명령어를 설정할 수 있다.
위 명령어를 해석해보면 모든 주소에 대한 8000 포트로 접속하면 Flask 서버를 시작할 수 있다. 위의 예시에서는 exec
형식을 사용했고, shell
형식으로도 사용할 수 있다. 아래코드 참고
CMD flask run --host 0.0.0.0 --port 8000
Docker Image Build
docker build -t test:latest .
-t test:latest
: 이미지의 태그와 이름을 명시해준 옵션이다.
명령어 끝에 있는 구두점(.
) 은 현재 디렉토리를 빌드 컨텍스트로 설정하는 것이다.
즉, 빌드는 Dockerfile 과 hello.py 파일을 명령어가 호출된 디렉토리에서 찾을 것으로 예상한다. 해당 파일이 없으면 빌드가 실패한다.
-> docker build 하는 명령어는 Dockerfile이 있는 디렉토리에서 수행해야한다.
이미지가 빌드된 후에는 docker run
명령어로 컨테이너오 애플리케이션을 실행할 수 있다.(이미지 이름 명시해서 실행 가능)
docker run -p 127.0.0.1:8000:8000 test:latest
해당 명령어는 8000포트로 컨테이너를 실행하고, local의 8000포트를 통해 8000 포트로 열린 컨테이너로 포트포워딩 된다.
'DevOps > Docker' 카테고리의 다른 글
[Gitub Action] Pull Requst 했을 때 프로젝트 빌드 테스트하기 (1) | 2024.10.29 |
---|---|
[Docker] Multi-Stage (0) | 2024.10.23 |
[Docker] Build Context (0) | 2024.10.23 |
[Docker] 캐시를 사용한 효율적인 빌드 수행 방법(1) - Docker Build Cache 무효화 (3) | 2024.10.19 |