132 lines
4.1 KiB
Bash
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"
|