← Вернуться к оглавлению

🚀 Инструкция по настройке VPS для веб-проектов

Версия 2.0 | 23 июля 2026

📋 Исходные данные

🏗️ Архитектура

VPS 193.32.179.138
├── Nginx Proxy Manager (:80, :443, :81)
├── Portainer (:9443)
├── Dozzle (:9999)
├── Watchtower (автообновление)
├── Uptime Kuma (:3001)
├── Main Site (avk27.ru)
├── Project A
│   ├── Container A1 (go app)
│   └── Container A2 (db)
└── Project B
    ├── Container B1 (php app)
    ├── Container B2 (node.js)
    └── Container B3 (redis)
    

📁 Структура каталогов

/opt/
├── infrastructure/     # Инфраструктурные сервисы
│   ├── docker-compose.yml
│   ├── monitoring.yml
│   ├── watchtower.yml
│   ├── uptime-kuma.yml
│   ├── npm/
│   │   ├── data/
│   │   └── letsencrypt/
│   ├── portainer/
│   │   └── data/
│   └── uptime-kuma/
│       └── data/
├── projects/          # Веб-проекты
│   ├── main-site/     # Главная страница avk27.ru
│   │   ├── docker-compose.yml
│   │   └── src/
│   │       └── index.html
│   ├── project-example/
│   │   ├── docker-compose.yml
│   │   ├── .env
│   │   ├── db-data/
│   │   └── src/
│   ├── project1/
│   ├── project2/
│   └── project3/
├── scripts/           # Скрипты автоматизации
│   └── backup.sh
└── backups/           # Бэкапы
    

1️⃣ Базовая подготовка VPS

# Подключение к серверу
ssh root@193.32.179.138

# Обновление системы
apt update && apt upgrade -y

# Установка необходимых пакетов
apt install -y curl wget git ufw fail2ban tree apache2-utils

# Настройка firewall
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 81/tcp    # для NPM админки
ufw allow 9443/tcp  # для Portainer
ufw enable

# Настройка fail2ban для защиты SSH
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
systemctl enable fail2ban
systemctl start fail2ban
    

2️⃣ Установка Docker

# Официальный способ установки Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Добавление пользователя в группу docker
usermod -aG docker $USER

# Установка Docker Compose
apt install -y docker-compose-plugin

# Перелогиньтесь или выполните:
newgrp docker
    

3️⃣ Создание Docker сети

# Создаём внешнюю сеть для связи контейнеров
docker network create --driver bridge webproxy

# Проверка
docker network ls | grep webproxy
    

4️⃣ Создание структуры каталогов

# Создание основной структуры
mkdir -p /opt/infrastructure/npm/data
mkdir -p /opt/infrastructure/npm/letsencrypt
mkdir -p /opt/infrastructure/portainer/data
mkdir -p /opt/infrastructure/uptime-kuma/data
mkdir -p /opt/projects/main-site/src
mkdir -p /opt/projects/project-example/db-data
mkdir -p /opt/projects/project-example/src
mkdir -p /opt/scripts
mkdir -p /opt/backups

# Установка прав
chown -R $USER:$USER /opt/infrastructure
chown -R $USER:$USER /opt/projects
chown -R $USER:$USER /opt/scripts
chown -R $USER:$USER /opt/backups
chmod +x /opt/scripts

# Проверка структуры
tree /opt -L 3 -d
    

5️⃣ Настройка docker-compose для инфраструктуры

Создайте файл /opt/infrastructure/docker-compose.yml:

version: '3.8'

services:
  nginx-proxy-manager:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '81:81'
    volumes:
      - ./npm/data:/data
      - ./npm/letsencrypt:/etc/letsencrypt
    networks:
      - webproxy

  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    command: -H unix:///var/run/docker.sock
    ports:
      - '9443:9443'
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./portainer/data:/data
    networks:
      - webproxy

networks:
  webproxy:
    external: true
    

6️⃣ Настройка мониторинга логов (Dozzle)

Создайте файл /opt/infrastructure/monitoring.yml:

version: '3.8'

services:
  dozzle:
    image: amir20/dozzle:latest
    container_name: dozzle
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - "9999:8080"
    networks:
      - webproxy

