Django в production окружении

Production развертывание Django требует специальных настроек безопасности, производительности и мониторинга. Правильная конфигурация критически важна для стабильной работы сайта в реальных условиях.

Структура production настроек

Создай отдельный файл настроек для production. Раздели настройки на несколько файлов:

1project/
2  settings/
3      __init__.py
4      base.py          # Общие настройки
5      development.py   # Разработка
6      production.py    # Production
7      staging.py       # Тестирование

Основные production настройки

Создай файл settings/production.py:

  1import os
  2    from pathlib import Path
  3    from .base import *
  4
  5    # Базовые production настройки
  6    DEBUG = False
  7    TEMPLATE_DEBUG = False
  8
  9    # Безопасность
 10    SECRET_KEY = os.environ.get('SECRET_KEY')
 11    if not SECRET_KEY:
 12        raise ValueError('SECRET_KEY environment variable is required')
 13
 14    # Разрешенные хосты
 15    ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')
 16    if not ALLOWED_HOSTS or ALLOWED_HOSTS == ['']:
 17        raise ValueError('ALLOWED_HOSTS environment variable is required')
 18
 19    # HTTPS настройки
 20    SECURE_SSL_REDIRECT = True
 21    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
 22    SESSION_COOKIE_SECURE = True
 23    CSRF_COOKIE_SECURE = True
 24    SECURE_HSTS_SECONDS = 31536000  # 1 год
 25    SECURE_HSTS_INCLUDE_SUBDOMAINS = True
 26    SECURE_HSTS_PRELOAD = True
 27
 28    # Безопасность заголовков
 29    SECURE_CONTENT_TYPE_NOSNIFF = True
 30    SECURE_BROWSER_XSS_FILTER = True
 31    X_FRAME_OPTIONS = 'DENY'
 32
 33    # CSRF защита
 34    CSRF_COOKIE_HTTPONLY = True
 35    CSRF_COOKIE_AGE = 31449600  # 1 год
 36    CSRF_TRUSTED_ORIGINS = os.environ.get('CSRF_TRUSTED_ORIGINS', '').split(',')
 37
 38    # База данных PostgreSQL
 39    DATABASES = {
 40        'default': {
 41            'ENGINE': 'django.db.backends.postgresql',
 42            'NAME': os.environ.get('DB_NAME'),
 43            'USER': os.environ.get('DB_USER'),
 44            'PASSWORD': os.environ.get('DB_PASSWORD'),
 45            'HOST': os.environ.get('DB_HOST', 'localhost'),
 46            'PORT': os.environ.get('DB_PORT', '5432'),
 47            'OPTIONS': {
 48                'sslmode': 'require',
 49                'connect_timeout': 10,
 50            },
 51            'CONN_MAX_AGE': 600,  # 10 минут
 52            'CONN_HEALTH_CHECKS': True,
 53        }
 54    }
 55
 56    # Кэширование Redis
 57    CACHES = {
 58        'default': {
 59            'BACKEND': 'django_redis.cache.RedisCache',
 60            'LOCATION': os.environ.get('REDIS_URL', 'redis://localhost:6379/1'),
 61            'OPTIONS': {
 62                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
 63                'CONNECTION_POOL_KWARGS': {
 64                    'max_connections': 50,
 65                    'retry_on_timeout': True,
 66                },
 67                'SERIALIZER': 'django_redis.serializers.json.JSONSerializer',
 68            },
 69            'KEY_PREFIX': 'django_cache',
 70            'TIMEOUT': 300,  # 5 минут по умолчанию
 71        },
 72        'sessions': {
 73            'BACKEND': 'django_redis.cache.RedisCache',
 74            'LOCATION': os.environ.get('REDIS_URL', 'redis://localhost:6379/1'),
 75            'OPTIONS': {
 76                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
 77            },
 78            'KEY_PREFIX': 'session',
 79        }
 80    }
 81
 82    # Сессии в Redis
 83    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
 84    SESSION_CACHE_ALIAS = 'sessions'
 85
 86    # Статические файлы
 87    STATIC_ROOT = BASE_DIR / 'staticfiles'
 88    STATIC_URL = '/static/'
 89
 90    # Медиа файлы
 91    MEDIA_ROOT = BASE_DIR / 'media'
 92    MEDIA_URL = '/media/'
 93
 94    # Логирование
 95    LOGGING = {
 96        'version': 1,
 97        'disable_existing_loggers': False,
 98        'formatters': {
 99            'verbose': {
100                'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
101                'style': '{',
102            },
103            'simple': {
104                'format': '{levelname} {message}',
105                'style': '{',
106            },
107        },
108        'handlers': {
109            'file': {
110                'level': 'INFO',
111                'class': 'logging.handlers.RotatingFileHandler',
112                'filename': BASE_DIR / 'logs' / 'django.log',
113                'maxBytes': 1024 * 1024 * 10,  # 10 MB
114                'backupCount': 5,
115                'formatter': 'verbose',
116            },
117            'console': {
118                'level': 'INFO',
119                'class': 'logging.StreamHandler',
120                'formatter': 'simple',
121            },
122        },
123        'loggers': {
124            'django': {
125                'handlers': ['file', 'console'],
126                'level': 'INFO',
127                'propagate': False,
128            },
129            'django.db.backends': {
130                'handlers': ['file'],
131                'level': 'WARNING',
132                'propagate': False,
133            },
134            'myapp': {
135                'handlers': ['file', 'console'],
136                'level': 'INFO',
137                'propagate': False,
138            },
139        },
140        'root': {
141            'handlers': ['console'],
142            'level': 'WARNING',
143        },
144    }

