[Docker] 예제

2024. 12. 9. 19:45Tools/Docker

 

3번의 프로젝트를 진행하면서 추후 참고할 만한 부분만 가져왔습니다.

 


1. 디렉터리 구조

 

  • frontend, backend 소스코드에 이미지 빌드를 위한 Dockerfile을 생성.
  • https 인증서 발급을 위한 cert-compose.ymlnginx.conf.
  • db를 위한 db-compose.yml 생성.
  • application 실행을 위한 app-compose.yml과 reverse proxy를 위한 nginx 설정 파일들 추가.

 


2. Dockerfile 예시

 

가. frontend (react)

# 5173 port를 사용하는 React를 정적으로 빌드하다음 Nginx를 이용해 배포한다.

# nginx 이미지를 사용합니다. 뒤에 tag가 없으면 latest 를 사용합니다.
FROM nginx:1.26.1

# root 에 app 폴더를 생성
RUN mkdir /app

# work dir 고정
WORKDIR /app

# work dir 에 build 폴더 생성 /app/build
RUN mkdir /build

# host pc의 현재경로의 dist 폴더를 workdir 의 build 폴더로 복사
ADD ./dist ./build

# nginx 의 default.conf 를 삭제
RUN rm /etc/nginx/conf.d₩/default.conf

# 80 포트 오픈
EXPOSE 80
# 443 포트 오픈
EXPOSE 443

# container 실행 시 자동으로 실행할 command. nginx 시작함
CMD ["nginx", "-g", "daemon off;"]
  • React 빌드 후 생성된 정적 파일을 nginx에서 서빙하도록 구성.

 


나. backend (java)

FROM openjdk:17-oracle
EXPOSE 8080
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENV TZ=Asia/Seoul
ENTRYPOINT ["java","-jar","/app.jar"]
  • Spring boot 빌드 후 생성된 jar 파일을 실행하도록 구성.

 


다. backend (python)

FROM ubuntu:22.04

# Set Environment Variables
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Seoul

# Install dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    python3.11 \
    python3-pip && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

# update pip to 24.2
RUN python3 -m pip install --upgrade pip==24.2

# Set default Python and pip commands
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 && \
    update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

# UTF-8 환경 설정
ENV PYTHONENCODING=utf-8

# Set a working directory
WORKDIR /app

# Make src directory and copy the source code
RUN mkdir src

