20160211

Docker Compose 운영 레시피

Compose v1.6 쓰면서 몇 달 굴려본 운영 레시피. 아직 single host 한정 (멀티노드는 swarm 보고있는중).

기본 셋업은 web + db + redis + nginx 조합이 많음. docker-compose.yml 공유.

version: '2'
services:
  web:
    build: .
    env_file: .env
    depends_on:
      - db
      - redis
    restart: unless-stopped
    volumes:
      - ./app:/app
      - logs:/app/logs
  db:
    image: mysql:5.7
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
      MYSQL_DATABASE: app
    volumes:
      - db-data:/var/lib/mysql
  redis:
    image: redis:3.0-alpine
    restart: unless-stopped
    volumes:
      - redis-data:/data
  nginx:
    image: nginx:1.9
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - web
volumes:
  db-data:
  redis-data:
  logs:

몇 가지 팁:

1. version: '2' 로 올리면 networks 자동 생성. 각 서비스끼리 hostname으로 접근 가능 (web에서 db:3306). 이전 v1 의 links 방식은 deprecated.

2. restart: unless-stopped. 호스트 재부팅 후에도 자동 재시작. always는 수동으로 stop한 것까지 살리니까 우리는 unless-stopped.

3. depends_on은 start 순서만 보장함. "DB가 connection ready" 를 보장하지 않음. 그래서 web 컨테이너 entrypoint 스크립트에서 mysql 포트 열릴때까지 wait 하는 로직 넣음:

#!/bin/sh
until nc -z db 3306; do
  echo "waiting for db..."
  sleep 1
done
exec "$@"

4. named volume 쓸 것. bind mount는 권한 이슈가 자주 생김 (컨테이너의 uid와 호스트의 uid 맞아야 함).

5. env 관리. 민감값은 env_file로. .env는 git 미포함, .env.sample만 올림.

6. 로그. 운영에서 docker-compose logs로 모든 서비스 로그 통합 조회 가능. 개발 환경에선 -f 로 tail 걸어놓음.

한계는 단일 호스트라는 점. 다음 스텝은 swarm mode 또는 k8s인데 둘 다 운영 경험 없어서 학습 시간 필요.