72b6879f4b
- Refactored max_bot from nested packages to flat module structure - Q2: Extended BotUser model (patronymic, email, org, address, vcf_raw, contact_hash, phone_verified, email_verified, last_interaction, total_conversations, total_tickets) - Q2: VCF parser (FN, N, TEL, EMAIL, ORG, ADR), upsert on re-contact, NLP history context (_get_user_history_context -> YandexGPT) - Q1: Broadcast preview modal with 10s confirmation timer - Q3: CSS var(--white)->var(--bg-card), var(--text)->var(--text-primary) - Q4: bot_settings showNotification(), editable max_bot_id - Q5: Webhook secret passthrough via X-Max-Bot-Api-Secret - Masking sensitive keys, dialog_cleared handler, migrate via _add_column_if_not_exists() - Rate limit (asyncio.sleep 0.5 per 10), dead code removed, conv.intent context in contact.py - Portal pages: bot_consent, bot_kb (edit), bot_settings, bot_test, bot_tickets, portal_settings - Tests: 21/21 passing, added test_yandex_gpt.py, test_email_sender.py - Deploy: deploy_full.sh, schema.sql, seed_knowledge_base.sql
1326 lines
36 KiB
Markdown
1326 lines
36 KiB
Markdown
# Инструкция по настройке VPS и миграции проектов
|
||
|
||
> **Сервер:** Ubuntu 24.04 LTS (чистая установка)
|
||
> **Цель:** Docker-инфраструктура для 3+ проектов с мультидоменом, SSL, Git-сервером и CI/CD
|
||
> **Дата:** 2026-05-17
|
||
> **Примечание:** Если при выполнении возникнут вопросы — лучше уточнить, чем переделывать потом.
|
||
|
||
---
|
||
|
||
## Содержание
|
||
|
||
1. [Подключение к VPS](#1-подключение-к-vps)
|
||
2. [Базовая настройка сервера](#2-базовая-настройка-сервера)
|
||
3. [Установка Docker и Docker Compose](#3-установка-docker-и-docker-compose)
|
||
4. [Структура директорий для мультипроекта](#4-структура-директорий-для-мультипроекта)
|
||
5. [Nginx Reverse Proxy + Let's Encrypt](#5-nginx-reverse-proxy--lets-encrypt)
|
||
6. [Gitea (Git-сервер)](#6-gitea-git-сервер)
|
||
7. [Подготовка к переносу AegisOne (PHP)](#7-подготовка-к-переносу-aegisone-php)
|
||
8. [Подготовка Python-админки (FastAPI)](#8-подготовка-python-админки-fastapi)
|
||
9. [CI/CD с Gitea Actions](#9-cicd-с-gitea-actions)
|
||
10. [Бэкапы и мониторинг](#10-бэкапы-и-мониторинг)
|
||
11. [Чек-лист завершения](#11-чек-лист-завершения)
|
||
|
||
---
|
||
|
||
## 1. Подключение к VPS
|
||
|
||
### 1.1. Получение данных для подключения
|
||
После создания VPS в панели Jino.ru вы получите:
|
||
- **IP-адрес сервера** (например, `185.100.100.50`)
|
||
- **Логин:** `root`
|
||
- **Пароль:** (указан в панели или отправлен на email)
|
||
|
||
### 1.2. Подключение через PowerShell (Windows)
|
||
```powershell
|
||
# Откройте PowerShell и выполните:
|
||
ssh root@<IP-АДРЕС-VPS>
|
||
|
||
# При первом подключении подтвердите fingerprint (yes)
|
||
# Введите пароль
|
||
```
|
||
|
||
### 1.3. Создание обычного пользователя (безопасность)
|
||
```bash
|
||
# Создать пользователя (замените 'angel' на ваше имя)
|
||
adduser angel
|
||
|
||
# Добавить в группу sudo (права администратора)
|
||
usermod -aG sudo angel
|
||
|
||
# Переключиться на нового пользователя
|
||
su - angel
|
||
```
|
||
|
||
### 1.4. Настройка SSH-ключей (опционально, но рекомендуется)
|
||
```bash
|
||
# На локальной машине (Windows PowerShell):
|
||
ssh-keygen -t ed25519 -C "angel@vps"
|
||
# Нажимайте Enter для всех вопросов (пароль можно оставить пустым)
|
||
|
||
# Копирование ключа на сервер:
|
||
ssh-copy-id angel@<IP-АДРЕС-VPS>
|
||
|
||
# Проверка подключения без пароля:
|
||
ssh angel@<IP-АДРЕС-VPS>
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Базовая настройка сервера
|
||
|
||
### 2.1. Обновление системы
|
||
```bash
|
||
# Обновить списки пакетов и установить обновления
|
||
sudo apt update && sudo apt upgrade -y
|
||
|
||
# Установить необходимые утилиты
|
||
sudo apt install -y \
|
||
curl \
|
||
wget \
|
||
git \
|
||
ufw \
|
||
fail2ban \
|
||
htop \
|
||
nano \
|
||
certbot \
|
||
python3-certbot-nginx
|
||
```
|
||
|
||
### 2.2. Настройка фаервола (UFW)
|
||
```bash
|
||
# Разрешить SSH (порт 22)
|
||
sudo ufw allow 22/tcp
|
||
|
||
# Разрешить HTTP и HTTPS
|
||
sudo ufw allow 80/tcp
|
||
sudo ufw allow 443/tcp
|
||
|
||
# Включить фаервол
|
||
sudo ufw enable
|
||
|
||
# Проверить статус
|
||
sudo ufw status
|
||
```
|
||
|
||
### 2.3. Настройка Fail2Ban (защита от перебора паролей)
|
||
```bash
|
||
# Скопировать конфиг
|
||
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
|
||
|
||
# Перезапустить сервис
|
||
sudo systemctl enable fail2ban
|
||
sudo systemctl restart fail2ban
|
||
|
||
# Проверить статус
|
||
sudo fail2ban-client status
|
||
```
|
||
|
||
### 2.4. Настройка часового пояса
|
||
```bash
|
||
# Установить московское время
|
||
sudo timedatectl set-timezone Europe/Moscow
|
||
|
||
# Проверить
|
||
timedatectl
|
||
```
|
||
|
||
### 2.5. Настройка swap-файла (если мало RAM)
|
||
```bash
|
||
# Создать swap-файл 2GB
|
||
sudo fallocate -l 2G /swapfile
|
||
sudo chmod 600 /swapfile
|
||
sudo mkswap /swapfile
|
||
sudo swapon /swapfile
|
||
|
||
# Добавить в fstab для автозагрузки
|
||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||
|
||
# Проверить
|
||
free -h
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Установка Docker и Docker Compose
|
||
|
||
### 3.1. Установка Docker
|
||
```bash
|
||
# Удалить старые версии (если есть)
|
||
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
|
||
sudo apt-get remove -y $pkg
|
||
done
|
||
|
||
# Добавить репозиторий Docker
|
||
sudo apt-get update
|
||
sudo apt-get install -y ca-certificates curl
|
||
sudo install -m 0755 -d /etc/apt/keyrings
|
||
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||
|
||
# Добавить репозиторий в sources
|
||
echo \
|
||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
|
||
# Установить Docker
|
||
sudo apt-get update
|
||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
|
||
# Проверить установку
|
||
docker --version
|
||
docker compose version
|
||
```
|
||
|
||
### 3.2. Настройка пользователя для Docker (без sudo)
|
||
```bash
|
||
# Добавить текущего пользователя в группу docker
|
||
sudo usermod -aG docker $USER
|
||
|
||
# Применить изменения (выйти и зайти снова, или выполнить:)
|
||
newgrp docker
|
||
|
||
# Проверить (должно работать без sudo)
|
||
docker run hello-world
|
||
```
|
||
|
||
### 3.3. Настройка автозапуска Docker
|
||
```bash
|
||
sudo systemctl enable docker
|
||
sudo systemctl enable containerd
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Структура директорий для мультипроекта
|
||
|
||
### 4.1. Создание структуры
|
||
```bash
|
||
# Создать основную директорию для проектов
|
||
sudo mkdir -p /opt/projects
|
||
sudo chown -R $USER:$USER /opt/projects
|
||
|
||
# Создать директории для каждого проекта
|
||
mkdir -p /opt/projects/{nginx-proxy,gitea,aegisone-php,aegisone-py,project2,project3}
|
||
|
||
# Создать директорию для общих данных
|
||
mkdir -p /opt/projects/{backups,certs,data}
|
||
```
|
||
|
||
### 4.2. Итоговая структура
|
||
```
|
||
/opt/projects/
|
||
├── nginx-proxy/ # Nginx reverse proxy + Certbot
|
||
│ ├── docker-compose.yml
|
||
│ ├── nginx.conf
|
||
│ └── certs/ # SSL-сертификаты Let's Encrypt
|
||
├── gitea/ # Git-сервер
|
||
│ ├── docker-compose.yml
|
||
│ └── data/ # Данные Gitea (репозитории, БД)
|
||
├── aegisone-php/ # Публичная часть AegisOne (PHP)
|
||
│ ├── docker-compose.yml
|
||
│ ├── src/ # Исходный код (git clone)
|
||
│ └── nginx.conf
|
||
├── aegisone-py/ # Сервисная часть AegisOne (Python)
|
||
│ ├── docker-compose.yml
|
||
│ ├── app/ # FastAPI приложение
|
||
│ └── requirements.txt
|
||
├── project2/ # Второй проект
|
||
│ └── docker-compose.yml
|
||
├── project3/ # Третий проект
|
||
│ └── docker-compose.yml
|
||
├── backups/ # Бэкапы БД и файлов
|
||
├── certs/ # Общие SSL-сертификаты
|
||
└── data/ # Общие данные (PostgreSQL, Redis)
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Nginx Reverse Proxy + Let's Encrypt
|
||
|
||
### 5.1. Создание docker-compose.yml для Nginx
|
||
```bash
|
||
cd /opt/projects/nginx-proxy
|
||
nano docker-compose.yml
|
||
```
|
||
|
||
**Содержимое `docker-compose.yml`:**
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
nginx:
|
||
image: nginx:alpine
|
||
container_name: nginx-proxy
|
||
ports:
|
||
- "80:80"
|
||
- "443:443"
|
||
volumes:
|
||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||
- ./certs:/etc/nginx/certs:ro
|
||
- ./conf.d:/etc/nginx/conf.d:ro
|
||
- ./html:/usr/share/nginx/html:ro
|
||
restart: unless-stopped
|
||
networks:
|
||
- proxy-net
|
||
|
||
certbot:
|
||
image: certbot/certbot:latest
|
||
container_name: certbot
|
||
volumes:
|
||
- ./certs:/etc/letsencrypt
|
||
- ./html:/var/www/certbot
|
||
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
||
restart: unless-stopped
|
||
|
||
networks:
|
||
proxy-net:
|
||
external: true
|
||
```
|
||
|
||
### 5.2. Создание базового nginx.conf
|
||
```bash
|
||
mkdir -p conf.d html
|
||
nano nginx.conf
|
||
```
|
||
|
||
**Содержимое `nginx.conf`:**
|
||
```nginx
|
||
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;
|
||
tcp_nodelay on;
|
||
keepalive_timeout 65;
|
||
types_hash_max_size 2048;
|
||
client_max_body_size 50M;
|
||
|
||
# Gzip сжатие
|
||
gzip on;
|
||
gzip_vary on;
|
||
gzip_proxied any;
|
||
gzip_comp_level 6;
|
||
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;
|
||
}
|
||
```
|
||
|
||
### 5.3. Создание сети для Docker
|
||
```bash
|
||
# Создать общую сеть для всех проектов
|
||
docker network create proxy-net
|
||
```
|
||
|
||
### 5.4. Запуск Nginx
|
||
```bash
|
||
cd /opt/projects/nginx-proxy
|
||
docker compose up -d
|
||
|
||
# Проверить
|
||
docker compose ps
|
||
docker compose logs -f
|
||
```
|
||
|
||
### 5.5. Получение SSL-сертификатов
|
||
```bash
|
||
# Для каждого домена выполнить:
|
||
docker compose run --rm certbot certonly \
|
||
--webroot \
|
||
--webroot-path=/var/www/certbot \
|
||
-d aegisone.ru \
|
||
-d www.aegisone.ru \
|
||
-d service.aegisone.ru \
|
||
-d git.aegisone.ru \
|
||
--email your@email.com \
|
||
--agree-tos \
|
||
--non-interactive
|
||
|
||
# Проверить сертификаты
|
||
ls -la certs/live/aegisone.ru/
|
||
```
|
||
|
||
### 5.6. Пример конфига для домена (aegisone.ru)
|
||
```bash
|
||
nano conf.d/aegisone.conf
|
||
```
|
||
|
||
**Содержимое `conf.d/aegisone.conf`:**
|
||
```nginx
|
||
# HTTP → HTTPS редирект
|
||
server {
|
||
listen 80;
|
||
server_name aegisone.ru www.aegisone.ru;
|
||
return 301 https://aegisone.ru$request_uri;
|
||
}
|
||
|
||
# HTTPS сервер
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name aegisone.ru www.aegisone.ru;
|
||
|
||
# SSL сертификаты
|
||
ssl_certificate /etc/nginx/certs/live/aegisone.ru/fullchain.pem;
|
||
ssl_certificate_key /etc/nginx/certs/live/aegisone.ru/privkey.pem;
|
||
|
||
# SSL настройки
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
ssl_prefer_server_ciphers on;
|
||
|
||
# Проксирование на PHP-контейнер
|
||
location / {
|
||
proxy_pass http://aegisone-php:80;
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.7. Конфиг для поддомена (service.aegisone.ru)
|
||
```bash
|
||
nano conf.d/service-aegisone.conf
|
||
```
|
||
|
||
**Содержимое `conf.d/service-aegisone.conf`:**
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name service.aegisone.ru;
|
||
return 301 https://service.aegisone.ru$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name service.aegisone.ru;
|
||
|
||
ssl_certificate /etc/nginx/certs/live/aegisone.ru/fullchain.pem;
|
||
ssl_certificate_key /etc/nginx/certs/live/aegisone.ru/privkey.pem;
|
||
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
ssl_prefer_server_ciphers on;
|
||
|
||
# Проксирование на Python-контейнер
|
||
location / {
|
||
proxy_pass http://aegisone-py: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;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.8. Перезапуск Nginx после изменений
|
||
```bash
|
||
cd /opt/projects/nginx-proxy
|
||
docker compose restart nginx
|
||
|
||
# Проверить конфиг
|
||
docker compose exec nginx nginx -t
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Gitea (Git-сервер)
|
||
|
||
### 6.1. Создание docker-compose.yml
|
||
```bash
|
||
cd /opt/projects/gitea
|
||
mkdir -p data
|
||
nano docker-compose.yml
|
||
```
|
||
|
||
**Содержимое `docker-compose.yml`:**
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
gitea:
|
||
image: gitea/gitea:latest
|
||
container_name: gitea
|
||
environment:
|
||
- USER_UID=1000
|
||
- USER_GID=1000
|
||
- GITEA__database__DB_TYPE=postgres
|
||
- GITEA__database__HOST=db:5432
|
||
- GITEA__database__NAME=gitea
|
||
- GITEA__database__USER=gitea
|
||
- GITEA__database__PASSWD=gitea_password
|
||
- GITEA__server__DOMAIN=git.aegisone.ru
|
||
- GITEA__server__HTTP_PORT=3000
|
||
- GITEA__server__ROOT_URL=https://git.aegisone.ru/
|
||
volumes:
|
||
- ./data:/data
|
||
- /etc/timezone:/etc/timezone:ro
|
||
- /etc/localtime:/etc/localtime:ro
|
||
ports:
|
||
- "3000:3000"
|
||
- "2222:22"
|
||
depends_on:
|
||
- db
|
||
restart: unless-stopped
|
||
networks:
|
||
- proxy-net
|
||
- gitea-net
|
||
|
||
db:
|
||
image: postgres:15-alpine
|
||
container_name: gitea-db
|
||
environment:
|
||
- POSTGRES_USER=gitea
|
||
- POSTGRES_PASSWORD=gitea_password
|
||
- POSTGRES_DB=gitea
|
||
volumes:
|
||
- ./data/postgres:/var/lib/postgresql/data
|
||
restart: unless-stopped
|
||
networks:
|
||
- gitea-net
|
||
|
||
networks:
|
||
proxy-net:
|
||
external: true
|
||
gitea-net:
|
||
driver: bridge
|
||
```
|
||
|
||
### 6.2. Запуск Gitea
|
||
```bash
|
||
cd /opt/projects/gitea
|
||
docker compose up -d
|
||
|
||
# Проверить
|
||
docker compose ps
|
||
docker compose logs -f gitea
|
||
```
|
||
|
||
### 6.3. Настройка Nginx для Gitea
|
||
```bash
|
||
nano /opt/projects/nginx-proxy/conf.d/gitea.conf
|
||
```
|
||
|
||
**Содержимое `conf.d/gitea.conf`:**
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name git.aegisone.ru;
|
||
return 301 https://git.aegisone.ru$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name git.aegisone.ru;
|
||
|
||
ssl_certificate /etc/nginx/certs/live/aegisone.ru/fullchain.pem;
|
||
ssl_certificate_key /etc/nginx/certs/live/aegisone.ru/privkey.pem;
|
||
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
ssl_prefer_server_ciphers on;
|
||
|
||
client_max_body_size 50M;
|
||
|
||
location / {
|
||
proxy_pass http://gitea:3000;
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.4. Перезапуск Nginx
|
||
```bash
|
||
cd /opt/projects/nginx-proxy
|
||
docker compose restart nginx
|
||
```
|
||
|
||
### 6.5. Первоначальная настройка Gitea
|
||
1. Откройте `https://git.aegisone.ru`
|
||
2. Заполните форму регистрации первого пользователя (он станет администратором)
|
||
3. В настройках Gitea:
|
||
- Включить Gitea Actions (CI/CD)
|
||
- Настроить SSH-порт (2222)
|
||
- Создать организацию `aegisone`
|
||
|
||
### 6.6. Создание репозиториев
|
||
```bash
|
||
# Через веб-интерфейс Gitea создать:
|
||
# - aegisone/aegisone-php (публичная часть)
|
||
# - aegisone/aegisone-py (сервисная часть)
|
||
# - aegisone/infra (конфигурации Docker, Nginx, CI/CD)
|
||
# - aegisone/project2 (второй проект)
|
||
# - aegisone/project3 (третий проект)
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Подготовка к переносу AegisOne (PHP)
|
||
|
||
### 7.1. Создание docker-compose.yml
|
||
```bash
|
||
cd /opt/projects/aegisone-php
|
||
nano docker-compose.yml
|
||
```
|
||
|
||
**Содержимое `docker-compose.yml`:**
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
nginx:
|
||
image: nginx:alpine
|
||
container_name: aegisone-php-nginx
|
||
volumes:
|
||
- ./src:/var/www/html:ro
|
||
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||
ports:
|
||
- "9080:80"
|
||
depends_on:
|
||
- php
|
||
restart: unless-stopped
|
||
networks:
|
||
- proxy-net
|
||
- aegisone-net
|
||
|
||
php:
|
||
image: php:7.4-fpm
|
||
container_name: aegisone-php-fpm
|
||
volumes:
|
||
- ./src:/var/www/html
|
||
environment:
|
||
- DB_HOST=mysql
|
||
- DB_PORT=3306
|
||
- DB_NAME=j30663893_engineering
|
||
- DB_USER=j30663893_engin
|
||
- DB_PASS=.-SHGWa_
|
||
depends_on:
|
||
- mysql
|
||
restart: unless-stopped
|
||
networks:
|
||
- aegisone-net
|
||
|
||
mysql:
|
||
image: mysql:5.7
|
||
container_name: aegisone-php-mysql
|
||
environment:
|
||
MYSQL_ROOT_PASSWORD: root_password
|
||
MYSQL_DATABASE: j30663893_engineering
|
||
MYSQL_USER: j30663893_engin
|
||
MYSQL_PASSWORD: .-SHGWa_
|
||
volumes:
|
||
- mysql_data:/var/lib/mysql
|
||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
||
ports:
|
||
- "3306:3306"
|
||
restart: unless-stopped
|
||
networks:
|
||
- aegisone-net
|
||
|
||
volumes:
|
||
mysql_data:
|
||
|
||
networks:
|
||
proxy-net:
|
||
external: true
|
||
aegisone-net:
|
||
driver: bridge
|
||
```
|
||
|
||
### 7.2. Создание nginx.conf для PHP
|
||
```bash
|
||
nano nginx.conf
|
||
```
|
||
|
||
**Содержимое `nginx.conf`:**
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name localhost;
|
||
root /var/www/html;
|
||
index index.php index.html;
|
||
|
||
location / {
|
||
try_files $uri $uri/ /index.php?$query_string;
|
||
}
|
||
|
||
location ~ \.php$ {
|
||
fastcgi_pass php:9000;
|
||
fastcgi_index index.php;
|
||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||
include fastcgi_params;
|
||
}
|
||
|
||
location ~ /\.ht {
|
||
deny all;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.3. Перенос файлов с хостинга
|
||
```bash
|
||
# На локальной машине (Windows):
|
||
# 1. Скачать файлы с хостинга через FTP/SFTP
|
||
# 2. Или скопировать из локальной папки проекта
|
||
|
||
# Копирование на VPS:
|
||
scp -r D:\YandexDisk\site_aegisone\* angel@<IP-VPS>:/opt/projects/aegisone-php/src/
|
||
|
||
# На VPS:
|
||
cd /opt/projects/aegisone-php
|
||
# Проверить файлы
|
||
ls -la src/
|
||
```
|
||
|
||
### 7.4. Миграция БД
|
||
```bash
|
||
# Экспорт с хостинга (через phpMyAdmin или mysqldump)
|
||
# mysqldump -u j30663893_engin -p j30663893_engineering > backup.sql
|
||
|
||
# Копирование на VPS
|
||
scp backup.sql angel@<IP-VPS>:/opt/projects/aegisone-php/
|
||
|
||
# На VPS:
|
||
cd /opt/projects/aegisone-php
|
||
cp backup.sql init.sql
|
||
|
||
# Запуск контейнеров
|
||
docker compose up -d
|
||
|
||
# Проверка
|
||
docker compose ps
|
||
docker compose logs -f
|
||
```
|
||
|
||
### 7.5. Настройка Nginx для aegisone.ru
|
||
```bash
|
||
# Файл уже создан в шаге 5.6 (conf.d/aegisone.conf)
|
||
# Перезапустить Nginx
|
||
cd /opt/projects/nginx-proxy
|
||
docker compose restart nginx
|
||
```
|
||
|
||
### 7.6. Проверка работоспособности
|
||
1. Открыть `https://aegisone.ru`
|
||
2. Проверить все страницы: главная, услуги, блог, контакты
|
||
3. Проверить форму обратной связи
|
||
4. Проверить карусель, FAQ, переключение темы
|
||
5. Проверить Яндекс.Карту
|
||
|
||
---
|
||
|
||
## 8. Подготовка Python-админки (FastAPI)
|
||
|
||
### 8.1. Создание структуры проекта
|
||
```bash
|
||
cd /opt/projects/aegisone-py
|
||
mkdir -p app/{api,models,schemas,services,tasks,templates,static/{css,js,img},utils}
|
||
mkdir -p migrations
|
||
touch app/__init__.py app/main.py app/config.py app/database.py
|
||
touch requirements.txt Dockerfile docker-compose.yml alembic.ini
|
||
```
|
||
|
||
### 8.2. requirements.txt
|
||
```bash
|
||
nano requirements.txt
|
||
```
|
||
|
||
**Содержимое `requirements.txt`:**
|
||
```
|
||
fastapi==0.104.1
|
||
uvicorn[standard]==0.24.0
|
||
sqlalchemy==2.0.23
|
||
alembic==1.13.0
|
||
psycopg2-binary==2.9.9
|
||
python-jose[cryptography]==3.3.0
|
||
passlib[bcrypt]==1.7.4
|
||
python-multipart==0.0.6
|
||
jinja2==3.1.2
|
||
celery==5.3.4
|
||
redis==5.0.1
|
||
weasyprint==60.1
|
||
openpyxl==3.1.2
|
||
yandex-disk==3.1.1
|
||
pydantic==2.5.2
|
||
pydantic-settings==2.1.0
|
||
httpx==0.25.2
|
||
```
|
||
|
||
### 8.3. Dockerfile
|
||
```bash
|
||
nano Dockerfile
|
||
```
|
||
|
||
**Содержимое `Dockerfile`:**
|
||
```dockerfile
|
||
FROM python:3.11-slim
|
||
|
||
WORKDIR /app
|
||
|
||
# Установка системных зависимостей
|
||
RUN apt-get update && apt-get install -y \
|
||
gcc \
|
||
libpq-dev \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
# Копирование requirements и установка Python-зависимостей
|
||
COPY requirements.txt .
|
||
RUN pip install --no-cache-dir -r requirements.txt
|
||
|
||
# Копирование исходного кода
|
||
COPY . .
|
||
|
||
# Запуск приложения
|
||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||
```
|
||
|
||
### 8.4. docker-compose.yml
|
||
```bash
|
||
nano docker-compose.yml
|
||
```
|
||
|
||
**Содержимое `docker-compose.yml`:**
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
app:
|
||
build: .
|
||
container_name: aegisone-py-app
|
||
ports:
|
||
- "8000:8000"
|
||
environment:
|
||
- DATABASE_URL=postgresql://aegisone:aegisone_password@db:5432/aegisone
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- SECRET_KEY=your-secret-key-change-in-production
|
||
- ALGORITHM=HS256
|
||
- ACCESS_TOKEN_EXPIRE_MINUTES=60
|
||
volumes:
|
||
- ./app:/app/app
|
||
depends_on:
|
||
- db
|
||
- redis
|
||
restart: unless-stopped
|
||
networks:
|
||
- proxy-net
|
||
- aegisone-py-net
|
||
|
||
worker:
|
||
build: .
|
||
container_name: aegisone-py-worker
|
||
command: celery -A app.tasks worker --loglevel=info
|
||
environment:
|
||
- DATABASE_URL=postgresql://aegisone:aegisone_password@db:5432/aegisone
|
||
- REDIS_URL=redis://redis:6379/0
|
||
volumes:
|
||
- ./app:/app/app
|
||
depends_on:
|
||
- db
|
||
- redis
|
||
restart: unless-stopped
|
||
networks:
|
||
- aegisone-py-net
|
||
|
||
db:
|
||
image: postgres:15-alpine
|
||
container_name: aegisone-py-db
|
||
environment:
|
||
- POSTGRES_USER=aegisone
|
||
- POSTGRES_PASSWORD=aegisone_password
|
||
- POSTGRES_DB=aegisone
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
ports:
|
||
- "5432:5432"
|
||
restart: unless-stopped
|
||
networks:
|
||
- aegisone-py-net
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: aegisone-py-redis
|
||
ports:
|
||
- "6379:6379"
|
||
restart: unless-stopped
|
||
networks:
|
||
- aegisone-py-net
|
||
|
||
volumes:
|
||
postgres_data:
|
||
|
||
networks:
|
||
proxy-net:
|
||
external: true
|
||
aegisone-py-net:
|
||
driver: bridge
|
||
```
|
||
|
||
### 8.5. Базовый app/main.py
|
||
```bash
|
||
nano app/main.py
|
||
```
|
||
|
||
**Содержимое `app/main.py`:**
|
||
```python
|
||
from fastapi import FastAPI, Request
|
||
from fastapi.templating import Jinja2Templates
|
||
from fastapi.staticfiles import StaticFiles
|
||
from fastapi.responses import HTMLResponse
|
||
|
||
app = FastAPI(title="AegisOne Engineering - Admin Panel")
|
||
|
||
# Подключение шаблонов и статики
|
||
templates = Jinja2Templates(directory="app/templates")
|
||
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
||
|
||
@app.get("/", response_class=HTMLResponse)
|
||
async def root(request: Request):
|
||
return templates.TemplateResponse("index.html", {"request": request})
|
||
|
||
@app.get("/health")
|
||
async def health_check():
|
||
return {"status": "ok"}
|
||
```
|
||
|
||
### 8.6. Запуск Python-админки
|
||
```bash
|
||
cd /opt/projects/aegisone-py
|
||
docker compose up -d --build
|
||
|
||
# Проверить
|
||
docker compose ps
|
||
docker compose logs -f app
|
||
```
|
||
|
||
### 8.7. Настройка Nginx для service.aegisone.ru
|
||
```bash
|
||
# Файл уже создан в шаге 5.7 (conf.d/service-aegisone.conf)
|
||
# Перезапустить Nginx
|
||
cd /opt/projects/nginx-proxy
|
||
docker compose restart nginx
|
||
```
|
||
|
||
---
|
||
|
||
## 9. CI/CD с Gitea Actions
|
||
|
||
### 9.1. Включение Gitea Actions
|
||
1. Открыть `https://git.aegisone.ru`
|
||
2. Зайти в **Site Administration** → **Configuration**
|
||
3. Включить **Actions** (Enable Gitea Actions)
|
||
4. Сохранить настройки
|
||
|
||
### 9.2. Создание workflow для aegisone-py
|
||
```bash
|
||
# На локальной машине:
|
||
cd D:\YandexDisk\site_aegisone
|
||
mkdir -p .gitea/workflows
|
||
nano .gitea/workflows/deploy.yml
|
||
```
|
||
|
||
**Содержимое `.gitea/workflows/deploy.yml`:**
|
||
```yaml
|
||
name: Deploy AegisOne Python
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
|
||
jobs:
|
||
deploy:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Build Docker image
|
||
run: |
|
||
docker build -t aegisone-py:latest .
|
||
|
||
- name: Deploy to VPS
|
||
uses: appleboy/ssh-action@v1.0.0
|
||
with:
|
||
host: ${{ secrets.VPS_HOST }}
|
||
username: ${{ secrets.VPS_USER }}
|
||
key: ${{ secrets.VPS_SSH_KEY }}
|
||
script: |
|
||
cd /opt/projects/aegisone-py
|
||
docker compose down
|
||
docker compose up -d --build
|
||
docker system prune -f
|
||
```
|
||
|
||
### 9.3. Настройка секретов в Gitea
|
||
1. Открыть репозиторий `aegisone/aegisone-py`
|
||
2. **Settings** → **Secrets**
|
||
3. Добавить секреты:
|
||
- `VPS_HOST`: IP-адрес VPS
|
||
- `VPS_USER`: `angel` (или ваш пользователь)
|
||
- `VPS_SSH_KEY`: Приватный SSH-ключ для подключения
|
||
|
||
### 9.4. Настройка SSH-ключей для CI/CD
|
||
```bash
|
||
# На VPS:
|
||
# Создать SSH-ключ для Gitea Actions
|
||
ssh-keygen -t ed25519 -C "gitea-actions" -f /home/angel/.ssh/gitea_actions -N ""
|
||
|
||
# Добавить публичный ключ в authorized_keys
|
||
cat /home/angel/.ssh/gitea_actions.pub >> /home/angel/.ssh/authorized_keys
|
||
|
||
# Скопировать приватный ключ для добавления в секреты Gitea
|
||
cat /home/angel/.ssh/gitea_actions
|
||
```
|
||
|
||
### 9.5. Тестирование CI/CD
|
||
1. Закоммитить изменения в `main`
|
||
2. Открыть репозиторий → **Actions**
|
||
3. Проверить выполнение workflow
|
||
4. Убедиться, что деплой прошел успешно
|
||
|
||
---
|
||
|
||
## 10. Бэкапы и мониторинг
|
||
|
||
### 10.1. Настройка бэкапов PostgreSQL
|
||
```bash
|
||
# Создать скрипт бэкапа
|
||
nano /opt/projects/backups/backup-postgres.sh
|
||
```
|
||
|
||
**Содержимое `backup-postgres.sh`:**
|
||
```bash
|
||
#!/bin/bash
|
||
BACKUP_DIR="/opt/projects/backups/postgres"
|
||
DATE=$(date +%Y%m%d_%H%M%S)
|
||
DB_NAME="aegisone"
|
||
DB_USER="aegisone"
|
||
DB_PASSWORD="aegisone_password"
|
||
|
||
# Создать директорию
|
||
mkdir -p $BACKUP_DIR
|
||
|
||
# Создать бэкап
|
||
PGPASSWORD=$DB_PASSWORD pg_dump -h localhost -U $DB_USER $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
|
||
|
||
# Удалить старые бэкапы (старше 30 дней)
|
||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||
|
||
echo "Backup created: ${DB_NAME}_${DATE}.sql.gz"
|
||
```
|
||
|
||
**Сделать скрипт исполняемым:**
|
||
```bash
|
||
chmod +x /opt/projects/backups/backup-postgres.sh
|
||
```
|
||
|
||
### 10.2. Настройка cron для автоматических бэкапов
|
||
```bash
|
||
# Открыть crontab
|
||
crontab -e
|
||
|
||
# Добавить задачу (бэкап каждый день в 3:00)
|
||
0 3 * * * /opt/projects/backups/backup-postgres.sh >> /opt/projects/backups/backup.log 2>&1
|
||
```
|
||
|
||
### 10.3. Бэкап MySQL (для PHP-части)
|
||
```bash
|
||
nano /opt/projects/backups/backup-mysql.sh
|
||
```
|
||
|
||
**Содержимое `backup-mysql.sh`:**
|
||
```bash
|
||
#!/bin/bash
|
||
BACKUP_DIR="/opt/projects/backups/mysql"
|
||
DATE=$(date +%Y%m%d_%H%M%S)
|
||
DB_NAME="j30663893_engineering"
|
||
DB_USER="j30663893_engin"
|
||
DB_PASSWORD=".-SHGWa_"
|
||
|
||
mkdir -p $BACKUP_DIR
|
||
|
||
docker exec aegisone-php-mysql mysqldump -u $DB_USER -p$DB_PASSWORD $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
|
||
|
||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||
|
||
echo "MySQL backup created: ${DB_NAME}_${DATE}.sql.gz"
|
||
```
|
||
|
||
**Сделать исполняемым и добавить в cron:**
|
||
```bash
|
||
chmod +x /opt/projects/backups/backup-mysql.sh
|
||
crontab -e
|
||
# Добавить: 30 3 * * * /opt/projects/backups/backup-mysql.sh >> /opt/projects/backups/backup.log 2>&1
|
||
```
|
||
|
||
### 10.4. Мониторинг с Uptime Kuma (опционально)
|
||
```bash
|
||
cd /opt/projects
|
||
mkdir -p uptime-kuma
|
||
cd uptime-kuma
|
||
nano docker-compose.yml
|
||
```
|
||
|
||
**Содержимое `docker-compose.yml`:**
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
uptime-kuma:
|
||
image: louislam/uptime-kuma:latest
|
||
container_name: uptime-kuma
|
||
ports:
|
||
- "3001:3001"
|
||
volumes:
|
||
- ./data:/app/data
|
||
restart: unless-stopped
|
||
networks:
|
||
- proxy-net
|
||
|
||
networks:
|
||
proxy-net:
|
||
external: true
|
||
```
|
||
|
||
**Запуск:**
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
**Настройка Nginx для Uptime Kuma:**
|
||
```bash
|
||
nano /opt/projects/nginx-proxy/conf.d/uptime.conf
|
||
```
|
||
|
||
**Содержимое `conf.d/uptime.conf`:**
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name monitor.aegisone.ru;
|
||
return 301 https://monitor.aegisone.ru$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name monitor.aegisone.ru;
|
||
|
||
ssl_certificate /etc/nginx/certs/live/aegisone.ru/fullchain.pem;
|
||
ssl_certificate_key /etc/nginx/certs/live/aegisone.ru/privkey.pem;
|
||
|
||
location / {
|
||
proxy_pass http://uptime-kuma:3001;
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Чек-лист завершения
|
||
|
||
### Этап 1: Базовая настройка
|
||
- [ ] Подключение к VPS по SSH
|
||
- [ ] Создание пользователя без root
|
||
- [ ] Настройка SSH-ключей
|
||
- [ ] Обновление системы
|
||
- [ ] Настройка фаервола (UFW)
|
||
- [ ] Настройка Fail2Ban
|
||
- [ ] Настройка часового пояса
|
||
- [ ] Настройка swap-файла
|
||
|
||
### Этап 2: Docker
|
||
- [ ] Установка Docker и Docker Compose
|
||
- [ ] Настройка пользователя для Docker (без sudo)
|
||
- [ ] Создание общей сети `proxy-net`
|
||
- [ ] Проверка `docker run hello-world`
|
||
|
||
### Этап 3: Nginx + SSL
|
||
- [ ] Создание структуры `/opt/projects/nginx-proxy/`
|
||
- [ ] Настройка `docker-compose.yml` для Nginx
|
||
- [ ] Создание `nginx.conf`
|
||
- [ ] Запуск Nginx
|
||
- [ ] Получение SSL-сертификатов Let's Encrypt
|
||
- [ ] Создание конфигов для доменов (aegisone.ru, service.aegisone.ru, git.aegisone.ru)
|
||
- [ ] Проверка HTTPS для всех доменов
|
||
|
||
### Этап 4: Gitea
|
||
- [ ] Создание структуры `/opt/projects/gitea/`
|
||
- [ ] Настройка `docker-compose.yml` для Gitea
|
||
- [ ] Запуск Gitea
|
||
- [ ] Настройка Nginx для git.aegisone.ru
|
||
- [ ] Первоначальная настройка Gitea (регистрация админа)
|
||
- [ ] Включение Gitea Actions
|
||
- [ ] Создание репозиториев
|
||
- [ ] Настройка SSH-ключей для CI/CD
|
||
|
||
### Этап 5: AegisOne PHP
|
||
- [ ] Создание структуры `/opt/projects/aegisone-php/`
|
||
- [ ] Настройка `docker-compose.yml`
|
||
- [ ] Перенос файлов с хостинга
|
||
- [ ] Миграция БД
|
||
- [ ] Запуск контейнеров
|
||
- [ ] Настройка Nginx для aegisone.ru
|
||
- [ ] Проверка работоспособности сайта
|
||
|
||
### Этап 6: AegisOne Python
|
||
- [ ] Создание структуры `/opt/projects/aegisone-py/`
|
||
- [ ] Настройка `Dockerfile` и `docker-compose.yml`
|
||
- [ ] Создание базового FastAPI приложения
|
||
- [ ] Запуск контейнеров
|
||
- [ ] Настройка Nginx для service.aegisone.ru
|
||
- [ ] Проверка работоспособности API
|
||
|
||
### Этап 7: CI/CD
|
||
- [ ] Создание workflow `.gitea/workflows/deploy.yml`
|
||
- [ ] Настройка секретов в Gitea
|
||
- [ ] Тестирование деплоя
|
||
- [ ] Настройка rollback
|
||
|
||
### Этап 8: Бэкапы и мониторинг
|
||
- [ ] Настройка бэкапов PostgreSQL
|
||
- [ ] Настройка бэкапов MySQL
|
||
- [ ] Настройка cron для автоматических бэкапов
|
||
- [ ] (Опционально) Установка Uptime Kuma
|
||
- [ ] Настройка алертов
|
||
|
||
### Этап 9: Финальная проверка
|
||
- [ ] Все домены работают по HTTPS
|
||
- [ ] PHP-часть (aegisone.ru) работает
|
||
- [ ] Python-часть (service.aegisone.ru) работает
|
||
- [ ] Gitea (git.aegisone.ru) работает
|
||
- [ ] CI/CD деплой работает
|
||
- [ ] Бэкапы создаются автоматически
|
||
- [ ] Мониторинг настроен
|
||
|
||
---
|
||
|
||
## Полезные команды
|
||
|
||
### Управление Docker
|
||
```bash
|
||
# Посмотреть запущенные контейнеры
|
||
docker ps
|
||
|
||
# Посмотреть все контейнеры (включая остановленные)
|
||
docker ps -a
|
||
|
||
# Посмотреть логи контейнера
|
||
docker logs -f <container_name>
|
||
|
||
# Остановить контейнер
|
||
docker stop <container_name>
|
||
|
||
# Запустить контейнер
|
||
docker start <container_name>
|
||
|
||
# Перезапустить контейнер
|
||
docker restart <container_name>
|
||
|
||
# Удалить контейнер
|
||
docker rm <container_name>
|
||
|
||
# Посмотреть использование ресурсов
|
||
docker stats
|
||
|
||
# Очистить неиспользуемые ресурсы
|
||
docker system prune -f
|
||
```
|
||
|
||
### Управление Docker Compose
|
||
```bash
|
||
# Запустить все сервисы
|
||
docker compose up -d
|
||
|
||
# Остановить все сервисы
|
||
docker compose down
|
||
|
||
# Перезапустить все сервисы
|
||
docker compose restart
|
||
|
||
# Посмотреть логи
|
||
docker compose logs -f
|
||
|
||
# Посмотреть статус
|
||
docker compose ps
|
||
|
||
# Пересобрать и запустить
|
||
docker compose up -d --build
|
||
```
|
||
|
||
### Управление Nginx
|
||
```bash
|
||
# Проверить конфиг
|
||
docker compose exec nginx nginx -t
|
||
|
||
# Перезагрузить конфиг
|
||
docker compose exec nginx nginx -s reload
|
||
|
||
# Посмотреть логи
|
||
docker compose logs -f nginx
|
||
```
|
||
|
||
### Управление Gitea
|
||
```bash
|
||
# Посмотреть логи
|
||
docker compose logs -f gitea
|
||
|
||
# Перезапустить
|
||
docker compose restart gitea
|
||
```
|
||
|
||
### Системные команды
|
||
```bash
|
||
# Посмотреть использование диска
|
||
df -h
|
||
|
||
# Посмотреть использование памяти
|
||
free -h
|
||
|
||
# Посмотреть загрузку CPU
|
||
htop
|
||
|
||
# Посмотреть логи системы
|
||
journalctl -f
|
||
|
||
# Посмотреть открытые порты
|
||
sudo ss -tulpn
|
||
```
|
||
|
||
---
|
||
|
||
## Контакты и поддержка
|
||
|
||
**Документ создан:** 2026-05-17
|
||
**Версия:** 1.0
|
||
**Автор:** AI-ассистент + Владелец
|
||
**Статус:** Готов к выполнению
|
||
|
||
> **Важно:** Если при выполнении возникнут вопросы — лучше уточнить, чем переделывать потом.
|
||
> **Примечание:** Все пароли и ключи в примерах являются демонстрационными. Замените их на реальные перед использованием в продакшене.
|