hotamul의 개발 이야기

[Flask] Flask & docker-compose wait for db 본문

Dev./Flask

[Flask] Flask & docker-compose wait for db

hotamul 2022. 8. 10. 00:31

docker-compose

version: "3.9"

services:
  app:
    build:
      context: .
      args:
        - DEV=true
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    command: >
      sh -c "flask run --host=0.0.0.0 --port=8000"
    environment:
      - DB_HOST=db
      - DB_NAME=devdb
      - DB_USER=devuser
      - DB_PASS=changeme
      - FLASK_ENV=development
      - FLASK_APP=app
    depends_on:
      - db

  db:
    image: postgres:13-alpine
    volumes:
      - dev-db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=devdb
      - POSTGRES_USER=devuser
      - POSTGRES_PASSWORD=changeme


volumes:
  dev-db-data:

wait for db

위와 같이 docker-compose 파일을 구성하면 app, db 두개의 service를 띄우게 된다. depends_on을 통해 db가 먼저 실행되고 그 다음 app이 실행 된다.


하지만 실제로 각각의 service는 원하는 순서대로 (db -> app) 실행되지만 db service가 완료되기 전에 flask가 실행된다.

it doesn’t verify when a specific service is really ready.


따라서 아래와 같은 방법으로 db service가 완전히 준비됨을 보장할 수 있다.

app 폴더 아래 scripts 폴더를 생성하고 아래와 같이 작성한다.

#!/bin/sh
# wait-for-postgres.sh

set -e

POSTGRES_HOST="$DB_HOST"
POSTGRES_PASSWORD="$DB_PASS"
POSTGRES_USER="$DB_USER"
POSTGRES_DBNAME="$DB_NAME"
shift

until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$POSTGRES_HOST" -U $POSTGRES_USER -d $POSTGRES_DBNAME -c '\q'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec "$@"

그리고 docker-compose.yml의 app command 부분을 아래와 같이 수정한다.

version: "3.9"

services:
  app:
      ...
    command: ["./scripts/wait-for-postgres.sh", "--", "flask", "run", "--host=0.0.0.0", "--port=8000"]
    ...

docker-compose up 명령어로 실행했을 때 Permission denied 에러가 발생하면 권한을 변경해주면 된다.

chmod 755 ./scripts/*

이제 다시 실행하면 아래와 같이 정상적으로 실행됨을 확인할 수 있다.

...
app_1  |        TCP/IP connections on port 5432?
app_1  | Postgres is unavailable - sleeping
...
app_1  | Postgres is up - executing command
app_1  |  * Serving Flask app 'app' (lazy loading)
app_1  |  * Environment: development
app_1  |  * Debug mode: on
app_1  |  * Running on all addresses (0.0.0.0)
app_1  |    WARNING: This is a development server. Do not use it in a production deployment.
app_1  |  * Running on http://127.0.0.1:8000
...

참고 : https://docs.docker.com/compose/startup-order/

Comments