Настройка email

Настрой отправку email для production:

 1# Email настройки
 2    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
 3    EMAIL_HOST = os.environ.get('EMAIL_HOST', 'smtp.gmail.com')
 4    EMAIL_PORT = int(os.environ.get('EMAIL_PORT', 587))
 5    EMAIL_USE_TLS = True
 6    EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
 7    EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')
 8    EMAIL_USE_SSL = False
 9
10    # Настройки по умолчанию
11    DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL', 'noreply@yourdomain.com')
12    SERVER_EMAIL = os.environ.get('SERVER_EMAIL', 'server@yourdomain.com')
13
14    # Админы для получения ошибок
15    ADMINS = [
16        ('Admin Name', 'admin@yourdomain.com'),
17    ]
18
19    # Менеджеры для получения 404 ошибок
20    MANAGERS = ADMINS

Настройка Celery для фоновых задач

Настрой Celery для production:

 1# Celery настройки
 2    CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://localhost:6379/0')
 3    CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', 'redis://localhost:6379/0')
 4
 5    # Настройки производительности
 6    CELERY_WORKER_CONCURRENCY = int(os.environ.get('CELERY_WORKER_CONCURRENCY', 4))
 7    CELERY_TASK_ACKS_LATE = True
 8    CELERY_WORKER_PREFETCH_MULTIPLIER = 1
 9    CELERY_TASK_REJECT_ON_WORKER_LOST = True
10
11    # Мониторинг задач
12    CELERY_TASK_SOFT_TIME_LIMIT = 300  # 5 минут
13    CELERY_TASK_TIME_LIMIT = 600       # 10 минут
14
15    # Роутинг задач
16    CELERY_TASK_ROUTES = {
17        'myapp.tasks.*': {'queue': 'default'},
18        'myapp.tasks.heavy_tasks.*': {'queue': 'heavy'},
19        'myapp.tasks.email_tasks.*': {'queue': 'email'},
20    }
21
22    # Очереди
23    CELERY_TASK_DEFAULT_QUEUE = 'default'
24    CELERY_TASK_DEFAULT_EXCHANGE = 'default'
25    CELERY_TASK_DEFAULT_ROUTING_KEY = 'default'

Настройка мониторинга Sentry

Интегрируй Sentry для отслеживания ошибок:

 1import sentry_sdk
 2    from sentry_sdk.integrations.django import DjangoIntegration
 3    from sentry_sdk.integrations.redis import RedisIntegration
 4    from sentry_sdk.integrations.celery import CeleryIntegration
 5
 6    # Sentry настройки
 7    SENTRY_DSN = os.environ.get('SENTRY_DSN')
 8    if SENTRY_DSN:
 9        sentry_sdk.init(
10            dsn=SENTRY_DSN,
11            integrations=[
12                DjangoIntegration(),
13                RedisIntegration(),
14                CeleryIntegration(),
15            ],
16            traces_sample_rate=0.1,  # 10% запросов
17            profiles_sample_rate=0.1,
18            environment=os.environ.get('ENVIRONMENT', 'production'),
19            release=os.environ.get('GIT_COMMIT_SHA', 'unknown'),
20            before_send=lambda event, hint: event,
21)

