dockerfile 은 이미지를 직접 생성할 목적으로 작성되는 파일이다. 우리가 직접 필요한 이미지를 만들어 우분투를 실행할 때 별도의 업데이트 없이 바로 장고를 실행할 수 있도록 만들 수도 있고, 혹은 미리 필요한 설정들을 해놓을 수도 있다.
우선 vi Dockerfile
을 통해 도커파일을 생성해준다. 이때 docker-compose 와 마찬가지로 철자가 틀릴 시 인식이 되지 않으니 신중하게 적어준다.
Dockerfile
# 빌드할 때 사용할 이미지를 지정해줍니다.
FROM httpd:latest
# 현재 경로에 존재하는 index.html 파일을 컨테이너 내부로 복사합니다.
COPY ./index.html /usr/local/apache2/htdocs/index.html
from 이나 copy 외에도 run, env 등의 명령어를 사용해서 이미지를 생성해줄 수 있다.
다음에는 docker-compose.yml 을 다시 편집한다.
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.
services:
example: # 서비스 이름을 지정합니다. 서비스 이름은 컨테이너끼리 통신할 때 사용됩니다.
container_name: example # 컨테이너 이름을 지정합니다.
build: . # 현재 경로에 있는 Dockerfile을 사용해 이미지를 생성합니다.
ports: # 포트포워딩을 설정해줍니다.
- 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결해줍니다.
restart: always # 컨테이너가 종료됐을 때 다시 실행시켜 줍니다.
dockerfile 을 만들 때 copy 를 통해 ./index.html 을 컨테이너 내부에 복사해줬기 때문에 동일한 이름으로 편집해준 다음 해당 이미지를 실행한다.
sudo docker compose up --build -d
이미지가 빌드되어 있지 않을 때는 --build 옵션을 주지 않아도 괜찮지만 이미지를 빌드한 후에 새로운 이미지를 배경으로 실행할 때는 --build 를 붙여줘야 한다. 없을 시 도커파일로 빌드된 이미지를 사용하는 것이 아니라 기본 이미지를 빌드하여 실행되기 때문이다. 그러면 이미지가 정상적으로 빌드되었다는 메세지와 함께 컨테이너가 실행된다.
도커가 실행될 때 기본적으로 생성되는 옵션이다. dockerfile 에 써줘도 좋고 docker-compose.yml 에 써줘도 괜찮지만, 둘 다 작성 시 docker-compose.yml 의 엔트리포인트 우선순위가 더 높다.
Dockerfile
FROM python:3.9.15
# .pyc 파일을 생성하지 않도록 설정합니다.
ENV PYTHONDONTWRITEBYTECODE 1
# 파이썬 로그가 버퍼링 없이 즉각적으로 출력하도록 설정합니다.
ENV PYTHONUNBUFFERED 1
# /app/ 디렉토리를 생성합니다.
RUN mkdir /app/
# /app/ 경로를 작업 디렉토리로 설정합니다.
WORKDIR /app/
# main.py 파일을 /app/ 경로로 복사합니다.
COPY ./main.py /app/
dockerfile 을 수정해줬으니 docker-compose.yml 도 수정해주자.
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.
services:
example: # 서비스 이름을 지정합니다. 서비스 이름은 컨테이너끼리 통신할 때 사용됩니다.
container_name: example # 컨테이너 이름을 지정합니다.
build: . # 현재 경로에 있는 Dockerfile을 사용해 이미지를 생성합니다.
entrypoint: sh -c "python3 main.py" # 작업 디렉토리에 존재하는 main.py 파일을 실행시킵니다.
restart: always # 컨테이너가 종료됐을 때 다시 실행시켜 줍니다.
이 뒤에 main.py 라는 임의의 파이썬 파일을 작성해준 뒤 실행한다.
main.py
from time import sleep
for i in range(100):
print(f"print number : {i}")
sleep(1)
sudo docker compose logs -f
를 쳐보면 제대로 실행되는 모습을 볼 수 있다.
컨테이너를 두 개 이상 사용할 시 docker-compose.yml 을 작성하는 방법은 기존과 크게 다르지 않지만, 컨테이너 이름이나 포트 번호 등 중복되면 안 되는 몇 가지 옵션들이 존재하기 때문에 이를 확인한 뒤에 실행해야 한다.
같은 docker-compose.yml 파일 안에 두 개의 서비스를 써준다.
version: '3.8'
services:
example1:
container_name: example1
image: 'httpd:latest'
ports:
- 80:80
restart: always
example2: # 서비스 이름이 동일하면 컨테이너가 정상적으로 생성되지 않을 수 있습니다.
container_name: example2 # 컨테이너 이름이 동일하면 컨테이너 생성 시 에러가 발생합니다.
build: .
entrypoint: sh -c "python3 main.py"
restart: always
아래처럼 두 개의 컨테이너가 실행되는 것이 보인다.