# Инструкция по настройке 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-ассистент + Владелец  
**Статус:** Готов к выполнению

> **Важно:** Если при выполнении возникнут вопросы — лучше уточнить, чем переделывать потом.  
> **Примечание:** Все пароли и ключи в примерах являются демонстрационными. Замените их на реальные перед использованием в продакшене.