Настройка Gunicorn

Создай файл gunicorn.conf.py:

 1import multiprocessing
 2import os
 3
 4# Базовые настройки
 5bind = os.environ.get('GUNICORN_BIND', '0.0.0.0:8000')
 6workers = int(os.environ.get('GUNICORN_WORKERS', multiprocessing.cpu_count() * 2 + 1))
 7worker_class = os.environ.get('GUNICORN_WORKER_CLASS', 'sync')
 8worker_connections = int(os.environ.get('GUNICORN_WORKER_CONNECTIONS', 1000))
 9
10# Таймауты
11timeout = int(os.environ.get('GUNICORN_TIMEOUT', 30))
12keepalive = int(os.environ.get('GUNICORN_KEEPALIVE', 2))
13graceful_timeout = int(os.environ.get('GUNICORN_GRACEFUL_TIMEOUT', 30))
14
15# Логирование
16accesslog = os.environ.get('GUNICORN_ACCESS_LOG', '-')
17errorlog = os.environ.get('GUNICORN_ERROR_LOG', '-')
18loglevel = os.environ.get('GUNICORN_LOG_LEVEL', 'info')
19
20# Безопасность
21limit_request_line = 4094
22limit_request_fields = 100
23limit_request_field_size = 8190
24
25# Производительность
26max_requests = int(os.environ.get('GUNICORN_MAX_REQUESTS', 1000))
27max_requests_jitter = int(os.environ.get('GUNICORN_MAX_REQUESTS_JITTER', 100))
28preload_app = True
29
30# Мониторинг
31statsd_host = os.environ.get('STATSD_HOST', 'localhost:8125')
32statsd_prefix = os.environ.get('STATSD_PREFIX', 'gunicorn')

Docker конфигурация

