jiiheee's 개발 일지

[Docker] Docker 배포 (+Docker-compose) 본문

📚 Study/Docker

[Docker] Docker 배포 (+Docker-compose)

◼️ 2024. 1. 7. 01:40

서버를 만들면서 웹서버와 DB는 필수 요소이다. 둘 중 하나가 없다면 서버는 절대 작동하지 않는다. 이런 서버를 배포하는 방법은 다양하지만 오늘은 Docker를 이용하여 배포하고자 한다. 그동안 AWS를 통해서 배포했었는데 그럴 때마다 서버에 필요한 모듈들이 없어서 번거로움이 있었는데 이럴 때는 Docker를 활용하면 효율적으로 배포할 수 있다.

 

그냥 컨테이너 하나만 배포할 수 있지만 보통 서버 하나가 작동하기 위해서는 DB가 필수요소이기 때문에 Docker-compose로 배포하고자 한다.


Docker-compose란?

다중 컨테이너를 실행하고 정의하기 위한 도구이다. 여러 개의 컨테이너를 묶어서 관리하는 도구라고 생각한다. 서버가 돌아가기 위해서는 DB가 필수적이고 DB도 서버가 있어야 data를 저장할 수 있기 때문에 두 개를 한 번에 묶어서 관리하면 더 효율적으로 관리하고 실행할 수 있다.


배포 방법

로컬에서 만든 서버를 어떤 환경에서든 실행되도록 하기 위해서는 크게 두 가지가 필요하다.

첫 번째는 서버가 돌아가기 위한 코드 서버가 돌아갈 수 있는 환경이다. 이는 쉽게 비유하면 붕어빵에 비유할 수 있다.

서버가 돌아갈 수 있는 환경은 붕어빵 틀에 해당하고 서버가 직접적으로 돌아가게 만드는 코드는 붕어빵 재료가 될 수 있다. 틀에 재료를 넣고 구워야 붕어빵을 만들 수 있다. 앞으로 진행할 순서는 붕어빵 틀을 제작하는 과정이라고 생각할 수 있다.

 

방법은 크게 4가지 프로세서를 통해 배포한다. 순서가 매우 중요하므로 순서를 꼭 지켜서 실행한다.

 

  1. 앱의 환경을 정의하여 어디에서나 재사용할 수 있는 Dockerfile을 정의한다.
  2. docker-compose.yml 에서 앱을 구성할 수 있는 서비스를 정의합니다. 그래서 단 하나의 환경에서 실행할 수 있게 한다.
  3. docker build를 통해 서버가 실행될 수 있도록 image를 만든다.
  4. docker push를 통해 Docker hub에 업데이트한다.

 

1번은 말 그대로 서버가 어디에서나 사용될 수 있도록 Dockerfile을 생성한다. 기본적으로 설치되어야 하는 모듈들과 포트 번호를 적어준다.

 

<Dockerfile>

# 공식 Python 이미지를 기본 이미지로 사용
FROM python:3.8

# 컨테이너 내에서 작업 디렉토리 설정
WORKDIR /app

# requirements 파일을 컨테이너로 복사
COPY . /app/

# 모듈 설치
RUN pip install asgiref && pip install Django
RUN pip install djangorestframework && pip install python-multipart
RUN pip install pytz && pip install sqlparse

# 현재 디렉토리의 내용을 컨테이너로 복사
COPY . /app/

# Django가 실행될 포트 노출
EXPOSE 8000

# Django 개발 서버 실행
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

 

2번은 각 컨테이너를 띄우기 위한 설정값이다. 서버보다 db를 먼저 띄워야 하니 db를 먼저 작성한다.

(서버를 먼저 띄우면 나중에 실행할 때 db가 뜨기 전이라 서버 실행하는데 오류가 날 수 있으니 반드시 db가 먼저 뜰 수 있도록 한다.)

 

<docker-compose.yml>

version: '3'

services:
  db:
    image: postgres:latest  # 또는 다른 데이터베이스 이미지를 사용
    container_name: myapp_db
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myappuser
      POSTGRES_PASSWORD: myapppassword

  web:
    build: .
    container_name: myapp_web
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    depends_on:
      - db
    environment:
      - DJANGO_DEBUG=True
      - DJANGO_DB_ENGINE=django.db.backends.sqlite3
      - DJANGO_DB_NAME=/app/db.sqlite3

 

3번은 필요한 설정들은 모두 마쳤으니 이 상태에서 아래 명령어를 이용해 image를 생성한다. 

docker build -t your-docker-hub-username/your-image-name:tag .

# your-docker-hub-username: docker hub 사용자 이름
# your-image-name: 생성할 image 이름
# tag: version

 

docker에서 image는 붕어빵 틀과 비슷하고 생각했다. 서버라는 붕어빵을 만들기 위한 틀이라고 생각이 들어 쉽게 이해할 수 있었다.


 

4번은 아래 명령어를 통해서 방금 생성한 image를 docker hub에 올려준다.

docker push your-docker-hub-username/your-image-name:tag

# 각 변경 요소들은 3번 설명과 동일하니 생략

 

여기까지가 내가 로컬에서 만든 서버를 다른 환경에서도 실행할 수 있도록 docker hub에 올리는 과정이다.


 

실행 방법

서버를 실행하기 위해서는 코드와 환경 모두 필요하므로 github를 통해서 코드를 받아온다. github에는 Dockerfile과 docker-compose.yml파일은 업로드되지 않기 때문에 docker hub에서 받아온다. 

 

  1. docker-compose.yml 파일 생성
  2. docker pull로 Dockerfile 생성

1번은 docker-compose.yml을 생성하는데 로컬에서 작성한 코드랑 다른 부분이 있다.

version: '3'

services:
  db:
    image: postgres:latest  # 또는 다른 데이터베이스 이미지를 사용
    container_name: myapp_db
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myappuser
      POSTGRES_PASSWORD: myapppassword

  web:
    image: your-docker-hub-username/your-image-name:tag 
    container_name: myapp_web
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    depends_on:
      - db
    environment:
      - DJANGO_DEBUG=True
      - DJANGO_DB_ENGINE=django.db.backends.sqlite3
      - DJANGO_DB_NAME=/app/db.sqlite3

   # 13번째 줄에 로컬에서는 build: . 으로 작성했지만 다른 환경에서는 docker hub에 공유된 이미지를 사용해야하므로 수정해준다.

 

서버가 실행될 수 있도록 박제해놓은 image를 사용해서 컨테이너를 실행해야 하므로 build가 아닌 Image로 수정하며 사용할 이미지를 적는다.


2번은 Dockerfile은 docker hub에 공유된 명령어를 사용하여 생성한다. 

docker pull ~~ 이 부분을 복사한 뒤 터미널에서 실행한다.

 

위 순서대로 진행하면 공유된 이미지를 통해서 어떤 환경에서도 서버를 실행할 수 있다.