Files
smartsoltech_site/DEPLOYMENT_GUIDE.md
Andrew K. Choi a2317bc619 🔧 Fix manage.py path in deployment scripts
- Changed 'python manage.py' to 'python smartsoltech/manage.py' in all deployment scripts
- Fixed deploy.sh, quick-deploy.sh
- Updated DEPLOYMENT_GUIDE.md and DEPLOYMENT_SCRIPTS.md documentation
- Added SERVER_FIX.md with instructions for server fix

Fixes issue: python: can't open file '/app/manage.py': [Errno 2] No such file or directory
2025-11-24 11:38:11 +09:00

16 KiB
Raw Blame History

🚀 Руководство по развертыванию SmartSolTech на продакшн

📋 Предварительные требования

На продакшн сервере должно быть установлено:

  • Ubuntu 20.04/22.04 или Debian 11/12
  • Docker 24.0+
  • Docker Compose 2.0+
  • Nginx (для reverse proxy)
  • Certbot (для SSL сертификатов)
  • Git

🔧 Шаг 1: Подготовка сервера

1.1 Обновление системы

sudo apt update && sudo apt upgrade -y

1.2 Установка Docker

# Установка Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Добавление пользователя в группу docker
sudo usermod -aG docker $USER
newgrp docker

# Проверка установки
docker --version
docker compose version

1.3 Установка Nginx и Certbot

sudo apt install nginx certbot python3-certbot-nginx -y

1.4 Настройка firewall

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

📦 Шаг 2: Клонирование проекта

# Создание директории для проекта
sudo mkdir -p /var/www/smartsoltech.kr
sudo chown $USER:$USER /var/www/smartsoltech.kr

# Клонирование репозитория
cd /var/www/smartsoltech.kr
git clone https://github.com/your-username/smartsoltech.kr.git .

# Или загрузка через SCP/SFTP

🔐 Шаг 3: Настройка переменных окружения

3.1 Создание .env файла

cd /var/www/smartsoltech.kr
cp .env.example .env
nano .env

3.2 Настройка .env для продакшена

# Django Settings
SECRET_KEY=GENERATE_NEW_SECRET_KEY_HERE_MINIMUM_50_CHARACTERS
DEBUG=False
ALLOWED_HOSTS=localhost,127.0.0.1,smartsoltech.kr,www.smartsoltech.kr
CSRF_TRUSTED_ORIGINS=https://smartsoltech.kr,https://www.smartsoltech.kr

# PostgreSQL Database
POSTGRES_DB=smartsoltech_db
POSTGRES_USER=smartsoltech_user
POSTGRES_PASSWORD=STRONG_PASSWORD_HERE
POSTGRES_HOST=postgres_db

# PgAdmin (опционально, можно отключить в проде)
PGADMIN_DEFAULT_EMAIL=admin@smartsoltech.kr
PGADMIN_DEFAULT_PASSWORD=ANOTHER_STRONG_PASSWORD

# Zabbix Agent
ZBX_SERVER_HOST=your-zabbix-server-ip

# Telegram Bot (настраивается через админку)
# TELEGRAM_BOT_TOKEN=your-bot-token-from-botfather

# Email Settings (настраивается через админку)
# SMTP_SERVER=smtp.gmail.com
# SMTP_PORT=587
# SENDER_EMAIL=your-email@gmail.com

3.3 Генерация нового SECRET_KEY

# На сервере запустите:
python3 -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

🐳 Шаг 4: Настройка Docker Compose для продакшена

4.1 Создание docker-compose.prod.yml

nano docker-compose.prod.yml
version: '3.8'

