๊ฐ๊ฐ์ ์์ํ์ฌ ์ค๋นํ ํ์บ์คํธ ํ์ฌ๋ณธ ๋ฒ์ญ
Docker Compose๋ ์์
์ ์์ฑํ๋ ๋๋ผ์ด ๋๊ตฌ์
๋๋ค.
์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฉ๋๋ ์คํ ํ๊ฒฝ์
๋๋ค. ์ด๋ฅผ ํตํด ์ ์ํ ์ ์์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ ๊ตฌ์ฑ ์์๋ ๋ช
ํํ๊ณ ๊ฐ๋จํ ๊ตฌ๋ฌธ์ ๋ฐ๋ฆ
๋๋ค.
ํ์ผ
์ ์ถํ์ผ๋ก
๋ฌด๋ฆฌ
ํ์ง๋ง ์ด๋ ๋์ผํ docker-compose ํ์ผ์ ๋ค์์์ ์ฌ์ฉํ ์ ์๋ค๋ ์๋ฏธ์
๋๊น?
๊ฐ๋ฐ ํ๋ก์ธ์ค์ ํ๋ก๋์
ํ๊ฒฝ์์? ๋๋ ๋์ผํ ํ์ผ์ ์ฌ์ฉํ์ฌ
๊ฐ์? ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ ์ต๋๋ค. ํ์ง๋ง ์ด ๊ธฐ๋ฅ์ ์ํด์๋ ๋ค์์ด ํ์ํฉ๋๋ค.
- ๋ณ์ ๋ณด๊ฐ: ์ผ๋ถ ํ๊ฒฝ ๋ณ์ ์ฌ์ฉ
ํ๊ฒฝ๋ง๋ค ๋ณํํ๋ ๊ฐ์น. - ๊ตฌ์ฑ ์ฌ์ ์: ๋ ๋ฒ์งธ(๋๋ ์์์
๋ ๋ค๋ฅธ ํ์) ๊ด๋ จ ๋ด์ฉ์ ๋ณ๊ฒฝํ๋ docker-compose ํ์ผ
๋จผ์ docker compose๊ฐ ๋ ํ์ผ์ ๋ณํฉํ๋ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค.
๊ฐ๋ฐ ํ์ผ๊ณผ ํ๋ก๋์ ํ์ผ์ ์ฐจ์ด์
๊ฐ๋ฐ ์ค์๋ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ๊ณ ์ถ์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
์ค์๊ฐ. ์ด๋ฅผ ์ํด ์ผ๋ฐ์ ์ผ๋ก ์์ค ์ฝ๋๊ฐ ํฌํจ๋ ๋ณผ๋ฅจ์ด ๋ง์ดํธ๋ฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์
์ ๋ฐํ์์ด ํฌํจ๋ ์ปจํ
์ด๋์
๋๋ค. ํ์ง๋ง ํ๋ก๋์
ํ๊ฒฝ์ ๊ฒฝ์ฐ
์ด ๋ฐฉ๋ฒ์ ์ ํฉํ์ง ์์ต๋๋ค.
ํ๋ก๋์
ํ๊ฒฝ์๋ ๋
ธ๋๊ฐ ๋ง์ ํด๋ฌ์คํฐ๊ฐ ์๊ณ ๋ณผ๋ฅจ์ ๋ก์ปฌ์
๋๋ค.
์ปจํ
์ด๋(๋๋ ์๋น์ค)๊ฐ ์คํ ์ค์ธ ๋
ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ฏ๋ก
๋ค์์ ํฌํจํ ๋ณต์กํ ์์
์์ด ์์ค ์ฝ๋๋ฅผ ๋ง์ดํธํ ์ ์์ต๋๋ค.
์ฝ๋ ๋๊ธฐํ, ์ ํธ ๋ฑ
๋์ , ์ฐ๋ฆฌ๋ ์ผ๋ฐ์ ์ผ๋ก ํน์ ๋ฒ์ ์ ์ฝ๋๋ก ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ ค๊ณ ํฉ๋๋ค.
์ ์ ํ ํ๊ทธ๋ก ํ์ํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค(์๋ฏธ ์ฒด๊ณ๋ฅผ ์ฌ์ฉํ ์ ์์).
๋ฒ์ ๊ด๋ฆฌ ๋๋ ๊ทํ์ ์ฌ๋์ ๋ฐ๋ฅธ ๋ค๋ฅธ ์์คํ
).
๊ตฌ์ฑ ์ฌ์ ์
์ฐจ์ด์ ๊ณผ ์๋๋ฆฌ์ค์์ ์ข
์์ฑ์ด ๋ค๋ฅผ ์ ์๋ค๋ ์ ์ ๊ฐ์ํ ๋
๊ฐ๋ฐ ๋ฐ ์์ฐ ๊ณผ์ ์์ ์๋ก ๋ค๋ฅธ ๊ตฌ์ฑ ํ์ผ์ด ํ์ํ๋ค๋ ๊ฒ์ ๋ถ๋ช
ํฉ๋๋ค.
Docker Compose๋ ๋ค์ํ Compose ํ์ผ์ ๋ณํฉํ์ฌ
์ต์ข
๊ตฌ์ฑ์ ์ป์ต๋๋ค. ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์์ ์์ ๋ณผ ์ ์์ต๋๋ค:
$ cat docker-compose.yml
version: "3.2"
services:
whale:
image: docker/whalesay
command: ["cowsay", "hello!"]
$ docker-compose up
Creating network "composeconfigs_default" with the default driver
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ________
whale_1 | < hello! >
whale_1 | --------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0
๋งํ๋ฏ์ด docker compose๋ ์ฌ๋ฌ compose ๊ฒฐํฉ์ ์ง์ํฉ๋๋ค.
ํ์ผ์ ์ฌ์ฉํ๋ฉด ๋ ๋ฒ์งธ ํ์ผ์ ๋ค์ํ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด:
$ cat docker-compose.second.yml
version: "3.2"
services:
whale:
command: ["cowsay", "bye!"]
$ docker-compose -f docker-compose.yml -f docker-compose.second.yml up
Creating composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ______
whale_1 | < bye! >
whale_1 | ------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0
์ด ๊ตฌ๋ฌธ์ ๊ฐ๋ฐ ์ค์๋ ๊ทธ๋ค์ง ํธ๋ฆฌํ์ง ์์ต๋๋ค.
์ฌ๋ฌ ๋ฒ ํด์ผ ํ ๊ฒ์
๋๋ค.
์ด ์ข๊ฒ๋ docker compose๋ ์๋์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ํน์ ํ์ผ์ ์ฐพ์ต๋๋ค.
docker-compose.override.yml ๊ฐ์ ์ฌ์ ์ํ๋ ค๋ฉด docker-compose.yml. ๋ง์ฝ
๋ ๋ฒ์งธ ํ์ผ์ ์ด๋ฆ์ ๋ฐ๊พธ๋ฉด ์๋ ๋ช
๋ น๋ง ์ฌ์ฉํ์ฌ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ______
whale_1 | < bye! >
whale_1 | ------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0
์ข์์, ๊ทธ๊ฒ ๊ธฐ์ตํ๊ธฐ ๋ ์ฝ๋ค์.
๋ณ์ ๋ณด๊ฐ
๊ตฌ์ฑ ํ์ผ ์ง์
๋ณ์
services:
my-service:
build:
context: .
image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
...
๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ๋น์ ์ด ๊ทธ๋ ๊ฒ ํ๋ค๋ฉด docker-compose ๋น๋(๋๋ ํธ์) ํ๊ฒฝ๋ณ์ ์์ด
$MY_SERVICE_VERSION, ๊ฐ์ด ์ฌ์ฉ๋ฉ๋๋ค ์ต๊ทผํ์ง๋ง ์ค์ ํ๋ฉด
๋น๋ ์ ํ๊ฒฝ ๋ณ์์ ๊ฐ์ ๋น๋ํ๊ฑฐ๋ ํธ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฑ๋ก๋ถ์ ๊ฐ์ธ.๋ ์ง์คํธ๋ฆฌ.๊ด์ฐ.
๋์ ์์น
๋์๊ฒ ํจ๊ณผ๊ฐ ์๋ ์ ๊ทผ ๋ฐฉ์์ด ๋น์ ์๊ฒ๋ ํจ๊ณผ๊ฐ ์์ ์ ์์ต๋๋ค. ๋๋ ์ด๊ฒ์ ๋ฐ๋ฅธ๋ค
๊ฐ๋จํ ๊ท์น:
- ํ๋ก๋์
, ๊ฐ๋ฐ(๋๋ ๊ธฐํ ํ๊ฒฝ)์ ์ํ ๋ชจ๋ ์คํ์ ๋ค์์ ํตํด ์ ์๋ฉ๋๋ค.
๋์ปค ์์ฑ ํ์ผ - ๊ฐ๋ฅํ ํ ๋ชจ๋ ํ๊ฒฝ์ ํฌ๊ดํ๋ ๋ฐ ํ์ํ ๊ตฌ์ฑ ํ์ผ
์ค๋ณต์ ํผํ์ธ์. - ๊ฐ ํ๊ฒฝ์์ ์์ ํ๋ ค๋ฉด ํ๋์ ๊ฐ๋จํ ๋ช ๋ น์ด ํ์ํฉ๋๋ค.
- ๊ธฐ๋ณธ ๊ตฌ์ฑ์ ํ์ผ์ ์ ์๋์ด ์์ต๋๋ค. docker-compose.yml.
- ํ๊ฒฝ ๋ณ์๋ ์ด๋ฏธ์ง ํ๊ทธ ๋๋ ๊ธฐํ๋ฅผ ์ ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
ํ๊ฒฝ๋ง๋ค ๋ค๋ฅผ ์ ์๋ ๋ณ์(์คํ ์ด์ง, ํตํฉ,
์์ฐ). - ์์ฐ ๋ณ์์ ๊ฐ์ ๋ค์์ ๊ฐ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ ์คํ์ด ํ๋ก๋์ ํ๊ฒฝ์์ ์์๋ ๋ ์ํ์ ์ต์ํํฉ๋๋ค.
ํ๊ฒฝ๋ณ์๋ฅผ ์ค์ ํฉ๋๋ค. - ํ๋ก๋์ ํ๊ฒฝ์์ ์๋น์ค๋ฅผ ์์ํ๋ ค๋ฉด ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ์ญ์์ค. ๋์ปค ์คํ ๋ฐฐํฌ - ์์ฑ ํ์ผ docker-compose.yml -registry-auth my-stack-name.
- ์์ ํ๊ฒฝ์ ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ์์๋ฉ๋๋ค. ๋์ปค - ์๋ก ๊ตฌ์ฑ dd.
๊ฐ๋จํ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
# docker-compose.yml
...
services:
my-service:
build:
context: .
image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
environment:
API_ENDPOINT: ${API_ENDPOINT:-https://production.my-api.com}
...
ะ
# docker-compose.override.yml
...
services:
my-service:
ports: # This is needed for development!
- 80:80
environment:
API_ENDPOINT: https://devel.my-api.com
volumes:
- ./:/project/src
...
๋๋ ์ฌ์ฉํ ์ ์๋ค docker-compose (๋์ปค-์์ฑ)์คํ์ ์คํํ๋ ค๋ฉด
์์ค ์ฝ๋๊ฐ ๋ง์ดํธ๋ ๊ฐ๋ฐ ๋ชจ๋ /ํ๋ก์ ํธ/src.
ํ๋ก๋์
์์๋ ๋์ผํ ํ์ผ์ ์ฌ์ฉํ ์ ์์ต๋๋ค! ๊ทธ๋ฆฌ๊ณ ๋๋ ํ์คํ ์ฌ์ฉํ ์ ์์ต๋๋ค
๊ฐ์ ํ์ผ docker-compose.yml ๋ฌด๋๋ฅผ ์ํด. ์ด๋ฅผ ํ์ฅํ๋ ค๋ฉด
ํ๋ก๋์
์์๋ ์ฌ์ ์ ์๋ ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ๊ณ ์ ์กํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
CI ๋จ๊ณ์์:
export MY_SERVICE_VERSION=1.2.3
docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml push
ํ๋ก๋์ ์์๋ ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ์คํํ ์ ์์ต๋๋ค.
export MY_SERVICE_VERSION=1.2.3
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth
๋ฌด๋์์๋ ๋์ผํ ์์
์ ์ํํ๋ ค๋ฉด ๋ค์์ ์ ์ํ๋ฉด ๋ฉ๋๋ค.
์คํ
์ด์ง ํ๊ฒฝ์์ ์์
ํ๋ ๋ฐ ํ์ํ ํ๊ฒฝ ๋ณ์:
export MY_SERVICE_VERSION=1.2.3
export API_ENDPOINT=http://staging.my-api.com
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth
๊ฒฐ๊ณผ์ ์ผ๋ก ์ฐ๋ฆฌ๋ ๋ ๊ฐ์ ์๋ก ๋ค๋ฅธ docker-compose ํ์ผ์ ์ฌ์ฉํ์ต๋๋ค.
๊ทํ์ ๋ชจ๋ ํ๊ฒฝ์ ์ค๋ณต ๊ตฌ์ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค!
๊ณผ์ ์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ
์ถ์ฒ : habr.com