[Docker] docker-compose 작성 및 실행

rekv·2025년 3월 18일

Docker

목록 보기
4/12

Docker-compose란?

시스템 구축과 관련된 명령어를 하나의 텍스트 파일(정의 파일)에 기재해 명령어 한 번에 전체를 실행하고 종료와 폐기까지 한 번에 하도록 도와주는 도구

예를 들어 하나의 서버가 돌아가기 위해서는 프론트엔드, 백엔드, DB 서버 이 세 가지가 작동해야 하는데, 이걸 일일이 명령어를 이용해서 실행하면 무척이나 번거롭다. 게다가 DB가 master-slave 등으로 구성되어야 할 경우 그 복잡도는 더 커진다.
도커 컴포즈는 이러한 번거로움을 yaml파일을 통해 한 번에 할 수 있도록 한다.

docker-compose.yaml

문법

version: "3"

services:
  [컨테이너 이름]:
    image: [이미지 이름]:[버전]
    ports:
      - [Host Port]:[Container Port]
    volumes:
      - .[Host path]:[Container path]
    environment:
      - [Key]=[Value]
    command: ["명령어", "띄어쓰기는", "쉼표와", "따옴표"]
   	depends_on:
      - [먼저 실행될 컨테이너]

이미지 이름을 제외하면 나머지 속성은 전부 선택사항(꼭 전부 넣을 필요는 없다.)

코드

version: "3"

services:
  frontend:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./frotend/dist:/usr/share/nginx/html
      - ./frotend/nginx/default.conf:/etc/nginx/conf.d/default.conf
    environment:
      - ABC=qwer

  backend:
    image: openjdk:17-ea-slim-buster
    ports:
      - 8081:8080
    volumes:
      - ./backend/build/libs/[빌드 파일].jar:/app.jar"
    command: ["java", "-jar", "/app.jar"]

  db:
    image: mariadb:latest
    ports:
      - 3306:3306
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MARIADB_ROOT_PASSWORD=qwer1234
      - MARIADB_DATABASE=test

⚡여기서 volumes의 경로는 절대경로보다는 상대경로를 적는 걸 추천⚡

실행 버튼을 하나씩 눌러도 되지만 services를 누르면 세 개가 동시에 실행된다.

결과

하나의 service 안에서 3개의 컨테이너가 동시에 돌아가는 걸 확인할 수 있다.

MariaDB의 이미지 초기화 동작

여기서 잠깐 짚고 넘어가자면, docker desktop에서 mariaDB를 실행할 때 MARIADB_ROOT_PASSWORD를 지정해야만 정상적으로 작동이 되었다. 그러므로 docker-compose에서는 environment에 넣으면 되는데, MARIADB_DATABASE를 설정하면 database도 자동으로 생성되는 걸 확인할 수 있다.
이는 MariaDB 이미지 설명 페이지에서도 확인할 수 있는데,

if [ "$MARIADB_USER" -a "$MARIADB_PASSWORD" ]; then
    CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$MARIADB_PASSWORD';
    GRANT ALL PRIVILEGES ON `$MARIADB_DATABASE`.* TO '$MARIADB_USER'@'%';

➡️ 처음 실행될 때 database와 user가 환경변수로 설정되어있으면 유저에게 해당 데이터베이스에 접근하는 권한까지 알아서 준다.

✅ 동작 순서 (컨테이너 첫 기동 시)
1. docker-compose up → db 서비스 시작
2. /var/lib/mysql 폴더가 비어 있을 경우에만
3. 다음 환경 변수를 읽고 초기 설정 실행

  • MARIADB_DATABASE=web
  • MARIADB_USER=webuser
  • MARIADB_PASSWORD=webpass123
  1. webuser 계정을 생성하고, web 데이터베이스에 권한을 부여
  2. 이후 backend가 webuser로 접속 요청 → OK!

❗ 중요한 조건! (초기화는 한 번만 동작)
• /var/lib/mysql 디렉토리가 비어 있을 때만 초기화 동작이 실행된다.
• 이미 데이터가 존재하는 경우(./db 볼륨이 남아 있는 경우),
다시 초기화 스크립트가 실행되지 않는다.
-> 그러므로 이미 만들어진 컨테이너에 환경변수를 추가했다면 설정 또한 따로 해주어야 한다.

만약 DB 초기 데이터 삽입이나 SQL 스크립트 자동 실행이 필요하다면 docker-entrypoint-initdb.d 폴더에 넣으면 된다.

docker-compose를 이용한 HAProxy 실습

HAProxy에 관한 사용법은 여기(클릭)에 정리되어 있다.

이전의 실습 내용을 보면 haproxy를 사용하기 위해서는 haproxy.cfg파일을 수정해야 한다는 걸 알 수 있다.
그러므로 적당한 위치에 haproxy.cfg 파일을 생성하고 기존의 코드와 위에서 확인한 설정을 참고하여 아래의 코드를 작성한다.

haproxy.cfg

listen stats
  bind *:9000
  stats enable
  stats uri /stats
  stats realm Haproxy\ Statistics
  
frontend webserver
  bind *:80
  mode http
  default_backend nginx-server
  
backend nginx-server
  mode http
  balance roundrobin 
  option httpchk GET /
  server nginx1 localhost:81 check
  server nginx2 localhost:82 check
  

여기서 주의할 점이, 마지막에 엔터가 들어가야 haproxy docker가 제대로 작동한다.

dockeor-compose.yaml

version: "3"

services:
  haproxy:
    image: haproxy:latest
    container_name: haproxy
    ports:
      - "80:80"       # 외부에서 접근할 포트
      - "9000:9000"   # HAProxy stats 페이지
    volumes:
      - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
    depends_on:
      - nginx1
      - nginx2

  nginx1:
    image: nginx:latest
    container_name: frontend1
    ports:
      - "81:80"  # 내부에서 81 포트로 노출 -> HAProxy가 여기를 체크
    volumes:
      - ./frontend/dist:/usr/share/nginx/html
      - ./frontend/nginx/default.conf:/etc/nginx/conf.d/default.conf

  nginx2:
    image: nginx:latest
    container_name: frontend2
    ports:
      - "82:80"  # 내부에서 82 포트로 노출 -> HAProxy가 여기를 체크
    volumes:
      - ./frontend/dist:/usr/share/nginx/html
      - ./frontend/nginx/default.conf:/etc/nginx/conf.d/default.conf

결과

시간이 지난 후 컨테이너를 끄고 캡쳐해서 동작 버튼은 불이 꺼졌지만 아무튼 컨테이너가 정상적으로 생성되어 작동되었다.

0개의 댓글