Я создаю образ докера сервера Django, который использует базу данных postgresql для отслеживания информации для входа в систему, загруженных / загруженных файлов и т. Д. Я хочу, чтобы данные в моей базе данных оставались неизменными даже после выхода и повторного запуска докераimage.
Я создал файл docker-compose и файл точки входа, который успешно запускает образ докера сервера и создает том для базы данных. В каждом учебном пособии, которое я читал в Интернете, говорилось, что наличие постоянных данных так же просто, как сопоставление тома вашей базы данных с того места, где вы хотите, чтобы он хранился на хосте, с расположением / var / lib / postgresql / data в образе докера.
docker-compose.yml:
version: '3.7'
services:
web:
build: ./
command: python manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000
environment:
- DEBUG=1
- SECRET_KEY=foo
- SQL_ENGINE=django.db.backends.postgresql
- SQL_HOST=db
- SQL_PORT=5432
- DATABASE=postgres
depends_on:
- db
db:
image: postgres
volumes:
- ./postgres_data:/var/lib/postgresql/data/
environment:
...
ports:
- 5432:5432
volumes:
postgres_data:
docker-entrypoint.sh:
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python manage.py flush --no-input
python manage.py migrate
exec $@
Dockerfile:
FROM python:3.7.4-alpine
ARG PROJECT=MyProject
ARG PROJECT_DIR=/var/www/${PROJECT}
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& pip install psycopg2 \
&& pip install django \
&& pip install djangorestframework \
&& pip install django-sslserver \
&& pip install djangosecure \
&& pip install psycopg2 \
&& pip install django-environ \
&& apk del build-deps
COPY . $PROJECT_DIR/
ENTRYPOINT ["/var/www/EchoNine/docker-entrypoint.sh"]
settings.py
import os
import sys
from django.conf import settings
import environ
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
MEDIA_URL = 'inspections/'
TEST_ROOT = os.path.join(BASE_DIR, 'test')
if ('test' in sys.argv):
MEDIA_ROOT = os.path.join(TEST_ROOT, 'inspections')
else:
MEDIA_ROOT = os.path.join(BASE_DIR, 'inspections')
root = environ.Path(__file__) - 3 # three folder back (/a/b/c/ - 3 = /)
environ.Env.read_env(env.str('ENV_PATH', '.env.production')) # reading .env fil
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG') # This is set to False
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'djangosecure',
'sslserver',
# Third-Party Apps
'rest_framework',
'rest_framework.authtoken',
# Local Apps (Your project's apps)
'MyProject.MyProject',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
MIDDLEWARE_CLASSES = (
'djangosecure.middleware.SecurityMiddleware',
)
ROOT_URLCONF = 'MyProject.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'MyProject.wsgi.application'
DATABASES = {
'default': {
'ENGINE': os.environ.get('SQL_ENGINE', 'django.db.backends.sqlite3'),
'NAME': os.environ.get('SQL_DATABASE', os.path.join(BASE_DIR, 'db.sqlite3')),
'USER': os.environ.get('SQL_USER', 'user'),
'PASSWORD': os.environ.get('SQL_PASSWORD', 'password'),
'HOST': os.environ.get('SQL_HOST', 'localhost'),
'PORT': os.environ.get('SQL_PORT', '5432'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
STATIC_URL = '/static/'
Когда я запускаю образ докера, создаю нового суперпользователя внутри образа докера (который хранит данные в базе данных), закрываю образ докера, а затем снова запускаю образ, все таблицы базы данных снова пусты. Я ожидаю, что база данных сохранит записи базы данных от последнего запуска.
Оба ./postgres_data на хосте и / var / lib / postgresql / data в образе докера, похоже, инициализируются с файлами и папкойструктура в них.
Может кто-нибудь сказать мне, что я делаю не так? Спасибо.