services:
  postgres_db:
    image: postgres:17-alpine
    container_name: postgres_db
    restart: always
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5

  django_app:
    build: .
    container_name: django_app
    restart: always
    command: >
      sh -c "python manage.py collectstatic --noinput &&
             python manage.py migrate &&
             gunicorn smartsoltech.wsgi:application --bind 0.0.0.0:8000 --workers 4 --timeout 120"
    volumes:
      - static_volume:/app/staticfiles
      - media_volume:/app/media
    environment:
      - SECRET_KEY=${SECRET_KEY}
      - DEBUG=${DEBUG}
      - ALLOWED_HOSTS=${ALLOWED_HOSTS}
      - CSRF_TRUSTED_ORIGINS=${CSRF_TRUSTED_ORIGINS}
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_HOST=${POSTGRES_HOST}
    depends_on:
      postgres_db:
        condition: service_healthy
    networks:
      - backend
    expose:
      - "8000"

  telegram_bot:
    build: .
    container_name: telegram_bot
    restart: always
    command: python manage.py run_telegram_bot
    environment:
      - SECRET_KEY=${SECRET_KEY}
      - DEBUG=${DEBUG}
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_HOST=${POSTGRES_HOST}
    depends_on:
      postgres_db:
        condition: service_healthy
    networks:
      - backend

  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - static_volume:/var/www/static:ro
      - media_volume:/var/www/media:ro
      - /etc/letsencrypt:/etc/letsencrypt:ro
      - /var/www/certbot:/var/www/certbot:ro
    depends_on:
      - django_app
    networks:
      - backend

volumes:
  postgres_data:
  static_volume:
  media_volume:

networks:
  backend:
    driver: bridge

🌐 Шаг 5: Настройка Nginx

5.1 Создание конфигурации Nginx

mkdir -p nginx/conf.d
nano nginx/conf.d/smartsoltech.conf
# Редирект с www на non-www
server {
    listen 80;
    listen [::]:80;
    server_name www.smartsoltech.kr;
    return 301 https://smartsoltech.kr$request_uri;
}

# HTTP → HTTPS редирект
server {
    listen 80;
    listen [::]:80;
    server_name smartsoltech.kr;

    # Let's Encrypt challenge
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$server_name$request_uri;
    }
}

# HTTPS конфигурация
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name smartsoltech.kr;

    # SSL сертификаты
    ssl_certificate /etc/letsencrypt/live/smartsoltech.kr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/smartsoltech.kr/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/smartsoltech.kr/chain.pem;

    # SSL настройки
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Максимальный размер загружаемых файлов
    client_max_body_size 100M;

    # Статические файлы
    location /static/ {
        alias /var/www/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Медиа файлы
    location /media/ {
        alias /var/www/media/;
        expires 7d;
        add_header Cache-Control "public";
    }

    # Django приложение
    location / {
        proxy_pass http://django_app:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_buffering off;
    }

    # Логи
    access_log /var/log/nginx/smartsoltech_access.log;
    error_log /var/log/nginx/smartsoltech_error.log;
}

5.2 Создание nginx.conf

nano nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    keepalive_timeout 65;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;
}

🔒 Шаг 6: Получение SSL сертификата

6.1 Временный запуск для получения сертификата

# Запуск только postgres и django
docker compose -f docker-compose.prod.yml up -d postgres_db django_app

# Ожидание запуска
sleep 10

# Получение сертификата
sudo certbot certonly --webroot -w /var/www/certbot \
    -d smartsoltech.kr \
    -d www.smartsoltech.kr \
    --email admin@smartsoltech.kr \
    --agree-tos \
    --no-eff-email

6.2 Настройка автообновления сертификата

# Создание cron задачи
sudo crontab -e

# Добавить строку:
0 3 * * * certbot renew --quiet --post-hook "docker exec nginx nginx -s reload"

🚀 Шаг 7: Запуск приложения

7.1 Сборка и запуск контейнеров

cd /var/www/smartsoltech.kr

# Сборка образов
docker compose -f docker-compose.prod.yml build

# Запуск контейнеров
docker compose -f docker-compose.prod.yml up -d

# Проверка статуса
docker compose -f docker-compose.prod.yml ps

7.2 Проверка логов

# Логи Django
docker logs django_app --tail 100 -f

# Логи Nginx
docker logs nginx --tail 100 -f

# Логи PostgreSQL
docker logs postgres_db --tail 100 -f

👤 Шаг 8: Создание суперпользователя

docker exec -it django_app python smartsoltech/manage.py createsuperuser

📊 Шаг 9: Настройка мониторинга (опционально)

9.1 Zabbix Agent

# Обновить в .env
ZBX_SERVER_HOST=your-zabbix-server-ip

# Перезапустить контейнеры
docker compose -f docker-compose.prod.yml restart

9.2 Логирование

# Настройка ротации логов
sudo nano /etc/logrotate.d/docker-containers

