Files
harbor-net/scripts/deploy-gateway.sh
Dmitriy Petrov b0b9da51b6
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 13s
Build and Deploy Gateway / deploy (push) Successful in 12s
Split gateway control and dataplane into separate services
2026-07-11 17:52:48 +03:00

132 lines
4.1 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
DEPLOY_PATH="${DEPLOY_PATH:-/opt/vpn-proxy}"
CONTROL_IMAGE="${CONTROL_IMAGE:-${GATEWAY_IMAGE:-}}"
DATAPLANE_IMAGE="${DATAPLANE_IMAGE:-${GATEWAY_IMAGE:-}}"
CONTROL_IMAGE="${CONTROL_IMAGE:?CONTROL_IMAGE or GATEWAY_IMAGE is required}"
DATAPLANE_IMAGE="${DATAPLANE_IMAGE:?DATAPLANE_IMAGE or GATEWAY_IMAGE is required}"
UPDATE_DATAPLANE="${UPDATE_DATAPLANE:-false}"
PULL_IMAGE="${PULL_IMAGE:-true}"
echo "Preparing deploy directory: ${DEPLOY_PATH}"
mkdir -p "${DEPLOY_PATH}"
EXISTING_DATAPLANE_IMAGE="$(docker inspect --format '{{.Config.Image}}' vpn-proxy-dataplane 2>/dev/null || true)"
FIRST_SPLIT_DEPLOY=false
if [ -z "${EXISTING_DATAPLANE_IMAGE}" ]; then
FIRST_SPLIT_DEPLOY=true
elif [ "${UPDATE_DATAPLANE}" != "true" ]; then
DATAPLANE_IMAGE="${EXISTING_DATAPLANE_IMAGE}"
fi
cat > "${DEPLOY_PATH}/docker-compose.server.yml" <<EOF
services:
vpn-proxy-dataplane:
image: ${DATAPLANE_IMAGE}
container_name: vpn-proxy-dataplane
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
env_file:
- .env
environment:
APP_COMPONENT: dataplane
DATA_DIR: /var/lib/vpn-proxy
SING_BOX_CONFIG: /var/lib/vpn-proxy/sing-box-config.json
SING_BOX_CACHE: /var/lib/sing-box/cache.db
DATAPLANE_SOCKET: /run/vpn-proxy/dataplane.sock
volumes:
- vpn-proxy-data:/var/lib/vpn-proxy
- sing-box-cache:/var/lib/sing-box
- vpn-proxy-runtime:/run/vpn-proxy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "--unix-socket", "/run/vpn-proxy/dataplane.sock", "-fsS", "http://localhost/status"]
interval: 5s
timeout: 3s
retries: 12
start_period: 5s
vpn-proxy-control:
image: ${CONTROL_IMAGE}
container_name: vpn-proxy-gateway
env_file:
- .env
environment:
APP_COMPONENT: control
DATA_DIR: /var/lib/vpn-proxy
SING_BOX_CONFIG: /var/lib/vpn-proxy/sing-box-config.json
SING_BOX_CACHE: /var/lib/sing-box/cache.db
DATAPLANE_SOCKET: /run/vpn-proxy/dataplane.sock
ports:
- "\${PORT:-3456}:\${PORT:-3456}"
volumes:
- vpn-proxy-data:/var/lib/vpn-proxy
- vpn-proxy-runtime:/run/vpn-proxy
depends_on:
vpn-proxy-dataplane:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:\${PORT:-3456}/api/state"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
volumes:
vpn-proxy-data:
sing-box-cache:
vpn-proxy-runtime:
EOF
if [ ! -f "${DEPLOY_PATH}/.env" ]; then
cat > "${DEPLOY_PATH}/.env" <<'EOF'
PORT=3456
PROXY_PORT=8080
PROXY_BIND_IP=0.0.0.0
TPROXY_PORT=7895
TPROXY_MARK=1
TPROXY_TABLE=100
TPROXY_CHAIN=VPN_PROXY_TPROXY
GATEWAY_FORWARD_CHAIN=VPN_PROXY_FORWARD
GATEWAY_NAT_CHAIN=VPN_PROXY_NAT
GATEWAY_CLIENT_CIDRS=10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
LOG_LEVEL=info
EOF
echo "Created default .env. Edit ${DEPLOY_PATH}/.env if this server needs different ports."
else
echo "Preserving existing .env"
fi
cd "${DEPLOY_PATH}"
echo "Control image: ${CONTROL_IMAGE}"
echo "Dataplane image: ${DATAPLANE_IMAGE}"
if [ "${PULL_IMAGE}" = "true" ]; then
docker compose -f docker-compose.server.yml pull vpn-proxy-control
if [ "${FIRST_SPLIT_DEPLOY}" = "true" ] || [ "${UPDATE_DATAPLANE}" = "true" ]; then
docker compose -f docker-compose.server.yml pull vpn-proxy-dataplane
fi
else
echo "Skipping image pull"
fi
if [ "${FIRST_SPLIT_DEPLOY}" = "true" ]; then
echo "Migrating the legacy combined gateway to split services..."
docker stop vpn-proxy-gateway 2>/dev/null || true
docker rm vpn-proxy-gateway 2>/dev/null || true
docker compose -f docker-compose.server.yml up -d --wait --wait-timeout 90
elif [ "${UPDATE_DATAPLANE}" = "true" ]; then
echo "Updating control and dataplane..."
docker compose -f docker-compose.server.yml up -d --wait --wait-timeout 90
else
echo "Updating control; keeping dataplane running..."
docker compose -f docker-compose.server.yml up -d --no-deps --wait --wait-timeout 90 vpn-proxy-control
fi
echo "Current containers:"
docker ps --filter "name=vpn-proxy-gateway" --filter "name=vpn-proxy-dataplane"