Версия 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/ # Бэкапы
# Подключение к серверу
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
# Официальный способ установки 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
# Создаём внешнюю сеть для связи контейнеров
docker network create --driver bridge webproxy
# Проверка
docker network ls | grep webproxy
# Создание основной структуры
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
Создайте файл /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
Создайте файл /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
Создайте файл /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
Создайте файл /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
# Переход в директорию
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
⚠️ Сразу смените пароль!
Создайте файл /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
💡 По умолчанию при переходе на 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
Создайте файл /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
| Поле | Значение |
|---|---|
| Domain Names | avk27.ru |
| Scheme | http |
| Forward Hostname / IP | main-site |
| Forward Port | 80 |
✅ Готово! Теперь http://avk27.ru и https://avk27.ru открывают вашу страницу вместо заглушки NPM.
💡 Два способа настройки: через Nginx Proxy Manager (проще) или через конфиг nginx в контейнере. Рекомендуется способ через NPM.
# Установка утилиты (если ещё не установлена)
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
# Введите пароль дважды
auth_basic "Restricted Access";
auth_basic_user_file /data/nginx/htpasswd/.htpasswd_avk27;
✅ Готово! Теперь при заходе на https://avk27.ru браузер запросит логин и пароль.
apt install -y apache2-utils
# Создайте файл с пользователем
htpasswd -c /opt/projects/main-site/.htpasswd admin
# Введите пароль дважды
Создайте файл /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;
}
}
Отредактируйте /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
cd /opt/projects/main-site
docker compose down
docker compose up -d
⚠️ Важно: Если возникает ошибка 403 Forbidden, проверьте права доступа к файлу .htpasswd и правильность пути в конфиге nginx.
Скрипт бэкапа /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 -
В панели управления доменом 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 сертификат)
⚠️ Порт 81 (NPM админка) открыт для всего интернета. После настройки SSL рекомендуется проксировать админку через сам NPM и закрыть прямой доступ к порту 81.
# Просмотр запущенных контейнеров
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
# Просмотр использования
df -h
du -sh /opt/*
# Очистка Docker
docker system prune -a -f
# ⚠️ НЕ добавляйте --volumes: эта опция удаляет неиспользуемые тома Docker
# вместе с данными (например, базами), если контейнер в момент чистки остановлен
# Проверка больших файлов
find /opt -type f -size +100M -exec ls -lh {} \;
🎉 Поздравляем! Ваш VPS настроен и готов к работе.