도커 - 복잡한 개발 환경 부분

1. DB 구성


그림1

  • 개발 환경과 운영 환경 각각에서 DB구성이 다름
  • DB작업은 중요한 데이터들을 보관하고 이용하는 부분이기에 실제 중요한 데이터들을 다루는 운영 환경에서는 더욱 안정적인 AWS RDS를 이용하여 DB를 구성하는 것이 실무에서 더 보편적으로 쓰이는 방법


그림2 그림3

개발 환경과 운영 환경에서의 자세한 구성도이다. 개발환경 그림은 짤렸는데 아래에는 AWS RDS인 MYSQL이 연결되어 있다.

2. MYSQL 도커


FROM mysql:5.7

ADD ./my.cnf /etc/mysql/conf.d/my.cnf


한글이 깨지지 않도록 추가적인 작업 필요 -> my.cnf 파일 생성

[mysqld]
character-set-server=utf8

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8


3. Nginx 설정


그림4

  • proxy Nginx는 요청이 프론트로 갈지, 백엔드로 갈지 구분하는 설정이 필요
  • front 안에 있는 Nginx는 js, html, css를 클라이언트에서 요청했을 때 알맞은 것을 제공하기 위한 것

front Nginx 설정

server {
    listen 3000;

    location / {

        root /usr/share/nginx/html;

        index index.html index.htm;

        try_files $uri  $uri/ /index.html;

    }
}
  • listen : Nginx 서버 포트
  • location : 슬래시는 그림 보면 location/ 로 갈때를 의미
  • root : html 파일이 위치할 루트 설정
  • index : 사이트의 index 페이지로 할 파일명 설정
  • try 부분은 리액트 라우터를 사용해서 페이지간 이동할 때 필요한 부분


proxy Nginx

upstream frontend {
    server frontend:3000;
}

upstream backend {
    server backend:5000;
}

server {
    listen 80;

    location / {
        proxy_pass http://frontend;
    }

    location /api {
        proxy_pass http://backend;
    }

    location /sockjs-node {
        proxy_pass http://frontend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

}
  • upstream 서비스명 : 3000번 포트로 해당 서비스가 돌고 있다는 것
    • 서비스명은 도커컴포즈에서 서비스에 작성하는 이름
  • listen : Nginx가 80번 포트에서 돌고 있음
  • location : 뒤에는 path적어주고 proxy_pass에는 http 이후에는 도커 컴포즈에서 작성한 서비스 명 작성
    • /로 오면 proxy pass를 프론트로, /api로 오면 백엔드로
    • /만 있는 것이 우선순위가 가장 낮아 /api를 먼저 찾음
  • sockjs-node는 react만을 위한 설정


도커파일

FROM nginx
COPY ./default.conf  /etc/nginx/conf.d/default.conf
  • 작성된 conf 파일을 컨테이너에서 실행될 Nginx에도 적용될 수 있게 COPY


4. 도커 컴포즈로 컨테이너들 연결시켜주기


# docker-compose.yml
version: "3"
services:
  frontend:
    build:
      dockerfile: Dockerfile.dev
      context: ./frontend
    volumes:
      - /app/node_modules
      - ./frontend:/app
    stdin_open: true

  nginx: 
    restart: always
    build:
      dockerfile: Dockerfile
      context: ./nginx
    ports: 
      - "3000:80"

  backend:
    build: 
      dockerfile: Dockerfile.dev
      context: ./backend
    container_name: app_backend
    volumes:
      - /app/node_modules
      - ./backend:/app
            
  mysql:
    build: ./mysql
    restart: unless-stopped
    container_name: app_mysql
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/mysql_data:/var/lib/mysql
      - ./mysql/sqls/:/docker-entrypoint-initdb.d/
    environment:
      MYSQL_ROOT_PASSWORD: johnahn
      MYSQL_DATABASE: myapp
  • frontend
    • build
      • dockerfile : 사용할 도커파일 이름
      • context : 도커 파일 위치
    • volumes
      • 코드 수정후 다시 이미지 빌드 없이 수정된 코드가 반영되기 위해서 사용
      • /app/node_modules 는 참조하지 않음
      • ./frontend:/app : 로컬에 frontend에 있는 것은 /app 에서 참고
      • stdin_open: true : 리액트 앱을 종료할 때 나오는 버그 잡아줌
  • nginx
    • restart : 재시작 정책으로 서버가 갑작스럽게 꺼질 경우에 재시작에 대한 설정
      • no : 어떤 상황에도 재시작 안함
      • always : 항상 재시작
      • on-failure : 에러코드와 함께 컨테이너가 멈출때만 재시작
      • unless-stopped : 개발자가 임의로 멈추려고 할때 제외하고는 항상 재시작
      • nginx는 중요하게 항상 떠있어야 하므로 always로 설정
    • ports : 로컬:컨테이너 포트 매핑
  • backend:
    • container_name : 컨테이너 이름(여기서는 그냥 줘봤음)
  • mysql
    • build : 도커파일 위치
    • volumes
      • 현재까지는 volume의 용도를 코드를 업데이트 할때 바로 애플리케이션에 적용되도록 하기 위해 사용했음
      • mysql에 사용하는 volume은 데이터베이스의 저장된 자료를 컨테이너를 지우더라도 자료가 사라지지 않게 하기 위한 볼륨
      • volume을 사용하지 않으면 컨테이너 삭제시 컨테이너에 있는 데이터들도 삭제됨
      • 컨테이너에서 변화가 일어난 데이터가 컨테이너 안에 저장되는 것이 아닌 호스트 파일 시스템에 저장되게 하여 그 중에서도 도커에 의해서만 통제가 되는 도커 Area에 저장되므로 컨테이너를 삭제해도 변화된 데이터가 사라지지 않게 함
    • environment
      • MYSQL_ROOT_PASSWORD : 루트 계쩡 비밀번호
      • MYSQL_DATABASE : 데이터베이스 이름

그림5



본 포스팅은 인프런 John Ahn님의 ‘따라하며 배우는 도커와 CI환경’ 강의를 듣고 정리한 내용을 바탕으로 복습을 위해 작성하였습니다. [강의 링크]


© 2021. By Backtony