Docker Compose๋?
Docker Compose๋ ๋จ์ผ ์๋ฒ์์ ์ฌ๋ฌ๊ฐ์ ์ปจํ
์ด๋๋ฅผ ํ๋์ ์๋น์ค๋ก ์ ์ํด ์ปจํ
์ด๋์ ๋ฌถ์์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ ์์
ํ๊ฒฝ์ ์ ๊ณตํ๋ ๊ด๋ฆฌ ๋๊ตฌ์ด๋ค.
Docker Compose์์๋ compose ํ์ผ์ ์ค๋นํด์ ์ปค๋งจ๋๋ฅผ 1ํ ์คํํ๋ ๊ฒ์ผ๋ก ๊ทธ ํ์ผ๋ก๋ถํฐ ์ค์ ์ ์ฝ์ด๋ค์ฌ ๋ชจ๋ ์ปจํ
์ด๋ ์๋น์ค๋ฅผ ์คํ์ํค๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
Docker Compose๋ฅผ ์ฌ์ฉํ๋ ์ด์
์ฌ๋ฌ ๊ฐ์ ์ปจํ
์ด๋๊ฐ ํ๋์ ์ดํ๋ฆฌ์ผ์ด์
์ผ๋ก ๋์ํ ๋ย Docker Compose๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด, ์ด๋ฅผ ํ
์คํธ ํ๊ธฐ ์ํด ๊ฐ ์ปจํ
์ด๋๋ฅผ ํ๋์ฉ ์์ฑํด์ผ ํ๋ค.
์๋ฅผ ๋ค๋ฉด, ์น ์ดํ๋ฆฌ์ผ์ด์
์ ํ
์คํธํ๋ ค๋ฉด ์น ์๋ฒ ์ปจํ
์ด๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปจํ
์ด๋ ๋ ๊ฐ์ ์ปจํ
์ด๋๋ฅผ ๊ฐ๊ฐ ์์ฑํด์ผ ํ๋ค.
$ docker run --name wordpress_db -d mysql:8
$ docker run -d -p 8080:80 \
--link wordpress_db:mysql --name seunghwan_wordpress \
wordpress:latest
Shell
๋ณต์ฌ
์์ ์์ ๋ฅผ ์คํํ๋ฉด wordpress์ mysql ์ปจํ
์ด๋๋ฅผ ์์ฑํ๋ค.
์ด์ฒ๋ผ ์ฌ๋ฌ ๊ฐ์ ์ปจํ
์ด๋๋ก ๊ตฌ์ฑ๋ ์ดํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๊ธฐ ์ํด run ๋ช
๋ น์ด๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฌ์ฉํ ์ ์์ง๋ง ๊ฐ ์ปจํ
์ด๋๊ฐ ์ ๋๋ก ๋์ํ๋์ง ํ์ธํ๋ ํ
์คํธ ๋จ๊ณ์์๋ ์ด๋ฐ์์ผ๋ก ์ผ์ผํ ์ฌ๋ฌ๊ฐ์ ์ปจํ
์ด๋๋ฅผ ์คํํ๊ธฐ๋ ๋ฒ๊ฑฐ๋กญ๋ค.
๋งค๋ฒ run ๋ช
๋ น์ด์ ์ต์
์ ์ค์ ํด CLI๋ก ์ปจํ
์ด๋๋ฅผ ์์ฑํ๊ธฐ๋ณด๋ค๋ ์ฌ๋ฌ ๊ฐ์ ์ปจํ
์ด๋๋ฅผ ํ๋์ ์๋น์ค๋ก ์ ๋ฆฌํด ์ปจํ
์ด๋ ๋ฌถ์์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค๋ฉด ์ข ๋ ํธ๋ฆฌํ ๊ฒ์
๋๋ค.
์ด๋ฅผ ์ํด ๋์ปค ์ปดํฌ์ฆ(Docker Compose)๋ ์ปจํ
์ด๋๋ฅผ ์ด์ฉํ ์๋น์ค์ ๊ฐ๋ฐ๊ณผ CI๋ฅผ ์ํด ์ฌ๋ฌ ๊ฐ์ ์ปจํ
์ด๋๋ฅผ ํ๋์ ํ๋ก์ ํธ๋ก์ ๋ค๋ฃฐ ์ ์๋ ์์
ํ๊ฒฝ์ ์ ๊ณตํ๋ค.
Docker Compose์ ๊ตฌ์กฐ
Docker Compose๋ ์์คํ
๊ตฌ์ถ์ ํ์ํ ์ค์ ์ YAML ํฌ๋งท์ผ๋ก ๊ธฐ์ฌํ ์ ์ ํ์ผ์ ์ด์ฉํด ์ ์ฒด ์์คํ
์ ์ผ๊ด ์คํ(run) ๋๋ ์ผ๊ด ์ข
๋ฃ ๋ฐ ์ญ์ (down) ํ ์ ์๋ค.
YAML ํ์ผ์๋ ์ปจํ
์ด๋๋ ๋ณผ๋ฅจ์ โ์ด๋ ํ ์ค์ ์ผ๋ก ๋ง๋ค์งโ์ ๋ํ ํญ๋ชฉ์ด ๊ธฐ์ฌ๋์ด ์๋ค.
up ์ปค๋งจ๋
โข
docker run ์ปค๋งจ๋์ ๋น์ท
โข
์ ์ ํ์ผ์ ๊ธฐ์ฌ๋ ๋ด์ฉ๋๋ก ์ด๋ฏธ์ง๋ฅผ ๋ด๋ ค๋ฐ๊ณ ์ปจํ
์ด๋๋ฅผ ์์ฑ ๋ฐ ์คํ
โข
์ ์ ํ์ผ์๋ ๋คํธ์ํฌ๋ ๋ณผ๋ฅจ์ ๋ํ ์ ์๋ ๊ธฐ์ฌํ ์ ์์ด์ ์ฃผ๋ณ ํ๊ฒฝ์ ํ๊บผ๋ฒ์ ์์ฑํ ์ ์์
down ์ปค๋งจ๋
โข
์ปจํ
์ด๋์ ๋คํธ์ํฌ๋ฅผ ์ ์ง ๋ฐ ์ญ์
โข
๋ณผ๋ฅจ๊ณผ ์ด๋ฏธ์ง๋ ์ญ์
โข
์ปจํ
์ด๋์ ๋คํธ์ํฌ ์ญ์ ์์ด ์ข
๋ฃ๋ง ํ๊ณ ์ถ๋ค๋ฉด stop ์ปค๋งจ๋๋ฅผ ์ฌ์ฉ
์ด์ธ์๋ ๊ฐ ์ปจํ
์ด๋์ ์์กด์ฑ, ๋คํธ์ํฌ, ๋ณผ๋ฅจ ๋ฑ์ ํจ๊ป ์ ์ํ ์ ์๋ค.
YAML
โข
๋ค์์ Container๋ก ์ํํธ์จ์ด๊ฐ ๊ตฌ์ฑ๋๋ ๊ฒฝ์ฐ ์ฌ์ฉํ ์ ์๋ ํด + ํ๊ฒฝ ์ค์ ํ์ผ(yml or yaml)
โฆ
docker-compose.yml๋ก ์ค์
โฆ
์ฌ๊ธฐ์ ๋ค์ํ ํ
์คํธ๋ค๋ ์ํ ๊ฐ๋ฅ
โฆ
๋ค์ํ ๋ฒ์ ์ ๋ง๋๋ ๊ฒ๋ ์ผ๋ฐ์ (dev, test, prod ๋ฑ๋ฑ)
โช
ex) docker-compose.dev.yml
โข
๊ฐ๋ณ Container๋ฅผ ๋ฐ๋ก ๊ด๋ฆฌํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ์์ฐ์ฑ์ด ๋์
โข
์ฌ์ฉ๋ฒ ์์ฒด๋ ๊ฐ๋จ : ์ํํธ์จ์ด๋ฅผ ๊ตฌ์ฑํ๋ ๋ชจ๋ ์ปจํ
์ด๋์๊ฒ ์ ์ฉ๋จ
$ docker-compose build
$ docker-compose up # -> pull + build + run
$ docker-compose pull
$ docker-compose ps
$ docker-compose down
$ docker-compose start
$ docker-compose stop
$ docker-compose rm
Shell
๋ณต์ฌ
docker-compose.yml ์์ฑ ๋ฐ ํ์ฉ
Wordpress ์ฌ์ดํธ
์๋ํ๋ ์ค๋ ์น ์ฌ์ดํธ๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ํํธ์จ์ด๋ก, ์๋ฒ์ ์ค์นํด์ ์ฌ์ฉํ๋ค.
์๋ํ๋ ์ค ์ปจํ
์ด๋์ MySQL ์ปจํ
์ด๋๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์๋ํ๋ ์ค๋ ๊ฐ๋จํ ๋งํด ๋ธ๋ก๊ทธ ์์ฑ ๋๊ตฌ์ ๊ฐ์ ๊ฒ์ผ๋ก, ์น ์ฌ์ดํธ ์์ฑ์๊ฐ ์์ฑํ ๋ด์ฉ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๊ณ , ์น ์ฌ์ดํธ ์ด๋์์ ์์ฒญ์ ๋ฐ๋ผ ์น ํ์ด์ง๋ฅผ ๋ณด์ฌ์ค๋ค. ์ฆ, ํ๋ก๊ทธ๋จ์ด MySQL์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ธ ์ ์์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ ์ปจํ
์ด๋๊ฐ ์ฐ๊ฒฐ๋์ด ์์ด์ผ ํ๋ค.
MySQL, Wordpress ์ปจํ ์ด๋ ์์ฑ ์ ํ์ํ ์ต์ ๊ณผ ์ธ์
โข
MySQL
docker run --name ์ปจํ
์ด๋_์ด๋ฆ -dit --net=๋คํธ์ํฌ_์ด๋ฆ -e MYSQL_ROOT_PASSWORD=MySQL_๋ฃจํธ_ํจ์ค์๋ -e MYSQL_DATABASE=๋ฐ์ดํฐ๋ฒ ์ด์ค_์ด๋ฆ -e MYSQL_USER=MySQL_์ฌ์ฉ์์ด๋ฆ -e MYSQL_PASSWORD=MySQL_ํจ์ค์๋ mysql --character-set-server=๋ฌธ์_์ธ์ฝ๋ฉ --collation-server=์ ๋ ฌ_์์ --default-authentication-plugin=์ธ์ฆ_๋ฐฉ์
Shell
๋ณต์ฌ
โข
Wordpress
docker run --name ์ปจํ
์ด๋_์ด๋ฆ -dit --net=๋คํธ์ํฌ_์ด๋ฆ -p ํฌํธ_์ค์ -e WORDPRESS_DB_HOST=๋ฐ์ดํฐ๋ฒ ์ด์ค_์ปจํ
์ด๋_์ด๋ฆ -e WORDPRESS_DB_NAME=๋ฐ์ดํฐ๋ฒ ์ด์ค_์ด๋ฆ -e WORDPRESS_DB_USER=๋ฐ์ดํฐ๋ฒ ์ด์ค_์ฌ์ฉ์์ด๋ฆ -e WORDPRESS_DB_PASSWORD=๋ฐ์ดํฐ๋ฒ ์ด์ค_ํจ์ค์๋ wordpress
Shell
๋ณต์ฌ
docker run ๋ช ๋ น์ด๋ก ์ปจํ ์ด๋ ์์ฑ
docker run -d --name wordpress_db \
--network geonoo_network \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=y3787 \
-e MYSQL_DATABASE=y3787 \
-e MYSQL_USER=y3787 \
-e MYSQL_PASSWORD=y3787 \
-v mysql:/var/lib/mysql \
--restart unless-stopped \
mysql:8
Shell
๋ณต์ฌ
docker run -d --name geonoo_wordpress \
--network geonoo_network \
-p 8080:80 \
--link wordpress_db:mysql \
-e WORDPRESS_DB_HOST=db:3306 \
-e WORDPRESS_DB_NAME=y3787 \
-e WORDPRESS_DB_USER=y3787 \
-e WORDPRESS_DB_PASSWORD=y3787 \
--restart unless-stopped \
wordpress:latest
Shell
๋ณต์ฌ
yaml ํ์ผ๋ก ๋ณ๊ฒฝ
version: '3.9'
services:
db:
image: mysql:8
volumes:
- db:/var/lib/mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=seosh817
- MYSQL_DATABASE=seosh817
- MYSQL_USER=seosh817
- MYSQL_PASSWORD=seosh817
networks:
- wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: unless-stopped
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: seosh817
WORDPRESS_DB_PASSWORD: seosh817
WORDPRESS_DB_NAME: seosh817
networks:
- wordpress
volumes:
db: {}
networks:
wordpress: {}
YAML
๋ณต์ฌ
์์ docker-compose.yml ํ์ผ์ ๋ณด๋ฉด ์๋น์ค๋ก db, wordpress ๋๊ฐ๊ฐ ์กด์ฌํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ณผ๋ฅจ์ผ๋ก db, ๋คํธ์ํฌ๋ก wordpress๋ฅผ ์์ฑํ๊ณ ์๋น์ค์์ ํด๋น ๋ณผ๋ฅจ๊ณผ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ๋ ๊ตฌ์กฐ๋ก ๋์ด์๋ค.
์ด๋ ํ ์ค์ ๋ ํ์ง ์์ผ๋ฉด ๋์ปค ์ปดํฌ์ฆ๋ ํ์ฌ ๋๋ ํ ๋ฆฌ์ docker-compose.yml ํ์ผ์ ์ฝ์ด ๋ก์ปฌ์ ๋์ปค ์์ง์๊ฒ ์ปจํ
์ด๋ ์์ฑ์ ์์ฒญํ๋ค. docker compse up ๋ช
๋ น์ด๋ก ๋์ปค ์ปดํฌ์ฆ ํ๋ก์ ํธ๋ฅผ ์คํํ ์ ์๋ค.
docker-compose up -d
YAML
๋ณต์ฌ
์ปดํฌ์ฆ ํ์ผ(YAML ํ์)์ ์์ฑ ์๋ น
- ์ฒซ ์ค์ ๋์ปค ์ปดํฌ์ฆ ๋ฒ์ ์ ๊ธฐ์ฌ
- ์ฃผ ํญ๋ชฉ services, networks, volumes ์๋์ ์ค์ ๋ด์ฉ์ ๊ธฐ์ฌ
- ํญ๋ชฉ ๊ฐ์ ์ํ ๊ด๊ณ๋ ๊ณต๋ฐฑ์ ์ฌ์ฉํ ๋ค์ฌ์ฐ๊ธฐ๋ก ๋ํ๋ธ๋ค.
- ๋ค์ฌ์ฐ๊ธฐ๋ ๊ฐ์ ์์ ๋ฐฐ์๋งํผ์ ๊ณต๋ฐฑ์ ์ฌ์ฉํ๋ค.
- ์ด๋ฆ์ ์ฃผ ํญ๋ชฉ ์๋์ ๋ค์ฌ์ฐ๊ธฐํ ๋ค์ ๊ธฐ์ฌํ๋ค.
- ์ปจํ
์ด๋ ์ค์ ๋ด์ฉ์ ์ด๋ฆ ์๋์ ๋ค์ฌ์ฐ๊ธฐํ ๋ค์ ๊ธฐ์ฌํ๋ค.
- ์ฌ๋ฌ ํญ๋ชฉ์ ๊ธฐ์ฌํ๋ ค๋ฉด ์ค ์์ โ-โ์ ๋ถ์ธ๋ค.
- ์ด๋ฆ ๋ค์๋ ์ฝ๋ก (:)์ ๋ถ์ธ๋ค.
- ์ฝ๋ก ๋ค์๋ ๋ฐ๋์ ๊ณต๋ฐฑ์ด ์์ผ ํ๋ค.(๋ฐ๋ก ์ค๋ฐ๊ฟํ๋ ๊ฒฝ์ฐ๋ ์์ธ)
- # ๋ค์ ๋ด์ฉ์ ์ฃผ์์ผ๋ก ๊ฐ์ฃผ๋๋ค.
- ๋ฌธ์์ด์ ์์๋ฐ์ดํ(โ) ๋๋ ํฐ๋ฐ์ดํ(โ)๋ก ๊ฐ์ธ ์์ฑํ๋ค.
์ปดํฌ์ฆ ํ์ผ์ ํญ๋ชฉ
โข
์ฃผ ํญ๋ชฉ
ํญ๋ชฉ | ๋ด์ฉ |
services | ์ปจํ
์ด๋๋ฅผ ์ ์ํ๋ค. |
networks | ๋คํธ์ํฌ๋ฅผ ์ ์ํ๋ค. |
volumes | ๋ณผ๋ฅจ์ ์ ์ํ๋ค. |
โข
์์ฃผ ๋์ค๋ ์ ์ ๋ด์ฉ
ํญ๋ชฉ | docker run ์ปค๋งจ๋์ ํด๋น ์ต์
๋๋ ์ธ์ | ๋ด์ฉ |
images | ์ด๋ฏธ์ง ์ธ์ | ์ฌ์ฉํ ์ด๋ฏธ์ง๋ฅผ ์ง์ |
networks | โnet | ์ ์ํ ๋คํธ์ํฌ๋ฅผ ์ง์ |
volumes | -v, โmount | ์คํ ๋ฆฌ์ง ๋ง์ดํธ๋ฅผ ์ค์ |
ports | -p | ํฌํธ ์ค์ |
environment | -e | ํ๊ฒฝ๋ณ์ ์ค์ |
depends_on | ์์ | ๋ค๋ฅธ ์๋น์ค์ ๋ํ ์์กด๊ด๊ณ๋ฅผ ์ ์ |
restart | ์์ | ์ปจํ
์ด๋ ์ข
๋ฃ ์ ์ฌ์์ ์ฌ๋ถ๋ฅผ ์ค์ |
example-voting-app
Docker์์ ๊ณต์์ ์ผ๋ก ์ ๊ณตํ๋ ์์ ์ํ
โข
์ํคํ
์ฒ ์ค๋ช
โฆ
๋ ์ต์
์ฌ์ด์์ ํฌํํ ์ ์๋๋ก ํ๋ Python ํ๋ก ํธ์๋ ์น ์ฑ
โฆ
์๋ก์ด ํฌํ๋ฅผ ์์งํ๋ย Redis
โฆ
โฆ
โฆ
git clone https://github.com/Y-gw/example-voting-app.git
๋จผ์ ๊ธฐ์กด ๋ฐฉ์๋๋ก ๋งค๋ด์ผํ๊ฒ ํ๋์ฉ ๋น๋ํด๋ณด์.
โข
์ด๋ฏธ์ง ๋น๋
$ docker build -t vote ./vote
$ docker build -t result ./result
$ docker build -t worker ./worker
Shell
๋ณต์ฌ
โข
์ปจํ
์ด๋ ์คํ
# detached ๋ชจ๋๋ก ์์ ์ปจํ
์ด๋๋ค์ ์คํ
$ docker run -d --name=redis redis
$ docker run -d -e POSTGRES_PASSWORD=postgres --name=db postgres
$ docker run -d --name=vote -p 5001:80 vote
$ docker run -d --name=result -p 5002:80 result
$ docker run -d --name=worker worker
Shell
๋ณต์ฌ
โข
network ํต์ ํ์ธ
## vote(python app) container๋ก ๋ค์ด๊ฐ์ redis์์ ํต์ ์ ping์ ํตํด ํ์ธ
$ docker exec -it --user root vote sh
$ apt-get update && apt update
$ apt install -y iputils-ping
$ ping redis
>> ping: cannot resolve redis: Unknown host
Shell
๋ณต์ฌ
โข
docker images
โฆ
redis์ postgres๋ ๊ณต์ ์ด๋ฏธ์ง๋ค์ด๋ผ ๋น๋ํ ํ์๊ฐ ์๋ค.
โข
์์ ๊ฐ์ด ์ด๋ ๊ฒ ๋ด๊ฐ ์ผ์ผํ ํ๋์ฉ ์คํํ๋ฉด ๋์ํ ๊น?
โฆ
๊ฐ ์ปดํฌ๋ํธ๋ค ๊ฐ์ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ด ์๋๊ณ ์์!
โฆ
์ปจํ
์ด๋ ๊ฐ ํต์ ์ด ์๋๊ณ ์์์ ping์ ํตํด ํ์ธ ๊ฐ๋ฅํ๋ค
โข
๋คํธ์ํฌ issue ์ธ๋ถ ์ ๋ณด
โฆ
python app์์๋ ์๋์ ๊ฐ์ด redis๋ฅผ ํธ์ถํด์ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์จ๋ค.
โฆ
vote/app.py
def get_redis():
"""
Redis ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์์ด๋ค.
์ด ํจ์๋ Flask์ g ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ Redis ์ธ์คํด์ค๋ฅผ ์ฑ๊ธํค์ผ๋ก ๊ด๋ฆฌํ๋ค.
์ฑ๊ธํค ํจํด์ ์ฌ์ฉํ์ฌ ํ ๋ฒ์ ์์ฒญ์ ๋ํด ๋์ผํ Redis ์ธ์คํด์ค๋ฅผ ๊ณ์ ์ฌ์ฉํ๋ค.
Returns:
Redis: Redis - ํด๋ผ์ด์ธํธ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค.
Raises:
ConnectionError: Redis - ์๋ฒ์ ์ฐ๊ฒฐํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐ์ํ๋ค.
TimeoutError: Redis - ์๋ฒ์์ ์ฐ๊ฒฐ์ด ์๊ฐ ์ด๊ณผ๋๋ ๊ฒฝ์ฐ ๋ฐ์ํ๋ค.
"""
if not hasattr(g, 'redis'):
# g ๊ฐ์ฒด์ Redis ์ธ์คํด์ค๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง Redis ํด๋ผ์ด์ธํธ๋ฅผ ์์ฑํ๋ค.
# host๋ "redis"๋ก ์ค์ ๋์ด ์์ผ๋ฉฐ, db๋ 0์ผ๋ก ์ค์ ๋์ด ์๋ค.
# socket_timeout์ ์ฐ๊ฒฐ ์๋ ์๊ฐ์ 5์ด๋ก ์ค์ ํ๋ค.
g.redis = Redis(host="redis", db=0, socket_timeout=5)
return g.redis
Python
๋ณต์ฌ
โฆ
result/server.js
var pool = new pg.Pool({
connectionString:
'postgres://postgres:postgres@db/postgres'
});
JavaScript
๋ณต์ฌ
postgres ์ฐ๊ฒฐ์ postgres:postgres๋ฅผ ์ฌ์ฉํ๊ณ ์์์ ์ฃผ์๊น๊ฒ ๋ณผ ๊ฒ!
@ ๋ค์์ ์ค๋ ์ด๋ฆ์ ์ปจํ
์ด๋ ์ด๋ฆ
โ Docker Compose ํ์ผ์์ db๋ผ๋ ์ด๋ฆ์ผ๋ก PostgreSQL ์ปจํ
์ด๋๋ฅผ ์ ์
โฆ
worker/Program.cs
var pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;");
var redisConn = OpenRedisConnection("redis");
C#
๋ณต์ฌ
worker์์๋ postgresql๊ณผ redis๋ฅผ ๋์์ ํต์
์ด ๋ถ๋ถ์์ ์๋ก์ ์กด์ฌ๋ฅผ ๋ชฐ๋ผ ์๋ฌ๊ฐ ๋ฐ์ โ ํต์ X
๋คํธ์ํฌ issue ํด๊ฒฐ๋ฐฉ๋ฒ
โข
docker์ network ๊ธฐ๋ฅ ์ฌ์ฉ
โฆ
์ ์๋ docker run์ link ์ต์
์ ์ฌ์ฉ
โข
network๋ฅผ ํ๋ ๋ง๋ค๊ณ ๋ชจ๋ ์ปจํ
์ด๋๋ค์ ์ด ๋คํธ์ํฌ ์์ผ๋ก ์ง์
โฆ
์ฐ๊ฒฐ ์ํฉ์ ๋ฐ๋ผ ๋ณ๊ฐ์ ๋คํธ์ํฌ๋ฅผ ๋ง๋ค๊ณ ์ฌ์ฉ๋ ๊ฐ๋ฅํจ
โช
์๋์์๋ 2๊ฐ์ง ๋คํธ์ํฌ๋ฅผ ํตํด ์ปจํ
์ด๋๋ค ๊ฐ ํต์ ๊ทธ๋ฃน์ ๋ง๋ค ์์
โช
back-tier
โช
front-tier
โฆ
๋งค๋ด์ผ ์์ ์์๋ mynetwork ๋ผ๋ ๋คํธ์ํฌ๋ฅผ ํ๋ ๋ง๋ค๊ณ ์งํ ์์
docker network create
๋ค์ ์ ์ฒด ๊ณผ์ ์ ์คํํด๋ณด์.
โข
์ด๋ฏธ์ง ๋น๋
$ docker build -t vote ./vote
$ docker build -t result ./result
$ docker build -t worker ./worker
Shell
๋ณต์ฌ
โข
์ปจํ
์ด๋ ์ ๋ฆฌ
# ๋ง์ฝ ์ค์ํ ๊ฒ์ด ์๋ค๋ฉด ์๋์ ๊ฐ์ด ์ํ
$ docker container rm -f $(docker container ls -aq)
# ์ค์ํ ์ปจํ
์ด๋๊ฐ ์์ ๊ฒฝ์ฐ
$ docker ps
$ docker stop {์ปจํ
์ด๋ id}
$ docker rm {์ปจํ
์ด๋ id}
Shell
๋ณต์ฌ
โข
๋คํธ์ํฌ ์์ฑ
$ docker network create mynetwork
Shell
๋ณต์ฌ
โข
์ปจํ
์ด๋ ์คํ (--network ํ๊ทธ ์ง์ )
$ docker run -d --name=redis --network mynetwork redis
# password ์ค์ ๊ณผ ํจ๊ป docker run
$ docker run -d --name=db -e POSTGRES_PASSWORD=password --network mynetwork postgres
$ docker run -d --name=vote -p 5001:80 --network mynetwork vote
$ docker run -d --name=result -p 5002:80 --network mynetwork result
$ docker run -d --name=worker --network mynetwork worker
Shell
๋ณต์ฌ
โข
redis์ ํต์ ํ์ธ
$ docker exec -it --user root vote sh
$ apt-get update && apt update && apt install -y iputils-ping
$ apt install -y iputils-ping
$ ping redis
# ping redis -> ์๋์ ๊ฐ์ด ํต์ ์ด ๋๋ ๊ฒ์ ํ์ธ ๊ฐ๋ฅ!
PING redis (172.22.0.2) 56(84) bytes of data.
64 bytes from redis.mynetwork (172.22.0.2): icmp_seq=1 ttl=64 time=0.934 ms
64 bytes from redis.mynetwork (172.22.0.2): icmp_seq=2 ttl=64 time=0.099 ms
64 bytes from redis.mynetwork (172.22.0.2): icmp_seq=3 ttl=64 time=0.135 ms
64 bytes from redis.mynetwork (172.22.0.2): icmp_seq=4 ttl=64 time=0.079 ms
64 bytes from redis.mynetwork (172.22.0.2): icmp_seq=5 ttl=64 time=0.252 ms
64 bytes from redis.mynetwork (172.22.0.2): icmp_seq=6 ttl=64 time=0.235 ms
Shell
๋ณต์ฌ
Docker compose๋ฅผ ํตํ ์คํ
์์ 5๊ฐ์ Container๋ฅผ ์ผ์ผํ ์คํํ์ ๋์ ๋ฌธ์ ์
โข
Postgres๋ฅผ ์คํํ๋ ๋ถ๋ถ์ด ์ ๋๋ก ๋์ํ์ง ์์์
# $ ping db
PING db (192.168.107.3) 56(84) bytes of data.
64 bytes from db.mynetwork (192.168.107.3): icmp_seq=1 ttl=64 time=0.183 ms
64 bytes from db.mynetwork (192.168.107.3): icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from db.mynetwork (192.168.107.3): icmp_seq=3 ttl=64 time=0.055 ms
# ์? ํต์ ์ ๋๋๋ฐ..?
Shell
๋ณต์ฌ
โฆ
์ด๋ Postgres ์ปจํ
์ด๋๋ฅผ ์คํํ ๋ ์ ์ ํ ํ๊ฒฝ ๋ณ์๋ฅผ ์ง์ ํ์ง ์์ ๋ฐ์ํ ๋ฌธ์ .
โฆ
Worker ์ปจํ
์ด๋ ๋ด์์ OpenDbConnection ํจ์๋ฅผ ํธ์ถํ ๋, Postgres ์๋ฒ์์ ์ฐ๊ฒฐ ์ ๋ณด๊ฐ ์๋ชป ์ค์ ๋์๊ธฐ ๋๋ฌธ์ ๋์ํ์ง ์์์.
โฆ
docker run -d --name=db -e POSTGRES_PASSWORD=password --network mynetwork postgres
โฆ
worker/Program.cs
var pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;");
var redisConn = OpenRedisConnection("redis");
C#
๋ณต์ฌ
โข
์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด Container๋ฅผ ์คํํ ๋ ์๋ 2๊ฐ์ ํ๊ฒฝ๋ณ์๋ฅผ ๋๊ฒจ์ฃผ์ด์ผ ํจ
โฆ
POSTGRES_USER: "postgres"
โฆ
POSTGRES_PASSWORD: "postgres"
โ ์ด๊ฑธ docker-compose ํ๊ฒฝ ์ค์ ํ์ผ์ ํตํด ๋๊ธฐ๋ฉด์ ํด๊ฒฐํด๋ณผ ์์
docker-compose.yml๋ก ํฌํ
โข
์์ ์ปจํ
์ด๋๋ฅผ ํ๋์ฉ ์คํํ ๋ ๋คํธ์ํน ๋ถ๋ถ์ ์ ๋๋ก ๋์ํ์ง ์์์.
โข
docker volume์ด๋?
โฆ
Docker volume์ Docker ์ปจํ
์ด๋๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๊ณต์ ํ๊ธฐ ์ํ ๋ฐฉ๋ฒ.
โฆ
์ปจํ
์ด๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋
๋ฆฝ์ ์ธ ํ์ผ ์์คํ
์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ปจํ
์ด๋๊ฐ ์ญ์ ๋๋ฉด ๊ทธ ์์ ๋ฐ์ดํฐ๋ ํจ๊ป ์ญ์ ๋๋ค. ๊ทธ๋ฌ๋ Docker volume์ ์ฌ์ฉํ๋ฉด ์ปจํ
์ด๋์ ๋ฐ์ดํฐ๋ฅผ ํธ์คํธ ๋จธ์ ์ ํ์ผ ์์คํ
์ ์๊ตฌ์ ์ผ๋ก ์ ์ฅํ๊ณ ์ ์งํ ์ ์๋ค.
โข
services ํค ๋ณด๊ธฐ
โข
docker-compose.mac.yml
# v2 and v3 are now combined!
# docker-compose v1.27+ required
# % docker-compose version
# Docker Compose version v2.15.1
services:
vote:
build: ./vote
# use python rather than gunicorn for local dev
command: python app.py
ports:
- "5001:80"
result:
build: ./result
# use nodemon rather than node for local dev
entrypoint: nodemon server.js
ports:
- "5002:80"
worker:
build: ./worker
redis:
image: redis:alpine
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
YAML
๋ณต์ฌ
โข
Demo
## ๋จผ์ ์ฒญ์ ํ ๋ฒ ํ๊ธฐ
$ docker container rm -f $(docker container ls -aq)
# docker image rm -f $(docker image ls -q)
## ํ์ธํด๋ณด๊ธฐ
$ docker ps -a
$ docker images
## ๊ทธ๋ฆฌ๊ณ ๋์ ์์ docker-compose.mac.yml์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์คํํด๋ณด๊ธฐ
$ docker-compose -f docker-compose.mac.yml build
$ docker-compose -f docker-compose.mac.yml up -d
## db ์ปจํ
์ด๋ ์ ์
docker exec -it --user=postgres example-voting-app-db-1 sh
/ $ whoami
postgres
/ $ psql
psql (15.4)
Type "help" for help.
## \c: Connect to database
postgres=# \c
You are now connected to database "postgres" as user "postgres".
## \dt: List tables
postgres=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | votes | table | postgres
(1 row)
postgres=# select * from votes;
id | vote
-----------------+------
cb9d5ad7206be28 | a
(1 row)
exit
$ docker-compose -f docker-compose.mac.yml down
>> โ Container example-voting-app-worker-1 Removed 0.6s
โ Container example-voting-app-db-1 Removed 0.8s
โ Container example-voting-app-vote-1 Removed 1.0s
โ Container example-voting-app-result-1 Removed 0.7s
โ Container example-voting-app-redis-1 Removed 0.9s
โ Network example-voting-app_default Removed
Shell
๋ณต์ฌ
๋คํธ์ํฌ ์ ์๋ฅผ ํตํ docker-compose ๊ฐ์
โข
๋ชจ๋ ๋คํธ์ํฌ๋ฅผ ๋ค ํต์ผ ์ํค๋ ๊ฒ์ ๋ฐ๋์ง ํ์ง ์๋ค.
โฆ
๋คํธ์ํฌ๋ฅผ ๋
ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌ์์ผ์ฃผ๋ ๊ฒ์ด ์ ํ๋ฆฌ์ผ์ด์
์ ๋ณด์์ฑ, ํ์ฅ์ฑ, ์ ์ฐ์ฑ ๋ฐ ์๋น์ค ๋ถ๋ฆฌ ์ธก๋ฉด์์ ๋ ๋ฐ๋์ง
โฆ
์์ : ๋ฐฑ์๋ ๋ด ์ ๋ก์ง, ๋ฐฑ ๋ก์ง
โข
docker-compose.yml๋ก ํฌํ
: networks ์ ์
โฆ
front tier : ์ฌ์ฉ์์๊ฒ ๋
ธ์ถ
โฆ
back tier : ์ฌ์ฉ์์๊ฒ ๋
ธ์ถX
โฆ
์ด๋ฅผ ํตํ network isolation. ํน์๋ผ๋ ์๊ธธ ์ ์๋ ๋ฌธ์ ์ฐจ๋จ
1.
๊ฒฉ๋ฆฌ(Isolation): ๊ฐ ์๋น์ค๋ฅผ ๋คํธ์ํฌ๋ก ๋ถ๋ฆฌํจ์ผ๋ก์จ, ์๋ก ๋ค๋ฅธ ์๋น์ค ๊ฐ์ ๋คํธ์ํฌ ๊ฒฉ๋ฆฌ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. ์ด๋ ๊ฐ ์๋น์ค์ ๋ณด์์ ๊ฐํํ๊ณ , ํ ์๋น์ค์ ์ฅ์ ๋ ๊ณผ๋ถํ๊ฐ ๋ค๋ฅธ ์๋น์ค์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
2.
์ธ๋ถํ(Segmentation): ๋คํธ์ํฌ๋ฅผ back-tier์ front-tier๋ก ๋ถ๋ฆฌํจ์ผ๋ก์จ, ๋ฐฑ์๋ ์๋น์ค์ ํ๋ก ํธ์๋ ์๋น์ค๋ฅผ ๊ตฌ๋ถํ ์ ์์ต๋๋ค. ๋ฐฑ์๋ ์๋น์ค๋ ๋ด๋ถ ๋คํธ์ํฌ(back-tier)์ ์ํ๊ณ , ํ๋ก ํธ์๋ ์๋น์ค๋ ๋ด๋ถ ๋ฐ ์ธ๋ถ ๋คํธ์ํฌ(front-tier)์ ์ํฉ๋๋ค. ์ด๋ ๋ณด์์ ๊ฐํํ๊ณ , ์ธ๋ถ๋ก๋ถํฐ์ ์ง์ ์ ์ธ ์ก์ธ์ค๋ฅผ ์ ํํ์ฌ ์์ ํ ์๋น์ค ๊ตฌ์ถ์ ๋์ต๋๋ค.
docker-compose.yml๋ก ํฌํ : services๋ค์ ๋คํธ์ํฌ ์ง์
โข
๊ธฐ์กด
services:
redis:
image: redis:alpine
db:
image: postgres:15-alpine
vote:
build: ./vote
ports:
- 5001:80
result:
build: ./result
ports:
- 5002:80
worker:
build: ./worker
YAML
๋ณต์ฌ
โข
๋ณ๊ฒฝ
services:
redis:
โฆ
networks:
- back-tier
db:
โฆ
networks:
- back-tier
vote:
โฆ
networks:
- back-tier
- front-tier
result:
โฆ
networks:
- back-tier
- front-tier
worker:
โฆ
networks:
- back-tier
networks:
back-tier:
front-tier:
YAML
๋ณต์ฌ
docker-compose.yml๋ก ํฌํ : volumes ์ ์
โข
์ด๋ ์ปจํ
์ด๋ ์๋น์ค์ ๋ฐ์ดํฐ๊ฐ ๊ณ์ํด์ ์ ์ฅ๋์ด์ผ ํ๋๊ฐ?
โฆ
PostgreSQL
โข
db์ ๋ด์ฉ์ด persistentํด์ผํจ โ ๋ณผ๋ฅจ ์์ฑ (๋ค์๋ ๋ณผ๋ฅจ)
volumes:
db-data:
YAML
๋ณต์ฌ
โข
docker-compose.yml๋ก ํฌํ
: services๋ค์ ๋ณผ๋ฅจ ์ง์
services:
redis:
db:
vote:
result:
worker:
YAML
๋ณต์ฌ
services:
redis:
# db ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ ์ปจํ
์ด๋ ๋ด๋ถ ๋๋ ํ ๋ฆฌ ์ฅ์์ ๋ค์๋ ๋ณผ๋ฅจ์ ๋งคํ
db:
volumes:
- db-data:/var/lib/postgresql/data
vote:
result:
worker:
volumes:
db-data:
YAML
๋ณต์ฌ
docker-compose.yml๋ก ํฌํ : vote ์๋น์ค ๊ฐ์
โข
depends_on : ์๋น์ค๋ค๊ฐ์ ์์กด์ฑ์ด ์์ ๊ฒฝ์ฐ, ๋จผ์ ์คํ๋์ด์ผ ํ๋ ์๋น์ค๋ค์ ์ฌ๊ธฐ ๊ธฐ์ ํด์ผํ๋ค.
โฆ
๋ ๋์๊ฐ์ ํด๋น ์๋น์ค์ health check๋ ํฌํจํด์ค
โข
healthcheck : ํด๋น ์๋น์ค์ ๊ฑด๊ฐ์ ๋ํ๋ด์ฃผ๋ ์ฒดํฌ๋ฅผ ๊ธฐ์
โข
docker-compose.yml์ command์ entrypoint
โฆ
command: ์ด๋ฏธ์ง Dockerfile์ CMD๋ฅผ ๋ฎ์ด์ฐ๋๋ฐ ์ฌ์ฉ
โฆ
entrypoint: ์ด๋ฏธ์ง Dockerfile์ ENTRYPOINT๋ฅผ ๋ฎ์ด์ฐ๋๋ฐ ์ฌ์ฉ
โข
docker-compose.yml์ healthcheck
โฆ
์ญ์ Dockerfile์์ ๊ธฐ์ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ด๋ฉฐ docker-compose์์ ์๋์ ๊ฐ์ด ๋ฎ์ด์ฐ๊ธฐ ๊ฐ๋ฅ
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
# 0 for success 1 for failure
interval: 1m30s
timeout: 10s # ์คํ ์๊ฐ 10์ด ๋์ด๊ฐ๋ฉด fail
retries: 3
start_period: 40s
Docker
๋ณต์ฌ
โข
docker-compose.yml์ depends_on
โฆ
ํด๋น ์๋น์ค๊ฐ ์คํ๋๊ธฐ ์ํด์ ๋จผ์ ์คํ๋์ด์ผ ํ๋ ์๋น์ค๋ค์ ์ฌ๊ธฐ ๊ธฐ์
โช
short form:
depends_on:
- db
- redis
YAML
๋ณต์ฌ
โช
long form:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
YAML
๋ณต์ฌ
depends_on์ condition์ผ๋ก ๊ฐ๋ฅํ ๊ฐ
โช
service_started:
โข
์ปจํ
์ด๋๊ฐ ์์๋์๋์ง ์ฌ๋ถ
โช
service_healthy:
โข
์์กด์ฑ์ด ๊ฑด๊ฐ ์ํ๋ฅผ ๋ํ๋ด๋ healthcheck์ ๋ฐ๋ผ ์์ ์ ์ "๊ฑด๊ฐ"ํ ์ํ์ธ์ง ํ์ธ.
โข
True or False โ 0 for success 1 for failure
โช
service_completed_successfully:
โข
์์กด์ฑ์ ์ข
์๋ ์๋น์ค๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋๊ธฐ๋ฅผ ๊ธฐ๋ํ๊ณ , ์๋ฃ ํ์ ์ข
์ ์๋น์ค๋ฅผ ์์ํฉ๋๋ค.
โข
์ฒ์ ์ด๊ธฐํํด์ฃผ๋ ์๋น์ค
docker-compose.yml๋ก ํฌํ : db ์๋น์ค ๊ฐ์
โข
์ด ํ๊ฒฝ ๋ณ์๋ฅผ ํตํด Postgres DB ์ค์ ์ด ๋จ. ์ด์ ๋ํด์ ์์ ์ดํด๋ณด์์
โข
host volume๊ณผ named volume์ ์ฌ์ฉํ๊ณ ์์
โฆ
host volume : ์ง์ ํธ์คํธ pc์ ๋๋ ํ ๋ฆฌ ์ฃผ์์ ์ปจํ
์ด๋ ๋ด๋ถ ์ฃผ์๋ฅผ ๋งคํ
โข
docker-compose.yml์ environment
โฆ
ํด๋น ์๋น์ค๊ฐ ์ปจํ
์ด๋ ์์์ ์คํ๋ ๋ ํ๊ฒฝ๋ณ์๋ค์ ์ง์ (Dockerfile์ ENV)
โฆ
2๊ฐ์ง ๋ฌธ๋ฒ์ด ์กด์ฌ
โช
Map ๋ฌธ๋ฒ โ ์์ docker compose file์ ์ด ๊ฒ์ ์ฌ์ฉ
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:
Docker
๋ณต์ฌ
โช
Array ๋ฌธ๋ฒ:
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
Docker
๋ณต์ฌ
docker-compose.yml๋ก ํฌํ : redis ์๋น์ค ๊ฐ์
โข
volume, health check, network ์ค์
docker-compose.yml๋ก ํฌํ : worker ์๋น์ค ๊ฐ์
โข
build ํค์๋ ๋ฐ์ ๋น๋ ๊ด๋ จ ์ ๋ณด๋ฅผ ๋ ๋จ๊ฒจ์ docker compose ์ ๋ณด๋ค์ ๊ธฐ๋ก ๊ฐ๋ฅ
โฆ
๋์ปค ํ์ผ ๋ช
, ๋์ปคํ์ผ ์์นํ ๋๋ ํ ๋ฆฌ
build:
context: ./my_app # ๋์ปคํ์ผ์ด ์์นํ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก
dockerfile: Dockerfile.prod # ๋์ปค ํ์ผ ๋ช
args:
- ENV=production # ๋น๋ ์์ ์ฌ์ฉํ ํ๊ฒฝ ๋ณ์ ์ค์
Docker
๋ณต์ฌ
docker-compose.yml๋ก ํฌํ : result ์๋น์ค ๊ฐ์ (node)
โข
entrypoint : Dockerfile์ entrypoint๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ
์ต์ข Docker-compose.yml ๋ฆฌ๋ทฐ
โข
์ฃผ์ : ๋ค์ ํ๋ฒ Monterey Mac์์ ํฌํธ 5000๋ฒ์ ์ฌ์ฉํ ์ ์๊ธฐ์ vote ์ฑ์ ํฌํธ๋ฒํธ๋ฅผ ์์ ํด์ผํจ (์๋ฌด port๋ฅผ ๋ถ์ฌํ ๊ฒ, 5001, 5002 ์ ์ธ)
โข
vote์ result์ ํฌํธ๋ฒํธ๋ฅผ ๊ฐ๊ฐ 5001๊ณผ 5002๋ก ์์ ํ ๋ฒ์ ์ด ์์ ๋ฒ์
# version is now using "compose spec"
# v2 and v3 are now combined!
# docker-compose v1.27+ required
services:
vote:
build: ./vote
# use python rather than gunicorn for local dev
command: python app.py
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 15s
timeout: 5s
retries: 3
start_period: 10s
volumes:
- ./vote:/app
ports:
- "5000:80"
networks:
- front-tier
- back-tier
result:
build: ./result
# use nodemon rather than node for local dev
entrypoint: nodemon server.js
depends_on:
db:
condition: service_healthy
volumes:
- ./result:/app
ports:
- "5001:80"
- "5858:5858"
networks:
- front-tier
- back-tier
worker:
build:
context: ./worker
depends_on:
redis:
condition: service_healthy
db:
condition: service_healthy
networks:
- back-tier
redis:
image: redis:alpine
volumes:
- "./healthchecks:/healthchecks"
healthcheck:
test: /healthchecks/redis.sh
interval: "5s"
networks:
- back-tier
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
volumes:
- "db-data:/var/lib/postgresql/data"
- "./healthchecks:/healthchecks"
healthcheck:
test: /healthchecks/postgres.sh
interval: "5s"
networks:
- back-tier
# this service runs once to seed the database with votes
# it won't run unless you specify the "seed" profile
# docker compose --profile seed up -d
seed:
build: ./seed-data
profiles: ["seed"]
depends_on:
vote:
condition: service_healthy
networks:
- front-tier
restart: "no"
volumes:
db-data:
networks:
front-tier:
back-tier:
YAML
๋ณต์ฌ
์ฐธ๊ณ ๋ก ์์ docker compose file์ ์๋์ ๊ฐ์ด ์คํ์ด ๋์ง ์๋๋ค. (๊ทธ์ ์ด๋ ๊ฒ ๊ฐ์ ์ด ๋ ์ ์๋ค๋ ์ ์ ์๋ ค์ฃผ๊ณ ์ถ์์ ๋ฟ) โ ์๋์ ์๋ฌ๋ฅผ ํด๊ฒฐํ ์ ์๋ค๋ฉด ๋น์ ์ ์ด๋ฏธ..
example-voting-app-db-1 | 2023-07-25 15:45:47.023 UTC [1] LOG: database system is ready to accept connections
dependency failed to start: container example-voting-app-db-1 is unhealthy
Python
๋ณต์ฌ