Docker-compose
Docker-Compose란 무엇인가?
Docker compose란 여러 개의 컨테이너로부터 이루어진 서비스를 구축 실행하는 순서를 자동으로 하여 관리를 간단히 하는 기능이다.
Docker compose에서는 compose 파일을 준비하여 커맨드를 1회 실행하는 것으로 그 파일로부터 설정을 읽어들여 모든 컨테이너 서비스를 실행시키는 것이 가능하다.
•
다수의 Container로 소프트웨어가 구성되는 경우 사용할 수 있는 툴 + 환경 설정 파일(yml)
◦
docker-compose.yml로 설정
◦
여기서 다양한 테스트들도 수행 가능
◦
다양한 버전을 만드는 것도 일반적 (dev, test, prod 등등)
▪
예 : docker-compose.dev.yml
•
개별 Container를 따로 관리하는 것보다 훨씬 더 생산성이 높음
•
환경설정 파일의 이름은 docker-compose.yml이나 docker-compose.yaml
•
하지만 그만큼 배워야할 것도 많고 복잡해짐
•
사용법 자체는 간단: 소프트웨어를 구성하는 모든 컨테이너에게 적용됨
○ 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
Python
복사
•
Docker-Compose
◦
Docker Desktop의 일부로 설치가 됨
◦
Docker Engine을 실행하고 먼저 터미널에서 버전 확인
▪
만일 docker-compose가 없다고 나오면 먼저 docker-compose부터 실행
◦
Docker Compose v.1.27+ 부터 v2와 v3가 합쳐짐
$ docker-compose --version
Docker Compose version v2.15.1
Python
복사
docker-compose.yml 작성
•
다양한 버전이 존재하는데 우리는 v2와 v3가 합쳐진 버전 사용 예정
•
services: 다음으로 프로그램을 구성하는 서비스들을 지정
◦
각 서비스는 별개의 Docker Image 지정과 Docker Container 실행으로 구성됨
◦
즉 각 서비스는 자신의 Dockerfile을 갖고 있어야함 아니면 docker hub등에서 이미지를 다운로드
◦
서비스 별로 포트번호, 환경변수, 디스크 볼륨 등을 지정해야함
◦
서비스 이름은 아무 이름이나 가능
•
volumes: 앞서 사용된 docker volume들을 지정
•
networks: 앞서 사용된 network들을 지정
◦
network은 지정하지 않으면 같은 docker-compose 그룹 내에서는 모두 연결이 됨
◦
지정 안할 시, “default”라는 이름으로 기본 네트워크가 만들어짐
•
예제
◦
컨테이너 네이밍과 볼륨을 유심히 볼 것
services:
frontend:
build: ./frontend
ports:
- 3000:3000
backend:
build: ./backend
ports:
- 3001:3001
environment:
DB_URL: mongodb://database/vidly # 컨테이너명/디비명(볼륨 X)
database:
image: mongo:4.0-xenial
ports:
- 27017:27017
volumes:
- vidly: /data/db
volumes:
vidly:
Python
복사
◦
앗 같은데요..? ⇒ 당신은 눈치가 빠르시군요!
docker-compose vs. docker compose
•
v1: docker-compose
•
v2: docker compose
•
Docker 1.27부터 docker에 명령으로 compose가 추가됨
◦
docker-compose 보다는 “docker compose”를 쓰는 것이 더 좋음
◦
별도로 docker-compose를 설치할 필요가 없음. 하지만 아직까지 대부분의 문서가 docker-compose 중심으로 만들어져 있음
docker-compose.yaml or docker-compose.yml
•
docker compose 명령의 위 둘 중의 하나를 찾음
◦
만일 둘다 존재한다면 에러 발생함
•
만일 다른 이름의 파일을 사용하고 싶다면 -f 옵션 사용
◦
docker-compose -f docker-compose.mac.yml up
docker-compose로 이미지 생성과 관리
•
docker-compose build
◦
build 키로 지정된 것들 대상
•
docker-compose pull
◦
docker hub에서 이미지들을 읽어오려고 함
•
docker images
◦
각 개별 이미지 앞에 폴더 이름을 prefix로 붙임 (docker hub에서 읽어온 것들은 예외)
•
docker-compose images
◦
컨테이너에 의해 실행되고 있는 이미지들만 보여줌
•
docker-compose push
◦
docker hub으로 이미지들을 푸시하려고 함
docker-compose로 소프트웨어 시작과 중단
•
docker-compose up # build => create => start
◦
docker-compose create
◦
docker-compose start
•
docker-compose down
•
docker-compose stop
•
docker-compose rm
•
docker-compose ls ⇒ # docker-compose를 그룹별로 보여줌
•
docker-compose ps
docker-compose 네트워킹
•
docker끼리 네트워크 연결이 필요한 경우
◦
services에 준 이름으로 호스트 이름이 생성됨
◦
내부에 DNS 서버가 하나 생성되어 이름을 내부 IP로 변환해줌
•
별도로 네트워크를 구성하고 싶다면
◦
networks에 네트워크를 나열하고 네트워크를 적절하게 서비스에 지정해주어야함
•
docker network ls
◦
example-voting-app_default : docker compose로 실행되는 기본 네트워크
실습 - Voting Application with Docker-compose
우리가 실행해볼 프로그램 = Voting Application
Docker에서 제공해주는 예제 프로그램
•
먼저 매뉴얼하게 하나씩 빌드해보자
● docker build -t vote ./vote
● docker build -t result ./result
● docker build -t worker ./worker
# 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
## 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을 통해 확인 가능
•
네트워크 관련 이슈를 더 자세히 보자
◦
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
복사
▪
vote에 exec해서 iputils-ping 설치 후 ping 명령으로 redis 호스트 이름이 연결되는지 확인
$ ping redis
ping: cannot resolve redis: Unknown host
Python
복사
•
host ⇒ 컨테이너 이름 → redis
◦
result/server.js
var pool = new pg.Pool({
connectionString:
'postgres://postgres:postgres@db/postgres'
});
Python
복사
▪
Postgres 연결시 postgres:postgres를 사용하고 있음을 주의깊게 볼것!
▪
@ 다음에 오는 이름은 컨테이너 이름
•
Docker Compose 파일에서 db라는 이름으로 PostgreSQL 컨테이너를 정의
◦
worker/Program.cs
var pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;");
var redisConn = OpenRedisConnection("redis");
Python
복사
▪
worker에서는 postgresql과 redis를 동시에 통신
▪
이 부분에서 서로의 존재를 몰라 에러가 발생 ⇒ 통신 X
그렇다면 어떻게 Network 이슈를 해결할 수 있을까?
•
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
# 만약 중요한 것이 없다면 아래와 같이 수행
● docker container rm -f $(docker container ls -aq)
# 중요한 컨테이너가 있을 경우
docker ps
docker stop {컨테이너 id}
docker rm {컨테이너 id}
# 네트워크 생성
● docker network create mynetwork
.
├── healthchecks
├── k8s-specifications
├── result #
├── seed-data
├── vote #
└── worker #
● 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
## vote container로 들어가서 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
Python
복사
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
# 응? 통신은 되는데..?
Python
복사
◦
이는 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");
Python
복사
•
이를 해결하려면 Container를 실행할 때 아래 2개의 환경변수를 넘겨주어야 함
◦
POSTGRES_USER: "postgres"
◦
POSTGRES_PASSWORD: "postgres"
◦
이걸 docker-compose 환경 설정 파일을 통해 넘기면서 해결해볼 예정
•
docker-compose.yml로 포팅: 뼈대
● docker run -d --name=redis --network mynetwork redis
● 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
Python
복사
◦
앞서 컨테이너를 하나씩 실행할 때 네트워킹 부분은 제대로 동작하지 않았음
◦
docker-compose up
▪
docker volume이란?
•
Docker volume은 Docker 컨테이너가 데이터를 저장하거나 공유하기 위한 방법.
•
컨테이너는 기본적으로 독립적인 파일 시스템을 가지고 있으며, 컨테이너가 삭제되면 그 안의 데이터도 함께 삭제됨.
•
그러나 Docker volume을 사용하면 컨테이너의 데이터를 호스트 머신의 파일 시스템에 영구적으로 저장하고 유지할 수 있다.
•
docker-compose.yml로 포팅: services 키 보기
◦
빌드는 각 객체 폴더 밑에 Dockerfile로 수행
•
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"
Python
복사
•
데모
● 먼저 청소 한번 하기
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 expample-voting-app-db-1 sh
/ $ whoami
postgres
/ $ psql
psql (15.3)
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
Python
복사
네트워크 정의를 통한 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
Python
복사
•
변경
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:
Python
복사
docker-compose.yml로 포팅: volumes 정의
•
어느 컨테이너 서비스의 데이터가 계속해서 저장되어야 하는가?
◦
PostgreSQL
•
db의 내용이 persistent해야함 ⇒ 볼륨 생성 (네임드 볼륨)
volumes:
db-data:
Python
복사
•
docker-compose.yml로 포팅: services들에 볼륨 지정
services:
redis:
db:
vote:
result:
worker:
Python
복사
services:
redis:
# db 데이터가 저장되는 컨테이너 내부 디렉토리 장소와 네임드 볼륨을 매핑
db:
volumes:
- db-data:/var/lib/postgresql/data
vote:
result:
worker:
volumes:
db-data:
Python
복사
docker-compose.yml로 포팅: vote 서비스 개선
•
depends_on : 서비스들간의 의존성이 있을 경우, 먼저 실행되어야 하는 서비스들을 여기 기술해야함
◦
더 나아가서 해당 서비스의 health check도 포함해줌
•
healthcheck : 해당 서비스의 건강을 나타내주는 체크를 기술
•
◦
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
Python
복사
•
docker-compose.yml의 depends_on
◦
해당 서비스가 실행되기 위해서 먼저 실행되어야 하는 서비스들을 여기 기술
▪
short form:
depends_on:
- db
- redis
Python
복사
▪
long form:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
Python
복사
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:
Python
복사
▪
Array 문법:
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
Python
복사
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 # 빌드 시에 사용할 환경 변수 설정
Python
복사
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:
Python
복사
참고로 위의 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
복사
대신, 우리는 아래 파일을 실습한다. (네트워크 설정과 볼륨 설정)
docker-compose -f docker-compose.hj.yml up -d를 통해 실습을 해보면 된다.
version: '3.7'
services:
vote:
build: ./vote
command: python app.py
ports:
- "5001:80"
networks:
- front-tier
- back-tier
result:
build: ./result
entrypoint: nodemon server.js
ports:
- "5002:80"
networks:
- front-tier
- back-tier
worker:
build: ./worker
networks:
- back-tier
redis:
image: redis:alpine
networks:
- back-tier
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
volumes:
- db-data:/var/lib/postgresql/data
networks:
- back-tier
volumes:
db-data:
networks:
front-tier:
back-tier:
Python
복사
docker-compose rm -fsv