networks:
  webproxy:
    external: true
    

7️⃣ Настройка автообновления (Watchtower)

Создайте файл /opt/infrastructure/watchtower.yml:

version: '3.8'

services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      # Docker Engine 28+ не принимает API-клиенты старее 1.40,
      # а встроенный клиент watchtower говорит на 1.25 и падает с
      # "client version 1.25 is too old" — форсируем версию API
      - DOCKER_API_VERSION=1.41
    command: --interval 86400 --cleanup
    networks:
      - webproxy

networks:
  webproxy:
    external: true
    

8️⃣ Настройка мониторинга доступности (Uptime Kuma)

Создайте файл /opt/infrastructure/uptime-kuma.yml:

version: '3.8'

services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    restart: unless-stopped
    volumes:
      - ./uptime-kuma/data:/app/data
    ports:
      - "3001:3001"
    networks:
      - webproxy

networks:
  webproxy:
    external: true
    

9️⃣ Запуск инфраструктуры

# Переход в директорию
cd /opt/infrastructure

# Запуск всех сервисов
docker compose -f docker-compose.yml up -d
docker compose -f monitoring.yml up -d
docker compose -f watchtower.yml up -d
docker compose -f uptime-kuma.yml up -d

# Проверка запущенных контейнеров
docker ps
    

🔟 Настройка Nginx Proxy Manager

  1. Откройте http://193.32.179.138:81
  2. Логин/пароль по умолчанию: admin@example.com / changeme

⚠️ Сразу смените пароль!

Добавление SSL сертификата

  1. Перейдите в раздел "SSL Certificates"
  2. Нажмите "Add SSL Certificate"
  3. Выберите "Let's Encrypt"
  4. Введите домены: *.avk27.ru и avk27.ru
  5. Используйте DNS Challenge для wildcard сертификата

1️⃣1️⃣ Шаблон docker-compose для веб-проектов

Создайте файл /opt/projects/project-example/docker-compose.yml:

version: '3.8'

services:
  app:
    image: your-app-image
    container_name: project-example-app
    restart: unless-stopped
    expose:
      - "3000"  # порт внутри сети, не открывается наружу
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_USER=user
      - DB_PASSWORD=${DB_PASSWORD}
      - DB_NAME=app
    networks:
      - webproxy
      - internal
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16-alpine
    container_name: project-example-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - ./db-data:/var/lib/postgresql/data
    networks:
      - internal
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d app"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  webproxy:
    external: true
  internal:
    driver: bridge
    

Создайте файл /opt/projects/project-example/.env:

DB_PASSWORD=your_secure_password_here
    

1️⃣2️⃣ Настройка главной страницы домена (avk27.ru)

💡 По умолчанию при переходе на http://avk27.ru отображается заглушка Nginx Proxy Manager. Чтобы это исправить, нужно создать контейнер с вашим сайтом и настроить прокси.

Создание страницы

# Создаём директорию (уже должна существовать)
mkdir -p /opt/projects/main-site/src

# Создаём простую главную страницу
cat > /opt/projects/main-site/src/index.html << 'EOF'
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>avk27.ru</title>
</head>
<body>
    <h1>🚀 avk27.ru</h1>
    <p>Главная страница работает!</p>
    <p>Сервер: 193.32.179.138</p>
</body>
</html>
EOF
    

Создание docker-compose.yml для главного сайта

Создайте файл /opt/projects/main-site/docker-compose.yml:

version: '3.8'

services:
  web:
    image: nginx:alpine
    container_name: main-site
    restart: unless-stopped
    volumes:
      - ./src:/usr/share/nginx/html:ro
    expose:
      - "80"
    networks:
      - webproxy

networks:
  webproxy:
    external: true
    

Запуск контейнера

cd /opt/projects/main-site
docker compose up -d
    

Настройка прокси в Nginx Proxy Manager

  1. Откройте админку NPM: http://193.32.179.138:81
  2. Перейдите в раздел Hosts → Proxy Hosts
  3. Нажмите Add Proxy Host
  4. Заполните поля:
