programing

Docker-compose mysql 연결이 준비되었는지 확인

copyandpastes 2021. 1. 14. 23:38
반응형

Docker-compose mysql 연결이 준비되었는지 확인


내 앱 컨테이너가 db 컨테이너가 시작되고 연결을 수락 할 준비가 될 때까지 마이그레이션 / 시작을 실행하지 않는지 확인하려고합니다.

그래서 나는 healthcheck를 사용하기로 결정했고 docker compose file v2의 옵션에 따라 다릅니다.

앱에는 다음이 있습니다.

app:
    ...
    depends_on:
      db:
      condition: service_healthy

반면에 db에는 다음과 같은 상태 검사가 있습니다.

db:
  ...
  healthcheck:
    test: TEST_GOES_HERE
    timeout: 20s
    retries: 10

다음과 같은 몇 가지 접근 방식을 시도했습니다.

  1. db DIR이 생성되었는지 확인 test: ["CMD", "test -f var/lib/mysql/db"]
  2. mysql 버전 얻기 : test: ["CMD", "echo 'SELECT version();'| mysql"]
  3. 관리자 핑 (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이 실행되고 연결을 수락 할 때까지).


mysql이 준비 될 때까지 기다리도록 컨테이너를 변경할 수 있다면 그렇게하십시오.

데이터베이스를 연결하려는 컨테이너를 제어 할 수없는 경우 특정 포트를 기다릴 수 있습니다.

이를 위해 작은 스크립트를 사용하여 다른 컨테이너에 의해 노출 된 특정 포트를 기다립니다.

이 예에서 myservermydb 컨테이너 포트 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 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'

I personally prefer wait-for since it can run in an Alpine container (sh compatible, no dependance on bash). Drawback is that it depends on netcat, so if you decide to use it, make sure you have netcat installed in the container, or install it in your Dockerfile, for example with:

RUN apt-get -q update && apt-get -qy install netcat

I also forked the wait-for project so it can check for healthy HTTP status (it uses wget). Then you can do something like that:

command: sh -c 'bin/wait-for http://api/ping -- jest test'

Hi for a simple healthcheck using docker-compose v2.1, I used:

/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\"

Basically it runs a simple mysql command SHOW DATABASES; using as an example the user root with the password rootpasswd in the database.

If the command succeed the db is up and ready so the healthcheck path. You can use interval so it tests at interval.

Removing the other field for visibility, here is what it would look like in your docker-compose.yaml.

version: '2.1'

  services:
    db:
      ...
      healthcheck:
        test: "/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\""
        interval: 2s
        timeout: 20s
        retries: 10

     app:
       ...
       depends_on:
         db:
         condition: service_healthy

I modified the docker-compose.yml as per the following example and it worked.

  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

In my case ../schemaAndSeedData contains multiple schema and data seeding sql files. Design your own check script can be similar to following select * from LastSchema.LastDBInsert.

While web dependent container code was

depends_on:
  mysql:
    condition: service_healthy

This should be enough

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

ReferenceURL : https://stackoverflow.com/questions/42567475/docker-compose-check-if-mysql-connection-is-ready

반응형