Создай Dockerfile для production:

 1# Используй официальный Python образ
 2FROM python:3.11-slim
 3
 4# Установи системные зависимости
 5RUN apt-get update && apt-get install -y \
 6    gcc \
 7    postgresql-client \
 8    && rm -rf /var/lib/apt/lists/*
 9
10# Создай пользователя для безопасности
11RUN useradd --create-home --shell /bin/bash app
12
13# Установи рабочую директорию
14WORKDIR /app
15
16# Скопируй requirements
17COPY requirements.txt .
18
19# Установи Python зависимости
20RUN pip install --no-cache-dir -r requirements.txt
21
22# Скопируй код приложения
23COPY . .
24
25# Создай директории для логов и статики
26RUN mkdir -p logs staticfiles media && \
27    chown -R app:app logs staticfiles media
28
29# Переключись на пользователя app
30USER app
31
32# Собери статические файлы
33RUN python manage.py collectstatic --noinput
34
35# Открой порт
36EXPOSE 8000
37
38# Запусти приложение
39CMD ["gunicorn", "--config", "gunicorn.conf.py", "project.wsgi:application"]

Docker Compose для production

Создай docker-compose.prod.yml:

 1version: '3.8'
 2
 3      services:
 4        web:
 5          build: .
 6          restart: unless-stopped
 7          ports:
 8            - "8000:8000"
 9          environment:
10            - ENVIRONMENT=production
11            - SECRET_KEY=${SECRET_KEY}
12            - ALLOWED_HOSTS=${ALLOWED_HOSTS}
13            - DB_NAME=${DB_NAME}
14            - DB_USER=${DB_USER}
15            - DB_PASSWORD=${DB_PASSWORD}
16            - DB_HOST=db
17            - REDIS_URL=redis://redis:6379/1
18            - CELERY_BROKER_URL=redis://redis:6379/0
19            - CELERY_RESULT_BACKEND=redis://redis:6379/0
20            - SENTRY_DSN=${SENTRY_DSN}
21          depends_on:
22            - db
23            - redis
24          volumes:
25            - static_volume:/app/staticfiles
26            - media_volume:/app/media
27            - ./logs:/app/logs
28          networks:
29            - app_network
30
31        db:
32          image: postgres:15
33          restart: unless-stopped
34          environment:
35            - POSTGRES_DB=${DB_NAME}
36            - POSTGRES_USER=${DB_USER}
37            - POSTGRES_PASSWORD=${DB_PASSWORD}
38          volumes:
39            - postgres_data:/var/lib/postgresql/data
40          networks:
41            - app_network
42
43        redis:
44          image: redis:7-alpine
45          restart: unless-stopped
46          command: redis-server --appendonly yes
47          volumes:
48            - redis_data:/data
49          networks:
50            - app_network
51
52        celery:
53          build: .
54          restart: unless-stopped
55          command: celery -A project worker -l info
56          environment:
57            - ENVIRONMENT=production
58            - DB_NAME=${DB_NAME}
59            - DB_USER=${DB_USER}
60            - DB_PASSWORD=${DB_PASSWORD}
61            - DB_HOST=db
62            - REDIS_URL=redis://redis:6379/1
63            - CELERY_BROKER_URL=redis://redis:6379/0
64            - CELERY_RESULT_BACKEND=redis://redis:6379/0
65          depends_on:
66            - db
67            - redis
68          volumes:
69            - ./logs:/app/logs
70          networks:
71            - app_network
72
73        nginx:
74          image: nginx:alpine
75          restart: unless-stopped
76          ports:
77            - "80:80"
78            - "443:443"
79          volumes:
80            - ./nginx.conf:/etc/nginx/nginx.conf
81            - ./ssl:/etc/nginx/ssl
82            - static_volume:/app/staticfiles
83            - media_volume:/app/media
84          depends_on:
85            - web
86          networks:
87            - app_network
88
89      volumes:
90        postgres_data:
91        redis_data:
92        static_volume:
93        media_volume:
94
95      networks:
96        app_network:
97          driver: bridge

Nginx конфигурация

Создай nginx.conf:

  1events {
  2          worker_connections 1024;
  3      }
  4
  5http {
  6    include /etc/nginx/mime.types;
  7    default_type application/octet-stream;
  8
  9    # Логирование
 10    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 11                    '$status $body_bytes_sent "$http_referer" '
 12                    '"$http_user_agent" "$http_x_forwarded_for"';
 13
 14    access_log /var/log/nginx/access.log main;
 15    error_log /var/log/nginx/error.log warn;
 16
 17    # Основные настройки
 18    sendfile on;
 19    tcp_nopush on;
 20    tcp_nodelay on;
 21    keepalive_timeout 65;
 22    types_hash_max_size 2048;
 23    client_max_body_size 100M;
 24
 25    # Gzip сжатие
 26    gzip on;
 27    gzip_vary on;
 28    gzip_min_length 1024;
 29    gzip_proxied any;
 30    gzip_comp_level 6;
 31    gzip_types
 32        text/plain
 33        text/css
 34        text/xml
 35        text/javascript
 36        application/json
 37        application/javascript
 38        application/xml+rss
 39        application/atom+xml
 40        image/svg+xml;
 41
 42    # Upstream для Django
 43    upstream django {
 44        server web:8000;
 45    }
 46
 47    # HTTP -> HTTPS редирект
 48    server {
 49        listen 80;
 50        server_name _;
 51        return 301 https://$host$request_uri;
 52    }
 53
 54    # HTTPS сервер
 55    server {
 56        listen 443 ssl http2;
 57        server_name yourdomain.com;
 58
 59        # SSL сертификаты
 60        ssl_certificate /etc/nginx/ssl/cert.pem;
 61        ssl_certificate_key /etc/nginx/ssl/key.pem;
 62        ssl_protocols TLSv1.2 TLSv1.3;
 63        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
 64        ssl_prefer_server_ciphers off;
 65        ssl_session_cache shared:SSL:10m;
 66        ssl_session_timeout 10m;
 67
 68        # Безопасность
 69        add_header X-Frame-Options DENY;
 70        add_header X-Content-Type-Options nosniff;
 71        add_header X-XSS-Protection "1; mode=block";
 72        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
 73
 74        # Статические файлы
 75        location /static/ {
 76            alias /app/staticfiles/;
 77            expires 1y;
 78            add_header Cache-Control "public, immutable";
 79            access_log off;
 80        }
 81
 82        # Медиа файлы
 83        location /media/ {
 84            alias /app/media/;
 85            expires 1y;
 86            add_header Cache-Control "public";
 87            access_log off;
 88        }
 89
 90        # Django приложение
 91        location / {
 92            proxy_pass http://django;
 93            proxy_set_header Host $host;
 94            proxy_set_header X-Real-IP $remote_addr;
 95            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 96            proxy_set_header X-Forwarded-Proto $scheme;
 97            proxy_redirect off;
 98            proxy_connect_timeout 30s;
 99            proxy_send_timeout 30s;
100            proxy_read_timeout 30s;
101        }
102
103        # Health check
104        location /health/ {
105            access_log off;
106            return 200 "healthy\n";
107            add_header Content-Type text/plain;
108        }
109    }
110}

Переменные окружения

Создай файл .env.production:

 1# Django настройки
 2ENVIRONMENT=production
 3SECRET_KEY=your-super-secret-key-here
 4ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
 5DEBUG=False
 6
 7# База данных
 8DB_NAME=django_prod
 9DB_USER=django_user
10DB_PASSWORD=strong_password_here
11DB_HOST=localhost
12DB_PORT=5432
13
14# Redis
15REDIS_URL=redis://localhost:6379/1
16CELERY_BROKER_URL=redis://localhost:6379/0
17CELERY_RESULT_BACKEND=redis://localhost:6379/0
18
19# Email
20EMAIL_HOST=smtp.gmail.com
21EMAIL_PORT=587
22EMAIL_HOST_USER=your-email@gmail.com
23EMAIL_HOST_PASSWORD=your-app-password
24DEFAULT_FROM_EMAIL=noreply@yourdomain.com
25SERVER_EMAIL=server@yourdomain.com
26
27# Sentry
28SENTRY_DSN=https://your-sentry-dsn-here
29
30# Gunicorn
31GUNICORN_WORKERS=4
32GUNICORN_TIMEOUT=30
33GUNICORN_MAX_REQUESTS=1000
34
35# Celery
36CELERY_WORKER_CONCURRENCY=4
37
38# CSRF
39CSRF_TRUSTED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com

Скрипты развертывания

Создай скрипт для автоматического развертывания:

 1#!/bin/bash
 2# deploy.sh
 3
 4set -e
 5
 6echo "🚀 Начинаем развертывание..."
 7
 8# Обновляем код
 9echo "📥 Обновляем код..."
10git pull origin main
11
12# Активируем виртуальное окружение
13echo "🐍 Активируем Python окружение..."
14source venv/bin/activate
15
16# Устанавливаем зависимости
17echo "📦 Устанавливаем зависимости..."
18pip install -r requirements.txt
19
20# Применяем миграции
21echo "🗄️ Применяем миграции..."
22python manage.py migrate --noinput
23
24# Собираем статические файлы
25echo "📁 Собираем статические файлы..."
26python manage.py collectstatic --noinput
27
28# Перезапускаем сервисы
29echo "🔄 Перезапускаем сервисы..."
30sudo systemctl restart gunicorn
31sudo systemctl restart celery
32sudo systemctl restart nginx
33
34# Проверяем статус
35echo "✅ Проверяем статус сервисов..."
36sudo systemctl status gunicorn
37sudo systemctl status celery
38sudo systemctl status nginx
39
40echo "🎉 Развертывание завершено!"

Мониторинг и логирование

Настрой мониторинг production окружения:

 1# settings/production.py - добавь в конец
 2
 3# Мониторинг производительности
 4if os.environ.get('ENABLE_PROFILING'):
 5    MIDDLEWARE.append('django_profiler.middleware.ProfilerMiddleware')
 6    PROFILER = {
 7        'enabled': True,
 8        'storage': 'django_profiler.storage.FileStorage',
 9        'base_dir': BASE_DIR / 'profiles',
10    }
11
12# Prometheus метрики
13if os.environ.get('ENABLE_METRICS'):
14    INSTALLED_APPS.append('django_prometheus')
15    MIDDLEWARE.insert(0, 'django_prometheus.middleware.PrometheusBeforeMiddleware')
16    MIDDLEWARE.append('django_prometheus.middleware.PrometheusAfterMiddleware')
17
18# Health check endpoint
19HEALTH_CHECK = {
20    'DISK_USAGE_MAX': 90,  # Процент использования диска
21    'MEMORY_MIN': 100,     # Минимум свободной памяти в MB
22}

Тестирование production настроек

Создай тесты для проверки production конфигурации:

 1from django.test import TestCase, override_settings
 2from django.conf import settings
 3from django.core.cache import cache
 4from django.db import connection
 5
 6class ProductionSettingsTest(TestCase):
 7    @override_settings(DEBUG=False)
 8    def test_debug_is_disabled(self):
 9        """Проверяем, что DEBUG отключен в production"""
10        self.assertFalse(settings.DEBUG)
11
12    def test_secret_key_is_set(self):
13        """Проверяем, что SECRET_KEY установлен"""
14        self.assertIsNotNone(settings.SECRET_KEY)
15        self.assertNotEqual(settings.SECRET_KEY, 'your-secret-key-here')
16
17    def test_allowed_hosts_configured(self):
18        """Проверяем, что ALLOWED_HOSTS настроен"""
19        self.assertIsNotNone(settings.ALLOWED_HOSTS)
20        self.assertNotEqual(settings.ALLOWED_HOSTS, [])
21
22    def test_ssl_redirect_enabled(self):
23        """Проверяем, что SSL редирект включен"""
24        self.assertTrue(settings.SECURE_SSL_REDIRECT)
25
26    def test_csrf_cookies_secure(self):
27        """Проверяем, что CSRF куки защищены"""
28        self.assertTrue(settings.CSRF_COOKIE_SECURE)
29
30    def test_session_cookies_secure(self):
31        """Проверяем, что сессионные куки защищены"""
32        self.assertTrue(settings.SESSION_COOKIE_SECURE)
33
34    def test_database_connection(self):
35        """Проверяем подключение к базе данных"""
36        with connection.cursor() as cursor:
37            cursor.execute("SELECT 1")
38            result = cursor.fetchone()
39            self.assertEqual(result[0], 1)
40
41    def test_cache_connection(self):
42        """Проверяем подключение к кэшу"""
43        cache.set('test_key', 'test_value', 1)
44        self.assertEqual(cache.get('test_key'), 'test_value')

Лучшие практики production

  • Безопасность: Всегда используй HTTPS, валидируй входные данные, обновляй зависимости
  • Производительность: Кэшируй статику, используй CDN, оптимизируй запросы к БД
  • Мониторинг: Настрой логирование, метрики, алерты для критических ошибок
  • Резервное копирование: Автоматизируй бэкапы БД и файлов
  • Масштабирование: Используй балансировщики нагрузки, горизонтальное масштабирование
  • CI/CD: Автоматизируй тестирование и развертывание
  • Документация: Веди документацию по развертыванию и настройкам
  • Тестирование: Тестируй production настройки в staging окружении

Частые ошибки и их решения

Ошибка: "SECRET_KEY not set"

Решение: Убедись, что переменная окружения SECRET_KEY установлена

Ошибка: "ALLOWED_HOSTS not configured"

Решение: Настрой ALLOWED_HOSTS с правильными доменами

Ошибка: "Database connection failed"

Решение: Проверь настройки БД и доступность PostgreSQL

Ошибка: "Static files not found"

Решение: Запусти collectstatic и проверь STATIC_ROOT

Ошибка: "Permission denied"

Решение: Проверь права доступа к файлам и директориям

FAQ

Q: Как собрать статические файлы для production?
A: Используй python manage.py collectstatic --noinput и настрой STATIC_ROOT в настройках.

Q: Нужно ли использовать виртуальное окружение в production?
A: Да, это изолирует зависимости проекта и предотвращает конфликты версий.

Q: Как мониторить производительность Django в production?
A: Используй Sentry для ошибок, Prometheus для метрик, и настрой логирование.

Q: Можно ли использовать SQLite в production?
A: Нет, SQLite не подходит для production. Используй PostgreSQL или MySQL.

Q: Как настроить автоматические бэкапы?
A: Используй cron для регулярных бэкапов БД и rsync для файлов.

Q: Нужно ли использовать Docker в production?
A: Docker упрощает развертывание и обеспечивает консистентность окружений.