ПолеЗначение
Domain Namesavk27.ru
Schemehttp
Forward Hostname / IPmain-site
Forward Port80
  1. Включите Websocket Support, Block Common Exploits
  2. Перейдите на вкладку SSL
  3. Выберите ранее созданный сертификат для *.avk27.ru, avk27.ru
  4. Включите Force SSL, HTTP/2 Support, HSTS Enabled
  5. Нажмите Save

✅ Готово! Теперь http://avk27.ru и https://avk27.ru открывают вашу страницу вместо заглушки NPM.

1️⃣3️⃣ Настройка HTTP Basic Auth для avk27.ru

💡 Два способа настройки: через Nginx Proxy Manager (проще) или через конфиг nginx в контейнере. Рекомендуется способ через NPM.

Способ 1: Через Nginx Proxy Manager (рекомендуется)

Шаг 1: Создание файла с паролем

# Установка утилиты (если ещё не установлена)
apt install -y apache2-utils

# Создание директории для htpasswd
mkdir -p /opt/infrastructure/npm/data/nginx/htpasswd

# Создание пользователя и пароля
# Замените 'admin' на желаемый логин
htpasswd -c /opt/infrastructure/npm/data/nginx/htpasswd/.htpasswd_avk27 admin
# Введите пароль дважды
    

Шаг 2: Настройка в NPM

  1. Откройте админку NPM: http://193.32.179.138:81
  2. Перейдите в Hosts → Proxy Hosts
  3. Найдите и отредактируйте запись для avk27.ru
  4. Перейдите на вкладку Advanced
  5. В поле вставьте:
auth_basic "Restricted Access";
auth_basic_user_file /data/nginx/htpasswd/.htpasswd_avk27;
    
  1. Нажмите Save

✅ Готово! Теперь при заходе на https://avk27.ru браузер запросит логин и пароль.

Способ 2: На уровне контейнера (альтернативный)

Шаг 1: Создание файла .htpasswd

apt install -y apache2-utils

# Создайте файл с пользователем
htpasswd -c /opt/projects/main-site/.htpasswd admin
# Введите пароль дважды
    

Шаг 2: Создание конфига nginx

Создайте файл /opt/projects/main-site/default.conf:

server {
    listen 80;
    server_name avk27.ru;

    root /usr/share/nginx/html;
    index index.html;

    # Включаем Basic Auth для всего сайта
    auth_basic "Restricted Access";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        try_files $uri $uri/ =404;
    }
}
    

Шаг 3: Обновление docker-compose.yml

Отредактируйте /opt/projects/main-site/docker-compose.yml:

version: '3.8'

services:
  web:
    image: nginx:alpine
    container_name: main-site
    restart: unless-stopped
    volumes:
      - ./src:/usr/share/nginx/html:ro
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./.htpasswd:/etc/nginx/.htpasswd:ro
    expose:
      - "80"
    networks:
      - webproxy

networks:
  webproxy:
    external: true
    

Шаг 4: Перезапуск контейнера

cd /opt/projects/main-site
docker compose down
docker compose up -d
    

⚠️ Важно: Если возникает ошибка 403 Forbidden, проверьте права доступа к файлу .htpasswd и правильность пути в конфиге nginx.

1️⃣4️⃣ Настройка резервного копирования

Скрипт бэкапа /opt/scripts/backup.sh: консистентный mysqldump базы mylife, архив проектов (без «горячих» файлов БД), NPM, 3x-ui, мониторинг (Uptime Kuma + конфиг Netdata), системные настройки; retention 3 дня; итог записывается в /opt/backups/.last-status, по которому Telegram-бот показывает свежесть копии в отчёте /status. Полный текст скрипта, состав копий и инструкция по восстановлению — в документе «Бэкапы VPS: что, как и когда».

# Сделайте скрипт исполняемым
chmod +x /opt/scripts/backup.sh

# Добавление в crontab (ежедневно в 2:00)
(crontab -l 2>/dev/null; echo "0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1") | crontab -
    

1️⃣5️⃣ Настройка DNS

В панели управления доменом avk27.ru создайте следующие записи:

Тип Имя Значение TTL
A @ 193.32.179.138 3600
A * 193.32.179.138 3600

💡 Wildcard запись (*) позволяет автоматически направлять любые поддомены на ваш сервер без создания отдельных DNS записей.

🚀 Быстрый деплой нового проекта

