<volume을 사용해 데이터 보존하기>
- 도커는 컨테이너에서 작업한 내용이 컨테이터 down 후 다시 시작하면 바뀐 데이터가 싹 사라짐
- volume은 컨테이너에 저장되는 데이터의 일부를 host와 공유해주는 역할을 함
- host에 저장된 데이터는 사용자가 직접 삭제하지 않는 이상 계속해서 유지되고, 컨테이너가 종료되더라도 데이터가 사라지지 않음
- docker volume 종류
docker volume
- docker 엔진이 관리하는 volume을 생성하는 방식
- docker volume 방식을 사용해 생성된 volume은 host의 /var/lib/docker/volumes/ 경로에 저장됨
- docker에서 가장 권장하는 방식
- 주로 컨테이너간 파일을 공유하거나 중요도가 높은 파일들을 사용자가 쉽게 수정/삭제 하지 못하도록 할 때 사용
bind mount
- docker volume 방식과 매우 유사함
- docker container를 생성할 때 사용자가 지정한 경로에 데이터가 저장됨
- docker 엔진의 관리를 받지 않는 영역이기 때문에 사용자가 직접 파일을 추가/수정/삭제 할 수 있다는 특징이 있음(이런 특징으로 운영에 영향을 미칠 수 있어서 도커 공식 문서에서는 유사한 기능인 docker volume 방식으로 사용하기를 권장함)
- 설정 파일 혹은 소스코드를 프로젝트와 서버가 공유할 때 주로 사용됨
tmpfs mount
- 기존의 방식들이 ssd 혹은 hdd와 같은 저장장치에 데이터를 저장한다면 tmpfs mount 방식은 휘발성 메모리인 RAM에 데이터를 저장함
- 파일로 저장하면 안 되는 민감한 정보를 다룰 때 사용됨
- 많은 양의 데이터를 임시로 저장할 때, 혹은 보안적으로 중요한 데이터를 저장할 때 주로 사용됨
- docker-compose.yml (bind mount)
version: '3.8' # docker-compose.yml에 사용될 문법 버전 정의
services:
example: # 서비스 이름 지정. 서비스 이름은 컨테이너끼리 통신할 때 사용됨
container_name: example # 컨테이너 이름 지정
image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정
ports: # 포트포워딩을 설정
- 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결
volumes: # volume 설정
- ./example_http_code/:/usr/local/apache2/htdocs/ # 정의한 volume의 mount할 경로 지정
restart: always # 컨테이너가 종료됐을 때 다시 실행시킴
- docker-compose.yml (docker volume)
version: '3.8' # docker-compose.yml에 사용될 문법 버전 정의
volumes:
example_http_code: {} # docker volume 정의
services:
example: # 서비스 이름 지정. 서비스 이름은 컨테이너끼리 통신할 때 사용됨
container_name: example # 컨테이너 이름 지정
image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정
ports: # 포트포워딩을 설정
- 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결
volumes: # volume 설정
- example_http_code:/usr/local/apache2/htdocs/ # 정의한 volume의 mount할 경로 지정
restart: always # 컨테이너가 종료됐을 때 다시 실행시킴
- volume 설정 확인하기
sudo docker volume ls # 볼륨 목록 보기
sudo docker volume inspect 볼륨이름 # 특정 볼륨 정보 자세히 보기
- 사용하지 않는 docker volume 삭제하기
sudo docker volume prune # 사용하지 않는 볼륨 일괄 삭제
<이미지 직접 빌드하기>
- Dockerfile이란?
- docker의 이미지를 직접 생성하기 위한 용도로 작성하는 파일
- Dockerfile을 작성할 때는 기본이 되는 이미지를 지정한 후, 특정 패키지를 설치하거나 파일을 추가하는 등의 작업을 통해 사용자가 직접 이미지를 빌드하고 사용할 수 있음
- 사용자가 개발한 프로젝트 혹은 설정파일 등을 이미지에 포함시키거나 이미지에 기본적으로 특정 패키지를 설치하고 싶을 때 다양한 용도로 사용할 수 있음
- Dockerfile 작성하기
vi Dockerfile # Dockerfile 생성 후 편집
# 빌드할 때 사용할 이미지 지정
FROM httpd:latest
# 현재 경로에 존재하는 index.html 파일을 컨테이너 내부로 복사함
COPY ./index.html /usr/local/apache2/htdocs/index.html
Dockerfile에서 자주 사용되는 문법
# 지정한 명령어 실행
RUN mkdir /app/
# docker 이미지에서 사용할 기본 경로 지정
WORKDIR /app/
# 지정한 파일을 컨테이너 내부로 복사
COPY ./app/ /app/
# 이미지에서 사용할 환경변수 지정
ENV DEBUG 1
- docker-compose.yml
version: '3.8' # docker-compose.yml에 사용될 문법 버전 정의
services:
example: # 서비스 이름 지정. 서비스 이름은 컨테이너끼리 통신할 때 사용됨
container_name: example # 컨테이너 이름 지정
build: . # 현재 경로에 있는 Dockerfile을 사용해 이미지 생성
ports: # 포트포워딩을 설정
- 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결해줌
restart: always # 컨테이너가 종료됐을 때 다시 실행시켜 줌
- index.html 직접 만들고 docker 실행해보기
vi index.html
sudo docker compose up --build -d
# 처음에 빌드된 이미지 없을 땐 --build 옵션 없어도 됨
# Dockerfile 수정하고 이미지 새로 빌드해야 할 때는 --build 옵션 넣어야 함
# -d 랑 --build 순서는 상관없음
<entrypoint 활용해보기>
- entrypoint란?
- docker 컨테이너가 생성될 때 기본적으로 실행할 명령어를 지정해주는 옵션
- docker-compost.yml과 Dockerfile 두 군데에 모두 entrypoint가 있다면 Dockerfile의 entrypoint는 무시되고 docker-compose.yml 파일의 entrypoint가 우선적으로 수행됨
- Dockerfile
vi 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/
- docker-compose.yml
vi 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 # 컨테이너가 종료됐을 때 다시 실행시켜 줌
- 임의의 파이썬 파일 만들어서 실행해보기
vi main.py
sudo docker compose up -d --build
sudo docker compose logs -f
<컨테이너를 두 개 이상 띄워보기>
- 주의사항
- docker-compose.yml에 ports 또는 서비스 이름 등 중복되면 안 되는 부분이 있음 주의 필요!
- docker-compose.yml
vi 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
- 컨테이너 생성해보기
sudo docker compose up -d
sudo docker compose logs -f
- depends_on을 사용해 컨테이너 실행 순서 바꿔보기
# docker-compose.yml
version: '3.8'
services:
example1:
container_name: example1
image: 'httpd:latest'
ports:
- 80:80
depends_on:
- example2 # 해당 컨테이너보다 먼저 실행되어야 하는 컨테이너 지정
restart: always
example2: # 서비스 이름이 동일하면 컨테이너가 정상적으로 생성되지 않을 수 있음
container_name: example2 # 컨테이너 이름이 동일하면 컨테이너 생성 시 에러 발생
build: .
entrypoint: sh -c "python3 main.py"
restart: always