Files

347 lines
11 KiB
Markdown

# Развёртывание Social Graph на сервере
Инструкция для Linux-сервера (Ubuntu/Debian). Приложение публикуется через Docker; снаружи доступен только веб-прокси (80/443).
> **Production:** [deploy/social.deepfishing.ru.md](./social.deepfishing.ru.md) — инструкция для https://social.deepfishing.ru
## Схема
```text
Интернет :80 / :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 на сервере, общая БД | обязателен |
Режим задаётся при **сборке** фронтенда (`VITE_DATA_MODE`).
---
## 1. Требования к серверу
- Linux (Ubuntu 22.04+ / Debian 12+)
- Docker Engine + Docker Compose plugin
- Git
- Домен, указывающий на IP сервера (для HTTPS)
- Apache2 **или** nginx на хосте (reverse proxy)
Установка Docker (если ещё нет):
```bash
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
# перелогиньтесь, чтобы группа docker применилась
docker compose version
```
---
## 2. Клонирование проекта
```bash
sudo mkdir -p /opt/social-graph
sudo chown "$USER:$USER" /opt/social-graph
git clone <URL-репозитория> /opt/social-graph
cd /opt/social-graph
git checkout main # или нужная ветка
```
---
## 3. Конфигурация окружения
```bash
cp deploy/.env.prod.example deploy/.env.prod
nano deploy/.env.prod
```
### Вариант A — local-first (данные только в браузере)
Подходит, если сервер — просто «хостинг интерфейса», без общей базы.
```env
VITE_DATA_MODE=local
FRONTEND_BIND=127.0.0.1
FRONTEND_PORT=8080
```
Backend **не поднимается**. Каждый пользователь хранит данные локально; при смене браузера или устройства данные не переносятся автоматически (экспорт/импорт — через UI → Импорт).
### Вариант B — 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=your-domain.com,www.your-domain.com
USE_JWT_AUTH=true
```
Сгенерировать секретный ключ:
```bash
python3 -c "import secrets; print(secrets.token_urlsafe(50))"
```
Файл `deploy/.env.prod` **не коммитить** — в нём секреты.
---
## 4. Сборка и запуск контейнеров
Перейдите в каталог проекта:
```bash
cd /opt/social-graph
```
### Только frontend (режим local)
```bash
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
```
### Frontend + backend (режим remote)
```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 up -d --build frontend
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d --build backend
```
Проверка:
```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/
```
Ожидается `200` (backend в режиме remote с JWT может вернуть `401` без токена — это нормально, главное не `502`).
Логи:
```bash
docker logs sg_frontend --tail 50
docker logs sg_backend --tail 50
```
> **Конфликт с dev:** если в том же каталоге запускали `docker compose up`, сначала выполните `docker compose down`.
---
## 5. Прокси на хосте
Контейнеры слушают только `127.0.0.1`. Наружу открывается прокси.
### Apache2
```bash
sudo apt install apache2
sudo a2enmod proxy proxy_http headers rewrite
sudo cp deploy/apache/social-graph.conf /etc/apache2/sites-available/social-graph.conf
sudo nano /etc/apache2/sites-available/social-graph.conf
```
Измените `ServerName` / `ServerAlias` на ваш домен.
**При `VITE_DATA_MODE=remote`** раскомментируйте блок API **выше** блока frontend:
```apache
ProxyPass /api http://127.0.0.1:8000/api
ProxyPassReverse /api http://127.0.0.1:8000/api
```
Включите сайт:
```bash
sudo a2ensite social-graph.conf
sudo a2dissite 000-default.conf # опционально
sudo apache2ctl configtest
sudo systemctl reload apache2
```
HTTPS:
```bash
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d your-domain.com -d www.your-domain.com
```
### nginx на хосте
```bash
sudo apt install nginx
sudo cp deploy/proxy/nginx-host.conf.example /etc/nginx/sites-available/social-graph
sudo nano /etc/nginx/sites-available/social-graph
```
Укажите `server_name` и при remote-режиме раскомментируйте `location /api/`.
```bash
sudo ln -s /etc/nginx/sites-available/social-graph /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
HTTPS:
```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
```
---
## 6. Первый вход (режим remote)
1. Откройте `https://your-domain.com`
2. Перейдите на **Регистрация** (`/register`) и создайте аккаунт
3. Либо войдите под существующим пользователем
Если на сервере уже есть данные от пользователя `legacy` (миграция), задайте ему пароль:
```bash
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()
```
---
## 7. Обновление версии
```bash
cd /opt/social-graph
git pull
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
# при remote:
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
```
При изменении `VITE_DATA_MODE` нужна **пересборка** frontend (`--build`).
---
## 8. Резервное копирование (remote)
База — SQLite в Docker volume `sqlite_data`.
```bash
docker compose -f docker-compose.prod.yml --profile with-backend exec backend \
python manage.py dumpdata contacts --indent 2 > backup-contacts-$(date +%F).json
```
Полный дамп через UI: **Импорт** → экспорт бэкапа (если включён в интерфейсе).
Копия файла БД (осторожно — только при остановленном 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.sqlite3-$(date +%F)
docker compose -f docker-compose.prod.yml --profile with-backend start backend
```
---
## 9. Порты и безопасность
| Переменная | По умолчанию | Назначение |
|------------|--------------|------------|
| `FRONTEND_PORT` | 8080 | nginx в контейнере |
| `BACKEND_PORT` | 8000 | gunicorn |
| `FRONTEND_BIND` | 127.0.0.1 | только localhost |
Рекомендуется:
```bash
sudo ufw allow OpenSSH
sudo ufw allow 'Apache Full' # или 'Nginx Full'
sudo ufw enable
```
Порты 8080 и 8000 **не** открывать наружу — только через прокси.
---
## 10. Устранение неполадок
| Симптом | Что проверить |
|---------|----------------|
| 502 Bad Gateway | Контейнеры запущены? `docker ps`, логи `sg_frontend` / `sg_backend` |
| Белая страница после деплоя | Пересобран frontend? `VITE_DATA_MODE` совпадает с ожиданиями |
| API не отвечает в remote | Раскомментирован `ProxyPass /api` в Apache/nginx; backend в profile `with-backend` |
| «Сессия истекла» / 401 | `USE_JWT_AUTH=true` на backend; перелогин |
| Данные не общие между ПК | Нужен `VITE_DATA_MODE=remote`, не `local` |
Полезные команды:
```bash
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. Краткая шпаргалка
**Local (только UI):**
```bash
cd /opt/social-graph
cp deploy/.env.prod.example deploy/.env.prod # VITE_DATA_MODE=local
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
# настроить Apache/nginx → 127.0.0.1:8080
```
**Remote (серверная БД + авторизация):**
```bash
cd /opt/social-graph
cp deploy/.env.prod.example deploy/.env.prod
# VITE_DATA_MODE=remote, DJANGO_SECRET_KEY, ALLOWED_HOSTS, USE_JWT_AUTH=true
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
# прокси: / → :8080, /api → :8000
```
Дополнительно: [README.md](../README.md), разработка — `docker compose up --build` (порты 5173 и 8000).