====== docker-compose ======
* https://github.com/docker/compose
* https://docs.docker.com/compose/cli-command/
* [[https://www.docker.com/blog/new-docker-compose-v2-and-v1-deprecation/|Docker Compose: What’s New, What’s Changing, What’s Next | Docker]]
* v2 부터 cli plugin 으로 ''docker compose'' 형태로 사용가능해졌다.
[[docker:compose_cli|docker compose cli]]와 다른 것이다.
===== install v2 =====
* https://github.com/docker/compose/releases 에서 운영체제 버전에 맞는 것을 받아서
* ''$HOME/.docker/cli-plugins/docker-compose'' 로 다운로드한다.
* ''chmod +x $HOME/.docker/cli-plugins/docker-compose'' 로 실행 권한을 주면 이제 ''docker compose'' 명령으로 사용가능해진다.
* [[https://www.rockyourcode.com/how-to-install-docker-compose-v2-on-linux-2021/|How to Install Docker Compose v2 on Linux (2021) | rockyourcode]]
* [[:intellij_idea|IntelliJ IDEA]]에서 실행할 경우 **Settings -> Build, Execution, Deployment -> Docker -> Tools**에서 **Use Compose V2** 를 활성화해준다.
===== 네트워크 =====
* ''services'' 의 이름에 밑줄(''_'')이 있을 경우, 동일 docker-compose 내의 다른 컨테이너에서 해당 이름으로 네트워크 접속이 안됐다.
* [[https://docs.docker.com/compose/networking/|Networking in Compose | Docker Documentation]]
===== docker-compose 에서 network 생성 불가시 =====
* 특히 VPN 에 접속한 상태에서 발생하는 것으로 보임.
* [[https://stackoverflow.com/questions/43720339/docker-error-could-not-find-an-available-non-overlapping-ipv4-address-pool-am|python - Docker "ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network" - Stack Overflow]]
* see [[docker:network|Docker Network]]
* 전제: 내가 이미 docker 에 network 를 직접 생성해둔 상태에서 오류 발생
Creating network "xxx_default" with the default driver
ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
* **하지 말 것** : 이 경우 이미 존재하는 network 를 ''docker-compose.yml'' 에 명시해주거나 직접 생성한 뒤 명시해준다.
services:
myservice:
network_mode: bridge
* ''bridge'' 사용시에는 docker container 들 간에 docker container 이름 기반의 lookup이 작동하지 않는다.
* docker-compose user defined bridge 일 때만 이름 기반 lookup이 작동한다.
* 더 좋은 해결책 : IP 대역 충돌이 일어나지 않는 subnet 을 지정한 network 를 생성하고 ''default''로 지정한다. 이 경우 이름 lookup 도 잘 작동한다.
networks:
default:
driver: bridge
ipam:
config:
- subnet: ${MY_SUBNET:-192.168.100.1/24} # 192.168.100.x 대역의 subnet 으로 네트워크 생성
# .env 파일이나 환경 변수로 MY_SUBNET 값을 강제 지정가능함.
# 만약 network 이름이 default 가 아니라면, 각 service 에 네트워크 이름 명시 필요
services:
myservice:
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
ipam:
config:
- subnet: ${MY_SUBNET:-192.168.100.1/24} # 192.168.100.x 대역의 subnet 으로 네트워크 생성
* 이 경우 ''docker-compose.yml'' 에 직접 지정하지 말고, 아래에서 설명하는 다중 파일 기법으로 따로 설정을 빼두고 사용자에 따라 파일을 명시적으로 읽게하는게 좋다.
* [[https://docs.docker.com/compose/networking/|Networking in Compose | Docker Documentation]]
===== .env =====
* [[https://docs.docker.com/compose/env-file/|Declare default environment variables in file | Docker Documentation]]
* [[https://docs.docker.com/compose/environment-variables/|Environment variables in Compose | Docker Documentation]]
* 환경 변수를 지정할 수 있다.
* ''.env'' 파일을 만들어서 ''KEY=VALUE'' 형태로 추가해주면 ''docker-compose'' 실행시 적용된다.
* 원하는 환경변수 파일을 명시적으로 적용하려면 ''%%--env-file=파일명%%'' 옵션을 준다.
* 특정 환경 변수만 변경하고자 한다면 Linux 에서 보편적으로 하는 방식으로 한다.
MY_ENV_VAR=xxx docker compose up -d
# 혹은
export MY_ENV_VAR=xxx
docker compose up -d
* ''docker-compose.yml'' 내에서의 환경변수
servicename:
environment:
- MY_ENV_VAR=xxx # 명시적 값 설정
- ANOTHER_ENV_VAR # 이 값은 외부 설정값이 그대로 container 로 주입됨.
env_file:
- web-variables.env # 환경변수 파일 내의 환경변수들이 전달됨.
* ''docker-compose.yml'' 에서 환경 변수 사용
* ''${MY_VARIABLE}'' : 주입된 값을 그냥 사용
* ''${MY_VARIABLE:-default}'' : ''MY_VARIABLE'' 이 지정이 안 됐거나 빈 값(''""'')이면 ''default'' 사용
* ''${MY_VARIABLE-default}'' : ''MY_VARIABLE'' 이 지정이 안 된 경우에만 ''default'' 사용
===== Multiple docker-compose.yml 다중 파일 설정 =====
* 기본적으로 ''docker-compose.yml''과 존재할 경우 ''docker-compose.override.yml''을 순서대로 읽어서 적용한다.
* 따라서 개발자가 자기만의 환경이 필요할 때는 ''.gitignore''에 ''docker-compose.override.yml''을 넣어두고, 추가 사항만 해당 파일에 override할 추가 사항을 기입하면 된다.
* [[https://runnable.com/docker/advanced-docker-compose-configuration|Advanced Docker Compose Configuration | Runnable Docker Guides]]
* ''-f'' 옵션으로 명시적으로 파일을 지정하면 ''docker-compose.override.yml''은 무시되고 지정한 순서대로 설정을 override 한다.
# 두 파일을 순서대로 읽고 설정을 override 한다.
docker-compose -f docker-compose.yml -f docker-compose.production.yml up -d
* admin 처럼 기본 ''docker-compose.yml''에 있는 서버에 접속하는 admin web 을 원할 때만 띄우고 싶다면 admin 용 yml을 만들고서 ''run'' 명령으로 필요할 때만 띄운다.
# docker-compose.admin.yml 에 dbadmin, db-backup 이라는 서비스가 docker-compose.yml 에 있는 db에 접속해서 실행되는 것이라면
docker-compose -f docker-compose.yml -f docker-compose.admin.yml run dbadmin db-backup
===== Extending Service : 서비스 확장 =====
* 다중 파일 기법과 유사하지만 공통 설정을 빼놓고 항상 읽어들이는 방식
* ''common-services.yml''에 공통 설정으로 된 service 가 하나 있다면 해당 service 의 공통 설정을 가져가는 확장할 수 있다.
# common-services.yml - 아래 서비스는 설정일 뿐, 실제로 작동하는게 아님
webapp:
build: .
ports:
- "8000:8000"
volumes:
- "/data"
# docker-compose.yml - webapp 을 확장한 web 서비스
web:
extends:
file: common-services.yml
service: webapp
* 서비스들은 ''links'', ''volumes_from'', ''depends_on''은 ''extends''로는 공유할 수 없다. 항상 명시해야 한다.
===== 참조 =====
* [[https://dev-yeon.tistory.com/20|[docker-compose] docker-compose up에서 네트워크 생성이 되지 않을 때]]
* [[https://www.44bits.io/ko/post/almost-perfect-development-environment-with-docker-and-docker-compose|도커(Docker) 컴포즈를 활용하여 완벽한 개발 환경 구성하기 | 44BITS 기술 블로그]]
* [[https://meetup.toast.com/posts/277|Docker Compose와 버전별 특징 : NHN Cloud Meetup]]