# Развёртывание Social Graph на [social.deepfishing.ru](https://social.deepfishing.ru) Инструкция для production-сервера **social.deepfishing.ru**. Приложение публикуется через Docker; снаружи доступен только веб-прокси (80/443). **Адрес приложения:** https://social.deepfishing.ru --- ## Схема ```text https://social.deepfishing.ru (:443) ↓ Прокси на хосте (Apache или nginx) ↓ ┌───────────────────────────────────────┐ │ frontend-контейнер (nginx) │ │ 127.0.0.1:8080 → SPA + статика │ └───────────────────────────────────────┘ ↓ (режим remote) ┌───────────────────────────────────────┐ │ backend-контейнер (gunicorn) │ │ 127.0.0.1:8000 → Django API │ │ SQLite в Docker volume │ └───────────────────────────────────────┘ ``` | Режим | Где данные | Backend | |-------|------------|---------| | **local** | IndexedDB в браузере | не нужен | | **remote** | SQLite на сервере | обязателен | Для **social.deepfishing.ru** рекомендуется **remote** + `USE_JWT_AUTH=true` (регистрация, вход, общая база). --- ## 1. Требования - Linux (Ubuntu 22.04+ / Debian 12+) - Docker Engine + Docker Compose - Git - DNS: запись **A** (или **AAAA**) `social.deepfishing.ru` → IP сервера - Apache2 **или** nginx на хосте Установка Docker: ```bash curl -fsSL https://get.docker.com | sh sudo usermod -aG docker "$USER" # перелогиньтесь docker compose version ``` --- ## 2. Клонирование ```bash sudo mkdir -p /opt/social-graph sudo chown "$USER:$USER" /opt/social-graph git clone /opt/social-graph cd /opt/social-graph git checkout main ``` --- ## 3. Конфигурация `deploy/.env.prod` ```bash cd /opt/social-graph cp deploy/.env.prod.example deploy/.env.prod nano deploy/.env.prod ``` ### Рекомендуемый конфиг для social.deepfishing.ru (remote) ```env VITE_DATA_MODE=remote FRONTEND_BIND=127.0.0.1 FRONTEND_PORT=8080 BACKEND_BIND=127.0.0.1 BACKEND_PORT=8000 DJANGO_SECRET_KEY=<сгенерируйте-длинную-случайную-строку> ALLOWED_HOSTS=social.deepfishing.ru USE_JWT_AUTH=true ``` Сгенерировать `DJANGO_SECRET_KEY`: ```bash python3 -c "import secrets; print(secrets.token_urlsafe(50))" ``` ### Альтернатива — только UI (local) Если backend не нужен, данные останутся в браузере каждого пользователя: ```env VITE_DATA_MODE=local FRONTEND_BIND=127.0.0.1 FRONTEND_PORT=8080 ``` Файл `deploy/.env.prod` **не коммитить**. --- ## 4. Запуск контейнеров ```bash cd /opt/social-graph ``` ### Remote (frontend + backend) > Обязательно: `VITE_DATA_MODE=remote` в `.env.prod` и профиль `with-backend` — иначе вход/регистрация не работают (ошибка 405). ```bash docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod build docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d --build ``` Команда поднимает **оба** контейнера. Frontend в remote-сборке проксирует `/api` → backend внутри Docker. ### Только frontend (local) ```bash docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend ``` ### Проверка на сервере ```bash docker compose -f docker-compose.prod.yml ps curl -s -o /dev/null -w "frontend: %{http_code}\n" http://127.0.0.1:8080/ curl -s -o /dev/null -w "backend: %{http_code}\n" http://127.0.0.1:8000/api/v1/meta/choices/ curl -s -o /dev/null -w "public: %{http_code}\n" https://social.deepfishing.ru/ ``` Логи: ```bash docker logs sg_frontend --tail 50 docker logs sg_backend --tail 50 ``` > Перед prod-запуском остановите dev-контейнеры: `docker compose down` --- ## 5. Прокси на хосте Контейнеры слушают **только** `127.0.0.1`. Снаружи — прокси на 80/443. ### Apache2 ```bash sudo apt install apache2 sudo a2enmod proxy proxy_http headers rewrite ssl sudo cp deploy/apache/social-graph.conf /etc/apache2/sites-available/social-graph.conf sudo nano /etc/apache2/sites-available/social-graph.conf ``` Пример VirtualHost: ```apache ServerName social.deepfishing.ru ProxyPreserveHost On RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s # API (режим remote) ProxyPass /api http://127.0.0.1:8000/api ProxyPassReverse /api http://127.0.0.1:8000/api # Frontend SPA ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ ErrorLog ${APACHE_LOG_DIR}/social-graph-error.log CustomLog ${APACHE_LOG_DIR}/social-graph-access.log combined ``` ```bash sudo a2ensite social-graph.conf sudo a2dissite 000-default.conf sudo apache2ctl configtest sudo systemctl reload apache2 ``` HTTPS (Let's Encrypt): ```bash sudo apt install certbot python3-certbot-apache sudo certbot --apache -d social.deepfishing.ru ``` После certbot сайт будет доступен по https://social.deepfishing.ru . ### nginx на хосте ```bash sudo apt install nginx sudo nano /etc/nginx/sites-available/social-graph ``` ```nginx server { listen 80; server_name social.deepfishing.ru; location /api/ { proxy_pass http://127.0.0.1:8000/api/; 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; } location / { proxy_pass http://127.0.0.1:8080; 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; } } ``` ```bash sudo ln -s /etc/nginx/sites-available/social-graph /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx sudo certbot --nginx -d social.deepfishing.ru ``` --- ## 6. Первый вход 1. Откройте https://social.deepfishing.ru 2. **Регистрация:** https://social.deepfishing.ru/register 3. Или **вход:** https://social.deepfishing.ru/login Если на сервере есть пользователь `legacy` (данные после миграции), задайте пароль: ```bash cd /opt/social-graph docker compose -f docker-compose.prod.yml --profile with-backend exec backend python manage.py shell ``` ```python from django.contrib.auth import get_user_model User = get_user_model() u = User.objects.get(username='legacy') u.set_password('ваш-надёжный-пароль') u.save() exit() ``` Вход: https://social.deepfishing.ru/login → логин `legacy`. --- ## 7. Обновление ```bash cd /opt/social-graph git pull docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d --build backend sudo systemctl reload apache2 # или: sudo nginx -s reload ``` Проверка: https://social.deepfishing.ru --- ## 8. Резервное копирование ```bash cd /opt/social-graph docker compose -f docker-compose.prod.yml --profile with-backend exec backend \ python manage.py dumpdata contacts --indent 2 \ > backup-social-deepfishing-$(date +%F).json ``` Копия SQLite (backend должен быть остановлен): ```bash docker compose -f docker-compose.prod.yml --profile with-backend stop backend docker run --rm -v social-graph_sqlite_data:/data -v "$PWD":/backup alpine \ cp /data/db.sqlite3 /backup/db-social-deepfishing-$(date +%F).sqlite3 docker compose -f docker-compose.prod.yml --profile with-backend start backend ``` --- ## 9. Безопасность ```bash sudo ufw allow OpenSSH sudo ufw allow 'Apache Full' # или 'Nginx Full' sudo ufw enable ``` | Порт | Доступ | |------|--------| | 443, 80 | открыт (прокси) | | 8080, 8000 | только 127.0.0.1 | --- ## 10. Устранение неполадок | Симптом | Решение | |---------|---------| | **405 Not Allowed** при входе/регистрации | Запросы `/api` попали во frontend вместо backend. Пересоберите с `VITE_DATA_MODE=remote` (в образе включится `nginx.remote.conf`) **и** поднимите backend: `--profile with-backend` | | 502 на https://social.deepfishing.ru | `docker ps`, логи `sg_frontend` / `sg_backend` | | Страница открывается, API 404 | Backend не запущен или нет прокси `/api` | | 401 / не пускает | `USE_JWT_AUTH=true` в `.env.prod`, пересобрать backend | | Данные не сохраняются между устройствами | `VITE_DATA_MODE=remote`, пересобрать frontend | | Белый экран | `docker logs sg_frontend`, пересборка с `--build` | ```bash cd /opt/social-graph docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod ps docker logs sg_frontend --tail 100 docker logs sg_backend --tail 100 docker compose -f docker-compose.prod.yml --profile with-backend exec backend python manage.py migrate ``` --- ## 11. Шпаргалка (social.deepfishing.ru, remote) ```bash cd /opt/social-graph cp deploy/.env.prod.example deploy/.env.prod # ALLOWED_HOSTS=social.deepfishing.ru # VITE_DATA_MODE=remote # USE_JWT_AUTH=true # DJANGO_SECRET_KEY=... docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod build docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d --build backend # Apache: ServerName social.deepfishing.ru # ProxyPass /api → 127.0.0.1:8000 # ProxyPass / → 127.0.0.1:8080 # certbot --apache -d social.deepfishing.ru ``` **Проверка:** https://social.deepfishing.ru