도커 - 복잡한 개발 환경 부분
in Docker
1. DB 구성
- 개발 환경과 운영 환경 각각에서 DB구성이 다름
- DB작업은 중요한 데이터들을 보관하고 이용하는 부분이기에 실제 중요한 데이터들을 다루는 운영 환경에서는 더욱 안정적인 AWS RDS를 이용하여 DB를 구성하는 것이 실무에서 더 보편적으로 쓰이는 방법
개발 환경과 운영 환경에서의 자세한 구성도이다. 개발환경 그림은 짤렸는데 아래에는 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 설정
- 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 : 리액트 앱을 종료할 때 나오는 버그 잡아줌
- build
- nginx
- restart : 재시작 정책으로 서버가 갑작스럽게 꺼질 경우에 재시작에 대한 설정
- no : 어떤 상황에도 재시작 안함
- always : 항상 재시작
- on-failure : 에러코드와 함께 컨테이너가 멈출때만 재시작
- unless-stopped : 개발자가 임의로 멈추려고 할때 제외하고는 항상 재시작
- nginx는 중요하게 항상 떠있어야 하므로 always로 설정
- ports : 로컬:컨테이너 포트 매핑
- restart : 재시작 정책으로 서버가 갑작스럽게 꺼질 경우에 재시작에 대한 설정
- backend:
- container_name : 컨테이너 이름(여기서는 그냥 줘봤음)
- mysql
- build : 도커파일 위치
- volumes
- 현재까지는 volume의 용도를 코드를 업데이트 할때 바로 애플리케이션에 적용되도록 하기 위해 사용했음
- mysql에 사용하는 volume은 데이터베이스의 저장된 자료를 컨테이너를 지우더라도 자료가 사라지지 않게 하기 위한 볼륨
- volume을 사용하지 않으면 컨테이너 삭제시 컨테이너에 있는 데이터들도 삭제됨
- 컨테이너에서 변화가 일어난 데이터가 컨테이너 안에 저장되는 것이 아닌 호스트 파일 시스템에 저장되게 하여 그 중에서도 도커에 의해서만 통제가 되는 도커 Area에 저장되므로 컨테이너를 삭제해도 변화된 데이터가 사라지지 않게 함
- environment
- MYSQL_ROOT_PASSWORD : 루트 계쩡 비밀번호
- MYSQL_DATABASE : 데이터베이스 이름