# Copy the current directory contents into the container at /app
COPY requirements.txt /app/

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Install dependencies for Firefox
RUN apt-get update && apt-get install -y \
    wget \
    bzip2 \
    libgtk-3-0 \
    libdbus-glib-1-2 \
    libxt6 \
    libx11-xcb1 \
    libpci3 \
    libasound2 \
    libxcomposite1 \
    libxdamage1 \
    libxfixes3 \
    libcairo2 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libxtst6 \
    libgtk2.0-0 \
    && rm -rf /var/lib/apt/lists/*

# Install Firefox
# RUN apt-get update && apt-get install -y firefox==132.0.2
WORKDIR /tmp
RUN wget https://download-installer.cdn.mozilla.net/pub/firefox/releases/132.0.2/linux-x86_64/en-US/firefox-132.0.2.tar.bz2
RUN tar xjf firefox-132.0.2.tar.bz2 && mv firefox /opt/firefox && ln -s /opt/firefox/firefox /usr/local/bin/firefox

# Install geckodriver
RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.35.0/geckodriver-v0.35.0-linux64.tar.gz
RUN tar -xvzf geckodriver-v0.35.0-linux64.tar.gz
RUN chmod +x geckodriver && mv geckodriver /usr/local/bin/

# Remove unnecessary files
RUN rm -rf /tmp/*

# Copy source code
WORKDIR /app
COPY src /app/src

CMD ["python3", "/app/src/main.py"]
  • 실행에 필요한 dependency 설치 후 python 실행.

 


3. docker-compose.yml 예시

 

가. certbot

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot

  certbot:
    image: certbot/certbot
    command: certonly --webroot --webroot-path=/var/www/certbot --email fkaus4598@naver.com --agree-tos --no-eff-email -d mobipay.kr -d merchant.mobipay.kr
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    depends_on:
      - nginx
  • 구매한 도메인으로 https 인증서 발급.

 


나. db (mysql)

services:
  mobi-db:
    image: mysql:8.4.1
    volumes:
      - mobi-db-data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MOBI_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MOBI_DATABASE}
      MYSQL_USER: ${MOBI_USER}
      MYSQL_PASSWORD: ${MOBI_PASSWORD}
      TZ: Asia/Soeul
      LANG: C.UTF-8
    expose:
      - 3306
    networks:
      - mobi-network
    container_name: mobi-db

  mer-db:
    image: mysql:8.4.1
    volumes:
      - mer-db-data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MER_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MER_DATABASE}
      MYSQL_USER: ${MER_USER}
      MYSQL_PASSWORD: ${MER_PASSWORD}
      TZ: Asia/Soeul
      LANG: C.UTF-8
    expose:
      - 3306
    networks:
      - mer-network
    container_name: mer-db

volumes:
  mobi-db-data:
  mer-db-data:

networks:
  mobi-network:
    name: mobi-network
    driver: bridge
  mer-network:
    name: mer-network
    driver: bridge
  • mysql 컨테이너와 네트워크를 생성한다.

 


다. app

services:
  reverse-proxy:
    image: ramen4598/mobipay_nginx:latest
    depends_on:
      - mobi-backend
      - mer-backend
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/:/etc/nginx/
      - ../cert/data/certbot/conf:/etc/letsencrypt
      - ../cert/data/certbot/www:/var/www/certbot
    networks:
      - reverse-proxy
    restart: always
    container_name: reverse-proxy

  mobi-backend:
    image: ramen4598/mobipay_mobipay:latest
    env_file:
      - .env
    environment:
      MYSQL_HOST: mobi-db
      MYSQL_PORT: 3306
      MYSQL_DB: ${MOBI_DB}
      MYSQL_USER: ${MOBI_USER}
      MYSQL_PASSWORD: ${MOBI_PASSWORD}
      TZ: Asia/Seoul
    expose:
      - 8080
    networks:
      - reverse-proxy
      - mobi-network
    restart: always
    container_name: mobi-backend

  mer-backend:
    image: ramen4598/mobipay_merchant:latest
    env_file:
      - .env
    environment:
      MYSQL_HOST: mer-db
      MYSQL_PORT: 3306
      MYSQL_DB: ${MER_DB}
      MYSQL_USER: ${MER_USER}
      MYSQL_PASSWORD: ${MER_PASSWORD}
      TZ: Asia/Seoul
    expose:
      - 8080
    networks:
      - reverse-proxy
      - mer-network
    restart: always
    container_name: mer-backend

networks:
  reverse-proxy:
    driver: bridge
  mobi-network:
    external: true
    name: mobi-network
  mer-network:
    external: true
    name: mer-network
  • nginx reverse proxy를 생성.
  • backend 생성.
  • db 연결.

 


라. 기타

services:

  db:
    image: mysql:8.4.1
    volumes:
      - 'mysql_data:/var/lib/mysql'
    profiles: ["dev", "prod"]
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DB}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: Asia/Seoul
      LANG: C.UTF-8
    healthcheck:
      test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
      timeout: 20s
      retries: 10
    expose:
      - "3306"
    networks:
      - moducha
    container_name: moducha_db

    backend-dev:
      depends_on:
        db:
          condition: service_healthy
      profiles:
        - dev
      build:
        context: ./backend
        dockerfile: Dockerfile
      image: moducha_backend
      env_file: '.env'
      restart: 'always'
      expose:
        - "8080"
    ...

 

1) health check

healthcheck:
  test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
  timeout: 20s
  retries: 10

MySQL 컨테이너의 상태를 체크하는 healthcheck 설정이다.

 

mysqladmin ping 명령어로 데이터베이스 연결을 확인하며, 20초 타임아웃에 최대 10번 재시도한다.

 

depends_on:
  db:
    condition: service_healthy

이 설정은 다른 서비스가 MySQL 컨테이너에 의존성이 있을 때 사용된다.

 

MySQL이 완전히 준비된 상태(healthy)일 때만 의존하는 서비스가 시작되도록 보장한다.

 

2) expose & port

expose:
    - "3306"
설정 설명 접근 범위
expose 같은 Docker 네트워크 내 컨테이너 간 통신을 위한 포트 노출 같은 네트워크의 컨테이너만 접근 가능
ports 호스트와 컨테이너 간 포트 매핑 호스트 시스템 및 외부에서 접근 가능

보안을 위해서 외부에 노출할 이유가 없다면 expose를 사용하자.

 

3) env_file

env_file: '.env'

환경 변수를 별도의 .env 파일에서 읽어오도록 설정합니다.

 

민감한 정보를 compose 파일과 분리하여 관리할 수 있게 한다.

 

4) build

build:
  context: ./backend
  dockerfile: Dockerfile

docker compose 실행 시 Docker 이미지를 빌드하는 설정.

 

  • context : 도커 빌드가 실행될 디렉터리 경로를 지정.
  • dockerfile : 사용할 Dockerfile의 이름을 지정. 기본값은 Dockerfile이다.

 


4. env

프레임워크 환경변수 주입 시점 주입 방법
Java Spring 실행 시점 docker-compose의 environment 설정
React 빌드 시점 이미지 빌드 시 포함
Python 실행 시점 docker-compose의 environment 설정

 


'Tools > Docker' 카테고리의 다른 글

[Docker] MySQL 설치  (0) 2023.03.10
[Docker] Multi-architecture build  (0) 2023.03.07
[Docker] Github와의 연동  (0) 2023.02.28
[Docker] 연습하기  (2) 2023.02.27
[Docker] Compose  (0) 2023.02.27