- 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
- 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.
Docker Compose 사용하기
docker-compose.yml 파일 작성하기
이제 앞에서 docker run
명령으로 생성해본 컨테이너들을 Docker Compose로 만들어보겠습니다. Docker Compose는 docker-compose.yml
파일에 생성할 컨테이너들을 정의합니다.
먼저 mysql 컨테이너부터 만들어보겠습니다. docker run
명령을 다시 한번 살펴보면 다음과 같은 형태입니다.
$ sudo docker network create example-network
$ sudo docker run -d --name mysql --network example-network -v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=examplepassword \
-e MYSQL_DATABASE=db \
mysql:5.7
다음 내용을 app 디렉터리 아래에 docker-compose.yml
파일로 저장합니다.
version: '3.8'
services:
mysql:
image: mysql:5.7
volumes:
- mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: examplepassword
MYSQL_DATABASE: db
volumes:
mysql-data:
docker-compose.yml
은version
으로 시작합니다. 버전은 시간이 지남에 따라 계속 올라갑니다.services
: 생성하고자하는 컨테이너는services
아래에 나열합니다.mysql
: 컨테이너 이름입니다. 여기서는mysql
로 정했습니다.image
: Docker 이미지 이름과 태그를 지정합니다.volumes
: 데이터 볼륨 매핑입니다. 여기서는mysql-data
볼륨을/var/lib/mysql
에 연결합니다.docker volume create
로 생성한 볼륨을docker run
명령에서-v
옵션으로 사용하는 것과 같습니다.
environment
: 환경 변수 설정입니다.<환경 변수 이름>: <값>
형식으로 나열합니다.docker run
명령의-e
옵션과 같습니다.
volumes
: 데이터 볼륨을 생성합니다.docker volume create
와 같습니다.
다음 명령을 실행하여 MySQL 컨테이너를 생성해보겠습니다(docker compose
명령은 반드시 docker-compose.yml
이 있는 디렉터리에서 실행해야 합니다).
$ sudo docker compose up -d
[+] Running 3/3
⠿ Network app_default Created 0.9s
⠿ Volume "app_mysql-data" Created 0.2s
⠿ Container app-mysql-1 Started 3.7s
app_default라는 네트워크는 자동으로 생성됩니다(app이 앞에 붙는 이유는 현재 디렉터리 이름이 app이라서 그렇습니다).
docker ps
명령으로 컨테이너 목록을 출력해보면 app-mysql-1 컨테이너가 생성된 것을 볼 수 있습니다.
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ce3fc0c7e71 mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp app-mysql-1
docker compose ps
명령을 입력하면 Docker Compose로 생성한 컨테이너의 목록을 보여줍니다.
$ sudo docker compose ps
NAME COMMAND SERVICE STATUS PORTS
app-mysql-1 "docker-entrypoint.s…" mysql running 3306/tcp, 33060/tcp
docker exec
명령과 마찬가지로 Docker Compose에도 docker compose exec
라는 명령이 있습니다. 이 명령을 사용해서 MySQL 데이터베이스에 접근해보겠습니다.
$ sudo docker compose exec -it mysql mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.39 MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql>
프롬프트가 표시되면 다음 SQL 쿼리를 입력하여 Users 테이블을 생성합니다. 그리고 exit를 입력하여 프롬프트에서 빠져나옵니다.
mysql> USE db;
Database changed
mysql> CREATE TABLE Users (id VARCHAR(100) NOT NULL, password VARCHAR(100) NOT NULL, PRIMARY KEY (id));
Query OK, 0 rows affected (0.76 sec)
mysql> exit
Bye
이제 app.js 실행 부분을 추가해보겠습니다. app 컨테이너의 docker run
명령은 다음과 같은 모양입니다.
$ sudo docker run -it --name app -p 8080:8080 -w /app -v ~/app:/app --network example-network \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=examplepassword \
-e MYSQL_DB=db \
node:16-alpine sh -c "npm install && node app.js"
docker-compose.yml
파일을 열고 services
아래에 app
부분을 추가합니다.
version: '3.8'
services:
mysql:
image: mysql:5.7
volumes:
- mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: examplepassword
MYSQL_DATABASE: db
healthcheck:
test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD']
interval: 10s
timeout: 2s
retries: 100
app:
image: node:16-alpine
command: sh -c "npm install && node app.js"
ports:
- 8080:8080
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: examplepassword
MYSQL_DB: db
depends_on:
mysql:
condition: service_healthy
volumes:
mysql-data:
mysql
healthcheck
: MySQL 컨테이너가 생성되면서 MySQL 데이터베이스도 생성하는데 이때 시간이 조금 걸립니다. MySQL 데이터베이스가 생성되지 않은 상태로 app에서 SQL 쿼리를 실행하게 되면 에러가 발생합니다. 따라서 10초 간격으로mysqladmin ping
을 실행하여 MySQL 데이터베이스가 생성되었는지 검사하고, MySQL 데이터베이스가 완전히 생성되었을 때 app 컨테이너를 생성하도록 합니다.
app
: 컨테이너 이름은app
으로 지정했습니다.image
: Node.js를 사용하기 위해node:16-alpine
를 지정했습니다.command
: 컨테이너를 생성했을 때 실행할 명령(command)입니다.docker run
명령에서 가장 마지막에 들어가는 부분을 여기에 넣습니다.ports
: 호스트와 연결할 포트를 지정합니다.docker run
명령의-p
옵션과 같습니다.working_dir
:command
의 명령이 실행될 디렉터리입니다.docker run
명령의-w
옵션과 같습니다.volumes
: 앞의 MySQL과는 달리 호스트의 현재 디렉터리 ./를 /app에 연결합니다.environment
:docker run
명령에 지정했던 것과 동일하게 환경 변수를 나열합니다.depends_on
: 데이터베이스 컨테이너가 생성되지 않은 상태에서 app 컨테이너가 먼저 생성되면 안 됩니다. 따라서depends_on
에mysql
을 설정하여 mysql 컨테이너가 생성된 뒤에 app 컨테이너가 생성되도록 합니다. 특히,condition
에 service_healthy를 지정해서healthcheck
가 정상 상태가 될 때까지 기다립니다. 즉, MySQL 데이터베이스가 완전히 생성될 때까지 기다립니다.
다음 명령을 실행하여 추가된 app 컨테이너도 생성합니다.
$ sudo docker compose up -d
[+] Running 2/2
⠿ Container app-mysql-1 Running 0.0s
⠿ Container app-app-1 Started 3.8s
docker compose ps
명령으로 컨테이너 목록을 확인해봅니다. 다음과 같이 app-app-1 컨테이너가 보이면 정상적으로 생성된 것입니다.
$ sudo docker compose ps
NAME COMMAND SERVICE STATUS PORTS
app-app-1 "docker-entrypoint.s…" app running 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
app-mysql-1 "docker-entrypoint.s…" mysql running 3306/tcp, 33060/tcp
웹 브라우저에서 http://<컨테이너 IP 주소 또는 도메인>:8080으로 접속해봅니다(Docker Desktop에서 실행했다면 http://127.0.0.1:8080입니다).
다음과 같은 데이터가 표시되면 MySQL 데이터베이스에 정상적으로 데이터를 쓰고 읽어온 것입니다.
{"id":"hellouser","password":"examplepassword"}
이번에는 Docker Compose로 만든 컨테이너들을 정지, 재시작, 삭제하는 방법을 알아보겠습니다.
docker compose stop
명령으로 컨테이너들을 정지시킵니다.
$ sudo docker compose stop
[+] Running 2/2
⠿ Container app-app-1 Stopped 3.7s
⠿ Container app-mysql-1 Stopped 4.7s
정지된 컨테이너들을 시작하려면 docker compose start
명령을 사용합니다.
$ sudo docker compose stop
[+] Running 2/2
⠿ Container app-mysql-1 Started 4.0s
⠿ Container app-app-1 Started 3.7s
만약 컨테이너들이 시작된 상태에서 재시작하고 싶다면 docker compose restart
명령을 사용합니다.
$ sudo docker compose stop
[+] Running 2/2
⠿ Container app-app-1 Started 13.8s
⠿ Container app-mysql-1 Started 5.4s
마지막으로 컨테이너들을 모두 삭제할 때는 docker compose down
명령을 사용합니다.
$ sudo docker compose down
[+] Running 3/3
⠿ Container app-app-1 Removed 12.1s
⠿ Container app-mysql-1 Removed 3.2s
⠿ Network app_default Removed 1.1s
만약 데이터베이스 볼륨도 삭제하고 싶다면 docker volume rm
명령을 사용합니다.
$ sudo docker volume ls
DRIVER VOLUME NAME
local app_mysql-data
$ sudo docker volume rm app_mysql-data
저작권 안내
이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.- 블로그, 게시판 등에 퍼가는 것을 금지합니다.
- 비공개 포스트에 퍼가는 것을 금지합니다.
- 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
- 링크 및 SNS 공유는 허용합니다.