Dockerized Django Application Deployed to AWS Elastic Beanstalk Flushes Database Everytime I Rebuild My Environment. Как мне сохранить БД?
Я развернул django-приложение с помощью docker на AWS Elastic Beanstalk, которое подключено к базе данных AWS RDS postgresql. Каждый раз, когда я обновляю свой код и перестраиваю образ docker, база данных всегда стирается. Я использую github actions для развертывания приложения каждый раз, когда я продвигаю свой код. Я хочу, чтобы база данных сохранялась, как мне это сделать?
После поиска похожих проблем большинство людей предположили, что в одном из сценариев развертывания может быть команда flush. Это не так в моих сценариях развертывания, потому что я никогда явно не промываю базу данных.
Github Actions Config
name: Staging Docker Image CI
on:
push:
branches: [ staging ]
pull_request:
branches: [ staging ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
lfs: 'true'
-
name: Build the Docker image
run: docker build -t scrims -f Dockerfile .
-
name: Generate Deployment Package
run: zip -r deploy.zip *
-
name: Get timestamp
uses: gerred/actions/current-time@master
id: current-time
- name: Run string replace
uses: frabert/replace-string-action@master
id: format-time
with:
pattern: '[:\.]+'
string: "${{ steps.current-time.outputs.time }}"
replace-with: '-'
flags: 'g'
- name: Deploy to EB
uses: einaregilsson/beanstalk-deploy@v14
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: scrims
environment_name: scrims-env-staging
version_label: "scrims-staging-${{ steps.format-time.outputs.replaced }}"
region: ap-southeast-1
deployment_package: deploy.zip
Dockerfile
# syntax=docker/dockerfile:1
FROM python:3.8-slim
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt /code/
RUN apt-get update
RUN apt-get -y install libpq-dev gcc
RUN pip3 install -r requirements.txt --no-cache-dir
COPY . /code/
docker-compose.yml
version: "3.9"
services:
web:
build:
context: .
dockerfile: Dockerfile
command: >
sh -c "python3 manage.py collectstatic --noinput &&
python3 manage.py migrate &&
python3 manage.py ensure_admin &&
python3 manage.py runserver 0.0.0.0:8000"
volumes:
- .:/code
ports:
- "80:8000"
Конфигурация базы данных Elastic Beanstalk
Подключение к среде/базе данных
"База данных пары"
Политика удаления базы данных
"Создать моментальный снимок"
Конфигурация базы данных в Django settings.py
if 'RDS_HOSTNAME' in os.environ:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ['RDS_DB_NAME'],
'USER': os.environ['RDS_USERNAME'],
'PASSWORD': os.environ['RDS_PASSWORD'],
'HOST': os.environ['RDS_HOSTNAME'],
'PORT': os.environ['RDS_PORT'],
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.getenv("POSTGRES_DB"),
'USER': os.getenv("POSTGRES_USER"),
'PASSWORD': os.getenv("POSTGRES_PASSWORD"),
'HOST': 'localhost' if ENVIRONMENT == 'local' else 'db'
}
}
Django Custom Command (ensure_admin)
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
import os
class Command(BaseCommand):
help = "Creates an admin user non-interactively if it doesn't exist"
def handle(self, *args, **options):
username = os.getenv("DJANGO_SUPERUSER_USERNAME")
email = os.getenv("DJANGO_SUPERUSER_EMAIL")
password = os.getenv("DJANGO_SUPERUSER_PASSWORD")
discord_id = os.getenv("DJANGO_SUPERUSER_DISCORD_ID")
User = get_user_model()
if not User.objects.filter(username=username).exists():
User.objects.create_superuser(
username=username,
email=email,
discord_id=discord_id,
password=password
)
else:
admin = User.objects.get(username=username)
admin.email = email
admin.password = password
admin.discord_id = discord_id
admin.save()
Спасибо за помощь.