Two deployment options for recreating the kirgysia server: - manual-setup/: bash script for manual server provisioning - cloud-init/: cloud-init config + data upload script for automated VPS setup Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
170 lines
5.0 KiB
YAML
170 lines
5.0 KiB
YAML
#cloud-config
|
|
#
|
|
# Cloud-init конфиг для воссоздания сервера kirgysia
|
|
# Ubuntu 22.04 LTS
|
|
#
|
|
# Использование:
|
|
# Вставить содержимое этого файла в поле "User Data" / "Cloud-Init"
|
|
# при создании VPS у хостера (Hetzner, Vultr, DO и т.д.)
|
|
#
|
|
# После создания сервера запустить upload-data.sh для загрузки базы и сертификатов
|
|
#
|
|
|
|
# --- Пользователь ---
|
|
users:
|
|
- name: eberkheev
|
|
groups: sudo, docker
|
|
shell: /bin/bash
|
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
ssh_authorized_keys:
|
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDqMBaED9uVMQkKqwIZ6PeQp+3tNGBozQHpi4uNVjdcV admin@DESKTOP-4NGS6DA
|
|
|
|
# --- Пакеты ---
|
|
package_update: true
|
|
package_upgrade: true
|
|
packages:
|
|
- curl
|
|
- wget
|
|
- git
|
|
- htop
|
|
- mc
|
|
- nmap
|
|
- net-tools
|
|
- unzip
|
|
- fail2ban
|
|
- certbot
|
|
- docker.io
|
|
- docker-compose
|
|
- ufw
|
|
|
|
# --- SSH ---
|
|
write_files:
|
|
- path: /etc/ssh/sshd_config
|
|
content: |
|
|
Include /etc/ssh/sshd_config.d/*.conf
|
|
Port 10001
|
|
PermitRootLogin no
|
|
PasswordAuthentication no
|
|
PermitEmptyPasswords no
|
|
KbdInteractiveAuthentication no
|
|
UsePAM yes
|
|
X11Forwarding yes
|
|
PrintMotd no
|
|
AcceptEnv LANG LC_*
|
|
Subsystem sftp /usr/lib/openssh/sftp-server
|
|
|
|
# --- docker-compose.yml для 3x-ui ---
|
|
- path: /home/eberkheev/3x-ui/docker-compose.yml
|
|
owner: eberkheev:eberkheev
|
|
permissions: "0644"
|
|
content: |
|
|
services:
|
|
3xui:
|
|
image: ghcr.io/mhsanaei/3x-ui:latest
|
|
container_name: 3xui_app
|
|
volumes:
|
|
- ./db/:/etc/x-ui/
|
|
- ./cert/:/root/cert/
|
|
environment:
|
|
XRAY_VMESS_AEAD_FORCED: "false"
|
|
XUI_ENABLE_FAIL2BAN: "true"
|
|
tty: true
|
|
network_mode: host
|
|
restart: unless-stopped
|
|
|
|
# --- Скрипт обновления ---
|
|
- path: /home/eberkheev/update.sh
|
|
owner: eberkheev:eberkheev
|
|
permissions: "0755"
|
|
content: |
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
BACKUP_PATH="/home/eberkheev/x-ui-backup.db"
|
|
XUI_PATH="/home/eberkheev/3x-ui"
|
|
DOCKER_IMAGE="ghcr.io/mhsanaei/3x-ui:latest"
|
|
|
|
BUILD_MODE="pull"
|
|
if [ "$1" = "--build" ]; then
|
|
BUILD_MODE="build"
|
|
fi
|
|
|
|
echo "=== Mode: $BUILD_MODE ==="
|
|
|
|
echo "=== System update ==="
|
|
sudo apt update && sudo apt upgrade -y
|
|
|
|
echo "=== Finding x-ui container ==="
|
|
CONTAINER=$(sudo docker ps --format "{{.Names}}" | grep -i "xui\|x-ui\|3xui" | head -n 1)
|
|
|
|
if [ -z "$CONTAINER" ]; then
|
|
echo "WARNING: x-ui container not found, skipping backup..."
|
|
if [ ! -f "$BACKUP_PATH" ]; then
|
|
echo "ERROR: No container and no backup found, aborting!"
|
|
exit 1
|
|
fi
|
|
echo "Existing backup found at $BACKUP_PATH, continuing..."
|
|
else
|
|
echo "Found container: $CONTAINER"
|
|
echo "=== Backup x-ui database ==="
|
|
sudo docker cp $CONTAINER:/etc/x-ui/x-ui.db $BACKUP_PATH
|
|
echo "Backup saved to $BACKUP_PATH"
|
|
fi
|
|
|
|
echo "=== Pulling latest from main ==="
|
|
cd $XUI_PATH
|
|
sudo git checkout main
|
|
sudo git pull origin main
|
|
|
|
echo "=== Stopping old container ==="
|
|
sudo docker-compose down
|
|
|
|
if [ "$BUILD_MODE" = "build" ]; then
|
|
echo "--- Building from source ---"
|
|
sudo docker-compose build --no-cache
|
|
sudo docker-compose up -d
|
|
else
|
|
echo "--- Pulling prebuilt image: $DOCKER_IMAGE ---"
|
|
sudo docker pull $DOCKER_IMAGE
|
|
sudo docker rm -f 3xui_app 2>/dev/null || true
|
|
sudo docker run -d \
|
|
--name 3xui_app \
|
|
--restart unless-stopped \
|
|
--network host \
|
|
--env XRAY_VMESS_AEAD_FORCED=false \
|
|
--env XUI_ENABLE_FAIL2BAN=true \
|
|
-v $XUI_PATH/db/:/etc/x-ui/ \
|
|
-v $XUI_PATH/cert/:/root/cert/ \
|
|
-t \
|
|
$DOCKER_IMAGE
|
|
fi
|
|
|
|
echo "=== Restoring database from backup ==="
|
|
NEW_CONTAINER=$(sudo docker ps --format "{{.Names}}" | grep -i "xui\|x-ui\|3xui" | head -n 1)
|
|
if [ -z "$NEW_CONTAINER" ]; then
|
|
echo "ERROR: Container not found after restart!"
|
|
exit 1
|
|
fi
|
|
sudo docker cp $BACKUP_PATH $NEW_CONTAINER:/etc/x-ui/x-ui.db
|
|
echo "Database restored, restarting container..."
|
|
sudo docker restart $NEW_CONTAINER
|
|
|
|
echo "=== Status ==="
|
|
sudo docker ps | grep -i "xui\|x-ui\|3xui"
|
|
sudo docker logs $NEW_CONTAINER --tail=30
|
|
|
|
echo "=== Done! ==="
|
|
|
|
# --- Команды при первом запуске ---
|
|
runcmd:
|
|
- systemctl restart ssh
|
|
- systemctl enable docker
|
|
- systemctl start docker
|
|
- mkdir -p /home/eberkheev/3x-ui/db
|
|
- mkdir -p /home/eberkheev/3x-ui/cert
|
|
- mkdir -p /home/eberkheev/cert
|
|
- chown -R eberkheev:eberkheev /home/eberkheev/3x-ui
|
|
- chown -R eberkheev:eberkheev /home/eberkheev/cert
|
|
- chown eberkheev:eberkheev /home/eberkheev/update.sh
|
|
- docker pull ghcr.io/mhsanaei/3x-ui:latest
|