내 앱 컨테이너가 db 컨테이너가 시작되고 연결을 수락 할 준비가 될 때까지 마이그레이션 / 시작을 실행하지 않는지 확인하려고합니다.
그래서 나는 healthcheck를 사용하기로 결정했고 docker compose file v2의 옵션에 따라 달라집니다.
앱에는 다음이 있습니다.
app:
...
depends_on:
db:
condition: service_healthy
반면에 db에는 다음과 같은 상태 검사가 있습니다.
db:
...
healthcheck:
test: TEST_GOES_HERE
timeout: 20s
retries: 10
다음과 같은 몇 가지 접근 방식을 시도했습니다.
- db DIR이 생성되었는지 확인
test: ["CMD", "test -f var/lib/mysql/db"]
- mysql 버전 얻기 :
test: ["CMD", "echo 'SELECT version();'| mysql"]
- 관리자 핑 (db 컨테이너를 정상으로 표시하지만 유효한 테스트가 아닌 것 같음)
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
누구든지 이것에 대한 해결책이 있습니까?
답변
version: "2.1"
services:
api:
build: .
container_name: api
ports:
- "8080:8080"
depends_on:
db:
condition: service_healthy
db:
container_name: db
image: mysql
ports:
- "3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_USER: "user"
MYSQL_PASSWORD: "password"
MYSQL_DATABASE: "database"
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10
api 컨테이너는 db 컨테이너가 정상이 될 때까지 시작되지 않습니다 (기본적으로 mysqladmin이 실행되고 연결을 수락 할 때까지).
답변
docker-compose v3 + 를 condition
사용하는 경우의 옵션 depends_on
이 제거되었습니다 .
권장되는 경로가 아니라 사용하는 것입니다 wait-for-it
, dockerize
또는 wait-for
. 당신에 docker-compose.yml
파일로 명령을 변경 :
command: sh -c 'bin/wait-for db:3306 -- bundle exec rails s'
개인적 wait-for
으로 Alpine 컨테이너에서 실행할 수 있기 때문에 선호합니다 ( sh
호환성, 의존성 없음 bash
). 단점은에 따라 다르 netcat
므로 사용하기로 결정한 경우 netcat
컨테이너에 설치 했는지 확인 하거나 다음과 같이 Dockerfile에 설치하십시오.
RUN apt-get -q update && apt-get -qy install netcat
또한 건강한 HTTP 상태를 확인할 수 있도록 프로젝트를 분기wait-for
했습니다 (사용 wget
). 그런 다음 다음과 같이 할 수 있습니다.
command: sh -c 'bin/wait-for http://api/ping -- jest test'
추신 : PR은 또한 해당 용량을 wait-for
프로젝트 에 추가하기 위해 병합 할 준비 가되었습니다 .
답변
이 정도면 충분합니다
version: '2.1'
services:
mysql:
image: mysql
ports: ['3306:3306']
environment:
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
healthcheck:
test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD
답변
mysql이 준비 될 때까지 기다리도록 컨테이너를 변경할 수 있다면 그렇게하십시오.
데이터베이스를 연결하려는 컨테이너를 제어 할 수없는 경우 특정 포트를 기다릴 수 있습니다.
이를 위해 다른 컨테이너에 의해 노출 된 특정 포트를 기다리는 작은 스크립트를 사용하고 있습니다.
이 예에서 myserver 는 mydb 컨테이너 의 포트 3306 에 도달 할 수 있을 때까지 기다립니다 .
# Your database
mydb:
image: mysql
ports:
- "3306:3306"
volumes:
- yourDataDir:/var/lib/mysql
# Your server
myserver:
image: myserver
ports:
- "....:...."
entrypoint: ./wait-for-it.sh mydb:3306 -- ./yourEntryPoint.sh
여기 에서 스크립트 wait-for-it 문서를 찾을 수 있습니다.
답변
docker-compose v2.1 사용하여 간단한 상태 확인을 위해 안녕하세요 .
/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\"
기본적으로 데이터베이스 에서 암호 를 가진 사용자 를 예로 사용하여 간단한 mysql
명령 SHOW DATABASES;
을 실행 합니다.root
rootpasswd
명령이 성공하면 db가 가동되어 상태 확인 경로가 준비됩니다. interval
간격으로 테스트하도록 사용할 수 있습니다 .
가시성을 위해 다른 필드를 제거하면 docker-compose.yaml
.
version: '2.1'
services:
db:
... # Other db configuration (image, port, volumes, ...)
healthcheck:
test: "/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\""
interval: 2s
timeout: 20s
retries: 10
app:
... # Other app configuration
depends_on:
db:
condition: service_healthy
답변
docker-compose.yml
다음 예제에 따라 수정했고 작동했습니다.
mysql:
image: mysql:5.6
ports:
- "3306:3306"
volumes:
# Preload files for data
- ../schemaAndSeedData:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: rootPass
MYSQL_DATABASE: DefaultDB
MYSQL_USER: usr
MYSQL_PASSWORD: usr
healthcheck:
test: mysql --user=root --password=rootPass -e 'Design your own check script ' LastSchema
제 경우 ../schemaAndSeedData
에는 여러 스키마 및 데이터 시드 SQL 파일이 포함되어 있습니다. Design your own check script
다음과 유사 할 수 있습니다 select * from LastSchema.LastDBInsert
.
웹 종속 컨테이너 코드가
depends_on:
mysql:
condition: service_healthy
답변
나는 똑같은 문제가 있었고이 목적을 위해 외부 bash 스크립트를 만들었습니다 (Maxim 대답에서 영감을 얻었습니다). 교체 mysql-container-name
도 비밀번호 / 사용자가 필요 MySQL의 컨테이너의 이름 :
bin / wait-for-mysql.sh :
#!/bin/sh
until docker container exec -it mysql-container-name mysqladmin ping -P 3306 -proot | grep "mysqld is alive" ; do
>&2 echo "MySQL is unavailable - waiting for it... ?"
sleep 1
done
내 MakeFile에서이 스크립트는 docker-compose
up call 를 호출합니다.
wait-for-mysql: ## Wait for MySQL to be ready
bin/wait-for-mysql.sh
run: up wait-for-mysql reload serve ## Start everything...
그런 다음 오류없이 다른 명령을 호출 할 수 있습니다.
드라이버에서 예외가 발생했습니다. SQLSTATE [HY000] [2006] MySQL 서버가 사라졌습니다.
출력 예 :
docker-compose -f docker-compose.yaml up -d
Creating network "strangebuzzcom_default" with the default driver
Creating sb-elasticsearch ... done
Creating sb-redis ... done
Creating sb-db ... done
Creating sb-app ... done
Creating sb-kibana ... done
Creating sb-elasticsearch-head ... done
Creating sb-adminer ... done
bin/wait-for-mysql.sh
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
MySQL is unavailable - waiting for it... ?
mysqld is alive
php bin/console doctrine:cache:clear-metadata
// Clearing all Metadata cache entries
[OK] Successfully deleted cache entries.
이 접근 방식에서는 이제 쓸모가 없으므로 상태 확인을 삭제했습니다.