- 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
36 KiB
Инструкция по настройке VPS и миграции проектов
Сервер: Ubuntu 24.04 LTS (чистая установка)
Цель: Docker-инфраструктура для 3+ проектов с мультидоменом, SSL, Git-сервером и CI/CD
Дата: 2026-05-17
Примечание: Если при выполнении возникнут вопросы — лучше уточнить, чем переделывать потом.
Содержание
- Подключение к VPS
- Базовая настройка сервера
- Установка Docker и Docker Compose
- Структура директорий для мультипроекта
- Nginx Reverse Proxy + Let's Encrypt
- Gitea (Git-сервер)
- Подготовка к переносу AegisOne (PHP)
- Подготовка Python-админки (FastAPI)
- CI/CD с Gitea Actions
- Бэкапы и мониторинг
- Чек-лист завершения
1. Подключение к VPS
1.1. Получение данных для подключения
После создания VPS в панели Jino.ru вы получите:
- IP-адрес сервера (например,
185.100.100.50) - Логин:
root - Пароль: (указан в панели или отправлен на email)
1.2. Подключение через PowerShell (Windows)
# Откройте PowerShell и выполните:
ssh root@<IP-АДРЕС-VPS>
# При первом подключении подтвердите fingerprint (yes)
# Введите пароль
1.3. Создание обычного пользователя (безопасность)
# Создать пользователя (замените 'angel' на ваше имя)
adduser angel
# Добавить в группу sudo (права администратора)
usermod -aG sudo angel
# Переключиться на нового пользователя
su - angel
1.4. Настройка SSH-ключей (опционально, но рекомендуется)
# На локальной машине (Windows PowerShell):
ssh-keygen -t ed25519 -C "angel@vps"
# Нажимайте Enter для всех вопросов (пароль можно оставить пустым)
# Копирование ключа на сервер:
ssh-copy-id angel@<IP-АДРЕС-VPS>
# Проверка подключения без пароля:
ssh angel@<IP-АДРЕС-VPS>
2. Базовая настройка сервера
2.1. Обновление системы
# Обновить списки пакетов и установить обновления
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)
# Разрешить 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 (защита от перебора паролей)
# Скопировать конфиг
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Перезапустить сервис
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
# Проверить статус
sudo fail2ban-client status
2.4. Настройка часового пояса
# Установить московское время
sudo timedatectl set-timezone Europe/Moscow
# Проверить
timedatectl
2.5. Настройка swap-файла (если мало RAM)
# Создать 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
# Удалить старые версии (если есть)
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)
# Добавить текущего пользователя в группу docker
sudo usermod -aG docker $USER
# Применить изменения (выйти и зайти снова, или выполнить:)
newgrp docker
# Проверить (должно работать без sudo)
docker run hello-world
3.3. Настройка автозапуска Docker
sudo systemctl enable docker
sudo systemctl enable containerd
4. Структура директорий для мультипроекта
4.1. Создание структуры
# Создать основную директорию для проектов
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
cd /opt/projects/nginx-proxy
nano docker-compose.yml
Содержимое docker-compose.yml:
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
mkdir -p conf.d html
nano nginx.conf
Содержимое 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;
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
# Создать общую сеть для всех проектов
docker network create proxy-net
5.4. Запуск Nginx
cd /opt/projects/nginx-proxy
docker compose up -d
# Проверить
docker compose ps
docker compose logs -f
5.5. Получение SSL-сертификатов
# Для каждого домена выполнить:
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)
nano conf.d/aegisone.conf
Содержимое conf.d/aegisone.conf:
# 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)
nano conf.d/service-aegisone.conf
Содержимое conf.d/service-aegisone.conf:
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 после изменений
cd /opt/projects/nginx-proxy
docker compose restart nginx
# Проверить конфиг
docker compose exec nginx nginx -t
6. Gitea (Git-сервер)
6.1. Создание docker-compose.yml
cd /opt/projects/gitea
mkdir -p data
nano docker-compose.yml
Содержимое docker-compose.yml:
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
cd /opt/projects/gitea
docker compose up -d
# Проверить
docker compose ps
docker compose logs -f gitea
6.3. Настройка Nginx для Gitea
nano /opt/projects/nginx-proxy/conf.d/gitea.conf
Содержимое conf.d/gitea.conf:
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
cd /opt/projects/nginx-proxy
docker compose restart nginx
6.5. Первоначальная настройка Gitea
- Откройте
https://git.aegisone.ru - Заполните форму регистрации первого пользователя (он станет администратором)
- В настройках Gitea:
- Включить Gitea Actions (CI/CD)
- Настроить SSH-порт (2222)
- Создать организацию
aegisone
6.6. Создание репозиториев
# Через веб-интерфейс 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
cd /opt/projects/aegisone-php
nano docker-compose.yml
Содержимое docker-compose.yml:
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
nano nginx.conf
Содержимое nginx.conf:
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. Перенос файлов с хостинга
# На локальной машине (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. Миграция БД
# Экспорт с хостинга (через 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
# Файл уже создан в шаге 5.6 (conf.d/aegisone.conf)
# Перезапустить Nginx
cd /opt/projects/nginx-proxy
docker compose restart nginx
7.6. Проверка работоспособности
- Открыть
https://aegisone.ru - Проверить все страницы: главная, услуги, блог, контакты
- Проверить форму обратной связи
- Проверить карусель, FAQ, переключение темы
- Проверить Яндекс.Карту
8. Подготовка Python-админки (FastAPI)
8.1. Создание структуры проекта
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
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
nano 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
nano docker-compose.yml
Содержимое docker-compose.yml:
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
nano app/main.py
Содержимое app/main.py:
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-админки
cd /opt/projects/aegisone-py
docker compose up -d --build
# Проверить
docker compose ps
docker compose logs -f app
8.7. Настройка Nginx для service.aegisone.ru
# Файл уже создан в шаге 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
- Открыть
https://git.aegisone.ru - Зайти в Site Administration → Configuration
- Включить Actions (Enable Gitea Actions)
- Сохранить настройки
9.2. Создание workflow для aegisone-py
# На локальной машине:
cd D:\YandexDisk\site_aegisone
mkdir -p .gitea/workflows
nano .gitea/workflows/deploy.yml
Содержимое .gitea/workflows/deploy.yml:
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
- Открыть репозиторий
aegisone/aegisone-py - Settings → Secrets
- Добавить секреты:
VPS_HOST: IP-адрес VPSVPS_USER:angel(или ваш пользователь)VPS_SSH_KEY: Приватный SSH-ключ для подключения
9.4. Настройка SSH-ключей для CI/CD
# На 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
- Закоммитить изменения в
main - Открыть репозиторий → Actions
- Проверить выполнение workflow
- Убедиться, что деплой прошел успешно
10. Бэкапы и мониторинг
10.1. Настройка бэкапов PostgreSQL
# Создать скрипт бэкапа
nano /opt/projects/backups/backup-postgres.sh
Содержимое backup-postgres.sh:
#!/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"
Сделать скрипт исполняемым:
chmod +x /opt/projects/backups/backup-postgres.sh
10.2. Настройка cron для автоматических бэкапов
# Открыть crontab
crontab -e
# Добавить задачу (бэкап каждый день в 3:00)
0 3 * * * /opt/projects/backups/backup-postgres.sh >> /opt/projects/backups/backup.log 2>&1
10.3. Бэкап MySQL (для PHP-части)
nano /opt/projects/backups/backup-mysql.sh
Содержимое backup-mysql.sh:
#!/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:
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 (опционально)
cd /opt/projects
mkdir -p uptime-kuma
cd uptime-kuma
nano docker-compose.yml
Содержимое docker-compose.yml:
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
Запуск:
docker compose up -d
Настройка Nginx для Uptime Kuma:
nano /opt/projects/nginx-proxy/conf.d/uptime.conf
Содержимое conf.d/uptime.conf:
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
# Посмотреть запущенные контейнеры
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
# Запустить все сервисы
docker compose up -d
# Остановить все сервисы
docker compose down
# Перезапустить все сервисы
docker compose restart
# Посмотреть логи
docker compose logs -f
# Посмотреть статус
docker compose ps
# Пересобрать и запустить
docker compose up -d --build
Управление Nginx
# Проверить конфиг
docker compose exec nginx nginx -t
# Перезагрузить конфиг
docker compose exec nginx nginx -s reload
# Посмотреть логи
docker compose logs -f nginx
Управление Gitea
# Посмотреть логи
docker compose logs -f gitea
# Перезапустить
docker compose restart gitea
Системные команды
# Посмотреть использование диска
df -h
# Посмотреть использование памяти
free -h
# Посмотреть загрузку CPU
htop
# Посмотреть логи системы
journalctl -f
# Посмотреть открытые порты
sudo ss -tulpn
Контакты и поддержка
Документ создан: 2026-05-17
Версия: 1.0
Автор: AI-ассистент + Владелец
Статус: Готов к выполнению
Важно: Если при выполнении возникнут вопросы — лучше уточнить, чем переделывать потом.
Примечание: Все пароли и ключи в примерах являются демонстрационными. Замените их на реальные перед использованием в продакшене.