# 1. Создание структуры проекта
mkdir -p /opt/projects/my-new-app/src
cd /opt/projects/my-new-app

# 2. Копирование шаблона
cp /opt/projects/project-example/docker-compose.yml .
cp /opt/projects/project-example/.env .

# 3. Редактирование конфигурации
nano docker-compose.yml
nano .env

# 4. Запуск проекта
docker compose up -d

# 5. Настройка прокси в Nginx Proxy Manager
# Зайдите в http://193.32.179.138:81
# Добавьте Proxy Host:
#   Domain: my-app.avk27.ru
#   Forward Hostname/IP: container_name
#   Forward Port: порт_приложения
#   Включите SSL (выберите ранее созданный wildcard сертификат)
    

🔐 Важные моменты безопасности

  1. Сразу после установки NPM смените пароль администратора!
  2. Настройте SSL для всех админок (NPM, Portainer, Dozzle) через сам NPM
  3. Не открывайте порты приложений наружу — используйте expose вместо ports в docker-compose проектов
  4. Используйте сильные пароли и храните их в .env файлах
  5. Регулярно обновляйте систему: apt update && apt upgrade
  6. Проверяйте логи fail2ban: fail2ban-client status sshd
  7. Настройте SSH-ключи вместо парольной аутентификации

⚠️ Порт 81 (NPM админка) открыт для всего интернета. После настройки SSL рекомендуется проксировать админку через сам NPM и закрыть прямой доступ к порту 81.

🛠️ Полезные команды

Docker

# Просмотр запущенных контейнеров
docker ps

# Все контейнеры (включая остановленные)
docker ps -a

# Просмотр логов контейнера
docker logs -f container_name

# Перезапуск контейнера
docker restart container_name

# Обновление образов и перезапуск
docker compose -f /opt/infrastructure/docker-compose.yml pull
docker compose -f /opt/infrastructure/docker-compose.yml up -d

# Использование ресурсов
docker stats

# Очистка неиспользуемых данных
docker system prune -a -f
# ⚠️ НЕ добавляйте --volumes: эта опция удаляет неиспользуемые тома Docker
# вместе с данными (например, базами), если контейнер в момент чистки остановлен
    

Система

# Использование диска
df -h

# Размер директорий
du -sh /opt/*

# Ручной запуск бэкапа
/opt/scripts/backup.sh

# Проверка статуса fail2ban
fail2ban-client status sshd

# Перезагрузка сервера (если необходимо)
reboot
    

🌐 Доступ к сервисам после настройки

Сервис URL Назначение
Nginx Proxy Manager http://193.32.179.138:81 Управление прокси и SSL
Portainer https://193.32.179.138:9443 Управление контейнерами
Dozzle http://193.32.179.138:9999 Просмотр логов
Uptime Kuma http://193.32.179.138:3001 Мониторинг доступности

💡 Рекомендация: После настройки SSL проксируйте все административные интерфейсы через NPM для доступа по HTTPS с вашего домена:

📊 Мониторинг и обслуживание

Еженедельные задачи

Ежемесячные задачи

🆘 Решение проблем

Контейнер не запускается

# Проверка логов
docker logs container_name

# Проверка конфигурации compose
docker compose config

# Запуск с подробным выводом
docker compose up
    

Нет доступа к приложению через домен

  1. Проверьте DNS: nslookup your-subdomain.avk27.ru
  2. Проверьте настройки прокси в NPM
  3. Проверьте, что контейнер в сети webproxy: docker inspect container_name | grep webproxy

Закончилось место на диске

# Просмотр использования
df -h
du -sh /opt/*

# Очистка Docker
docker system prune -a -f
# ⚠️ НЕ добавляйте --volumes: эта опция удаляет неиспользуемые тома Docker
# вместе с данными (например, базами), если контейнер в момент чистки остановлен

# Проверка больших файлов
find /opt -type f -size +100M -exec ls -lh {} \;
    

SSL сертификат не обновляется

  1. Проверьте, что домен правильно направлен на сервер
  2. Убедитесь, что порты 80 и 443 открыты и доступны извне
  3. Проверьте логи NPM: docker logs nginx-proxy-manager

🎉 Поздравляем! Ваш VPS настроен и готов к работе.