# Содержимое:
/var/lib/docker/containers/*/*.log {
  rotate 7
  daily
  compress
  missingok
  delaycompress
  copytruncate
}

🔄 Шаг 10: Обновление приложения

10.1 Скрипт для обновления

nano /var/www/smartsoltech.kr/update.sh
chmod +x /var/www/smartsoltech.kr/update.sh
#!/bin/bash
set -e

echo "🔄 Начало обновления..."

# Переход в директорию проекта
cd /var/www/smartsoltech.kr

# Получение последних изменений
git pull origin master

# Остановка контейнеров
docker compose -f docker-compose.prod.yml down

# Пересборка образов
docker compose -f docker-compose.prod.yml build

# Запуск контейнеров
docker compose -f docker-compose.prod.yml up -d

# Ожидание запуска
sleep 10

# Применение миграций
docker exec django_app python smartsoltech/manage.py migrate

# Сборка статики
docker exec django_app python smartsoltech/manage.py collectstatic --noinput

# Проверка статуса
docker compose -f docker-compose.prod.yml ps

echo "✅ Обновление завершено!"

10.2 Использование

/var/www/smartsoltech.kr/update.sh

🔍 Проверка работоспособности

Чеклист проверки:

  • Сайт доступен по https://smartsoltech.kr
  • SSL сертификат валиден
  • Редирект с HTTP на HTTPS работает
  • Редирект с www на non-www работает
  • Статические файлы загружаются
  • Админ панель доступна: /admin/
  • Все страницы открываются без ошибок
  • Формы отправляются корректно
  • Telegram бот работает
  • Email уведомления приходят

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

# Проверка SSL
curl -I https://smartsoltech.kr

# Проверка редиректов
curl -I http://smartsoltech.kr
curl -I http://www.smartsoltech.kr

# Проверка страниц
curl https://smartsoltech.kr/
curl https://smartsoltech.kr/services/
curl https://smartsoltech.kr/about/
curl https://smartsoltech.kr/blog/

🐛 Устранение неполадок

Проблема: Контейнеры не запускаются

# Проверка логов
docker compose -f docker-compose.prod.yml logs

# Пересоздание контейнеров
docker compose -f docker-compose.prod.yml down -v
docker compose -f docker-compose.prod.yml up -d

Проблема: 502 Bad Gateway

# Проверка статуса Django
docker exec django_app ps aux

# Перезапуск Django
docker compose -f docker-compose.prod.yml restart django_app

Проблема: Статические файлы не загружаются

# Пересборка статики
docker exec django_app python smartsoltech/manage.py collectstatic --noinput

# Проверка прав
docker exec nginx ls -la /var/www/static/

📱 Настройка Telegram бота

  1. Зайти в админ панель: https://smartsoltech.kr/admin/
  2. Перейти в "Настройки коммуникации" → "Telegram settings"
  3. Добавить bot token и bot name
  4. Перезапустить telegram_bot контейнер:
docker compose -f docker-compose.prod.yml restart telegram_bot

📧 Настройка Email

  1. Зайти в админ панель: https://smartsoltech.kr/admin/
  2. Перейти в "Настройки коммуникации" → "Email settings"
  3. Заполнить SMTP настройки
  4. Отправить тестовое письмо

🔐 Безопасность

Рекомендации:

  1. Регулярно обновляйте систему:

    sudo apt update && sudo apt upgrade
    
  2. Настройте fail2ban:

    sudo apt install fail2ban
    sudo systemctl enable fail2ban
    
  3. Настройте резервное копирование БД:

    # Создать скрипт backup.sh
    #!/bin/bash
    docker exec postgres_db pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > /backups/smartsoltech_$(date +%Y%m%d).sql
    
    # Добавить в crontab
    0 2 * * * /var/www/smartsoltech.kr/backup.sh
    
  4. Мониторинг логов:

    tail -f /var/log/nginx/smartsoltech_error.log
    docker logs django_app --tail 100 -f
    

📊 Производительность

Рекомендуемые настройки сервера:

  • CPU: минимум 2 ядра
  • RAM: минимум 4GB
  • Disk: минимум 40GB SSD
  • Bandwidth: минимум 100Mbps

Оптимизация Django:

  • Gunicorn workers: (2 × CPU cores) + 1
  • PostgreSQL shared_buffers: 25% от RAM
  • Nginx worker_connections: 1024

🎉 Готово!

Ваш сайт развернут и работает по адресу: https://smartsoltech.kr

Для получения помощи обратитесь к документации или проверьте логи контейнеров.