docker-compose를 통해 django 서비스와 database 서비스를 run 시켜야 한다.
사전에 다운받은 dump파일을 database 컨테이너에 insert 후 django 서비스가 run돼야 한다.
import time
from django.db import connections
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand
class Command(BaseCommand):
'''Django command to pause execution until database is available'''
def handle(self, *args, **options):
self.stdout.write('Waiting for database...')
db_conn = None
max_attempts = 15
waiting_time = 10
attempts = 0
while db_conn is None and attempts < max_attempts:
try:
db_conn = connections['default']
db_conn.ensure_connection()
except OperationalError:
attempts += 1
self.stdout.write(f'Database unavailable, waiting {waiting_time} seconds... (Attempt {attempts})')
time.sleep(waiting_time)
if db_conn:
self.stdout.write(self.style.SUCCESS('Database is available!'))
else:
self.stdout.write(self.style.ERROR(f'Database is still unavailable after {max_attempts} attempts.'))
version: "3.9"
volumes:
db:
driver: local
services:
db:
image: mariadb:10.5.8
container_name: mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: 12341234
MYSQL_DATABASE: local_db
ports:
- 3306:3306
volumes:
- db:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
backend:
build:
context: .
container_name: django
restart: always
environment:
DJANGO_ENV: development
LOCAL_MYSQL_HOST: db
LOCAL_MYSQL_NAME: local_db
ports:
- 8000:8000
command: >
bash -c "while !</dev/tcp/db/3306; do
echo 'Waiting for DB to become available...'
sleep 2
done && python manage.py runserver 0.0.0.0:8000"
env_file:
- ./config/settings/.env
depends_on:
- db
volumes:
- .:/src
command: >
bash -c "while !</dev/tcp/db/3306; do
echo 'Waiting for DB to become available...'
sleep 2
done && python manage.py runserver 0.0.0.0:8000"
3306포트를 사용하는 db 서비스가 활성화되는 것을 django 서비스가 기다리게 함으로써 해결할 수있다.
wait_for_db.py를 채택하지 않은 이유는 아래와 같다.
max_attempts
,waiting_time
의 변수값을 최적화 시켜줘야 한다.