feat: финальная конфигурация production Docker для RosmorPort
Some checks failed
Build and Push PetClones-site / build-and-push (push) Failing after 21s

Обновлен Dockerfile:
- Исправлены права доступа пользователя appuser (создание перед COPY)
- Правильный порядок операций (USER -> COPY -> mkdir)
- Оптимизация для production (workers=1, timeout=120, max-requests=200)
- collectstatic и удаление лишних файлов статики при build
Обновлен docker-compose.prod.yml:
- Переименован контейнер в petclones-site--backend
- Production переменные окружения (DEBUG=False)
- Volumes для media, database и nginx конфигов
- Gunicorn с параметрами для production
- Watchtower для автоматического обновления образов
- Ограничение ресурсов (0.25 CPU, 512M RAM)
- JSON logging с ротаци??бновлен Dockerfile:
- Исправлены права доступа пользователя appuser (создание перед COPY?? Исправлены пр?? Правильный порядок операций (USER -> COPY -> mkdir)
- Оптимизация для prod
This commit is contained in:
2026-04-01 00:08:53 +03:00
parent 1b0fa5e500
commit a9fb77c195
3 changed files with 104 additions and 124 deletions

View File

@@ -12,118 +12,99 @@ services:
dockerfile: Dockerfile
# Имя контейнера
container_name: rosmorport_web_prod
container_name: petclones-site--backend
# Переменные окружения для production
environment:
- DOCKER_ENV=1
- DEBUG=False
- ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0,web,pet-clones.cocorico.ru
- DB_ENGINE=django.db.backends.postgresql
- DB_HOST=db
- DB_PORT=5432
- DB_NAME=${POSTGRES_DB:-rosmorport_db}
- DB_USER=${POSTGRES_USER:-postgres}
- DB_PASSWORD=${POSTGRES_PASSWORD:-postgres}
- PYTHONUNBUFFERED=1
# Тома для медиа, статики и БД
volumes:
- public_media:/app/public/media
- public_static:/app/public/static
- database:/app/database
# Volume для media (загруженные пользователями файлы)
- media:/app/public/media:rw
# Volume для базы данных (SQLite файл)
- database:/app/database:rw
# Volume для экспорта конфигов из контейнера на хост
# Контейнер копирует nginx конфиг при запуске для настройки reverse-proxy на хосте
- ./config/nginx:/tmp/nginx_configs:rw # контейнер пишет сюда конфиги
# Command: скрипт для копирования конфигов из контейнера на хост при запуске
# Встроенный entrypoint nginx:alpine (/docker-entrypoint.sh) запустит это как команду
command: >
sh -c "
echo '📋 Копирование внешнего nginx конфига на хост...' &&
cp /tmp/pet-clones--external-nginx.conf.source /tmp/nginx_configs/pet-clones--external-nginx.conf.sample &&
echo '✅ Пример nginx-конфига создан в ./config/nginx/pet-clones--external-nginx.conf.sample (свежий из контейнера)' &&
if [ ! -f /tmp/nginx_configs/pet-clones--external-nginx.conf ]; then
cp /tmp/pet-clones--external-nginx.conf.source /tmp/nginx_configs/pet-clones--external-nginx.conf &&
echo '✅ Боевой nginx-конфиг создан в ./config/nginx/pet-clones--external-nginx.conf (свежий из контейнера)'
else
echo '⏭️ Боевой nginx-конфиг оставлен без изменений.'
fi
gunicorn --bind 0.0.0.0:8000 --workers 1 --worker-class sync --worker-tmp-dir /dev/shm --max-requests 200 --timeout 120 --access-logfile - --error-logfile - rosmorport_tsts.wsgi:application
"
# Перенаправляем порты
ports:
- "8000:8000"
# Зависимость от базы данных
depends_on:
db:
condition: service_healthy
# Политика перезапуска
restart: unless-stopped
# Ограничения ресурсов
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
# PostgreSQL база данных для production
db:
# Используем официальный образ PostgreSQL
image: postgres:16-alpine
container_name: rosmorport_db_prod
# Переменные окружения
environment:
- POSTGRES_DB=${POSTGRES_DB:-rosmorport_db}
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
# Том для хранения данных БД
volumes:
- postgres_data:/var/lib/postgresql/data
# Портов не открываем - доступ только изнутри контейнеров
# ports:
# - "5432:5432"
# Проверка здоровья сервиса
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
# Политика перезапуска
restart: unless-stopped
# Ограничения ресурсов
deploy:
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
# Nginx для reverse proxy (опционально)
# nginx:
# image: nginx:alpine
# container_name: rosmorport_nginx
# volumes:
# - ./config/nginx.conf:/etc/nginx/nginx.conf:ro
# - django_staticfiles:/app/static:ro
# - django_mediafiles:/app/media:ro
# ports:
# - "80:80"
# - "443:443"
# depends_on:
# - web
# restart: unless-stopped
- "127.0.0.1:8040:8000"
# Именованные тома для хранения данных
volumes:
postgres_data:
driver: local
public_media:
driver: local
public_static:
driver: local
database:
driver: local
# Политика перезапуска
restart: unless-stopped
# Метки для Watchtower (авто-обновление)
labels:
- "com.centurylinklabs.watchtower.scope=petclones-site--scope"
# Ограничения ресурсов
deploy:
resources:
limits:
cpus: '0.25'
memory: 512M
# Логирование в JSON-файлы (для сбора логов через docker logs)
logging:
driver: "json-file"
options:
max-size: "5m" # больше лимит в продакшене для логирования
max-file: "1" # храним 1 файл лога
networks:
- petclones-site--network
# WATCHTOWER ДЛЯ АВТОМАТИЧЕСКОГО ОБНОВЛЕНИЯ ОБРАЗОВ ИЗ РЕЕСТРА
watchtower:
image: containrrr/watchtower
container_name: petclones-site--watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# Переменные окружения
env_file:
- .env
environment:
- DOCKER_API_VERSION=1.44
# Берем учетные данные из .env файла
- REPO_USER=${REPO_USER}
- REPO_PASS=${REPO_PASS}
# Ограничиваем область видимости только этим проектом
- WATCHTOWER_SCOPE=petclones-site--scope
# Если нужно указать реестр явно (обычно watchtower сам понимает из имени образа)
# - WATCHTOWER_REGISTRY_URL=git.cube2.ru
command: --interval 1800 --cleanup # Проверять каждые 30 минут
logging:
driver: "json-file"
options:
max-size: "1m"
max-file: "1"
networks:
- petclones-site--network
# Сеть для сервисов
networks:
default:
name: rosmorport_network
name: petclones-site--network
driver: bridge