No description
Find a file
2026-08-30 13:20:30 +00:00
00-migrate-root.sh universal zero-downtime migration from legacy WireGuard/Go stack to operator-docker 2026-08-30 13:19:11 +00:00
01-migrate-user.sh universal zero-downtime migration from legacy WireGuard/Go stack to operator-docker 2026-08-30 13:18:00 +00:00
02-migrate-peers.sh universal zero-downtime migration from legacy WireGuard/Go stack 2026-08-30 13:20:30 +00:00
readme.md universal zero-downtime migration from legacy WireGuard/Go stack to operator-docker 2026-08-30 13:11:52 +00:00

migration-guide

🇺🇸English · 🇪🇸Español


English

Zero-downtime migration from the legacy WireGuard + Go API stack to operator-docker. Existing VPN clients reconnect automatically — no new configuration required on their end.


How it works

Before migration
  Legacy stack (sp-env-wireguard-ipv6)
    ├── wireguard        (linuxserver/wireguard)
    ├── wireguard-api    (Go)
    └── nginx-certbot

After migration
  operator-docker
    ├── wireguard        (same identity — same public key)
    ├── operator-api     (FastAPI)
    ├── marzban
    ├── hysteria2
    └── mysql

The server's WireGuard identity (private key → public key) is preserved. All peers are migrated via the new API. Clients reconnect without any config change.


Prerequisites

  • Legacy stack running (docker ps shows wireguard)
  • Domain with DNS pointing to this server
  • One subdomain per service (api, legacy, cdn, news or similar)
  • SSH key authorized by Simplified Privacy (generated in step 00)
  • Port 80/TCP reachable externally (required by Let's Encrypt)

Migration steps

Script Run as Description
00-migrate-root.sh root Backup, shutdown legacy, clean system
01-migrate-user.sh user Clone repo, install operator-docker
02-migrate-peers.sh user Inject identity, migrate peers

Usage

Scripts can be run from any directory:

sudo bash ~/migration/00-migrate-root.sh
bash ~/migration/01-migrate-user.sh
bash ~/migration/02-migrate-peers.sh

Step 00 — Backup and cleanup

Run as root:

sudo bash 00-migrate-root.sh

What it does:

Action Detail
Detects legacy WireGuard container By image or name
Backs up private key and public key Saved to ~/.wg-migration/
Backs up all peers From wg showconf wg0
Backs up Nginx configs and SSL certs Full /etc/nginx and /etc/letsencrypt
Backs up UFW rules Snapshot only
Generates SSH key For repo access
Shuts down legacy stack docker compose down
Cleans Nginx Removes all sites for fresh install
Verifies port 51820 is free Fails if still in use

At the end, the script prints the SSH public key. Send it to Simplified Privacy before running 01.


Step 01 — Install operator-docker

Once Simplified Privacy authorizes the SSH key, run as your Linux user:

bash 01-migrate-user.sh

What it does:

Action Detail
Validates backups exist Fails early if 00 was not run
Cleans any failed previous install Detects corrupt .env, incomplete repo
Clones private repo Via SSH
Runs install.sh in migration mode WireGuard is NOT started yet
Creates wg0.conf placeholder 02 will inject the real private key
Restores external Nginx configs e.g. mail server vhosts

MIGRATION_MODE=1 tells the installer to skip starting WireGuard. The 02 script starts it after injecting the legacy identity.


Step 02 — Migrate identity and peers

bash 02-migrate-peers.sh

What it does:

Action Detail
Stops legacy WireGuard Via docker compose stop in legacy dir
Injects legacy private key Into wg0.conf and server keyfiles
Starts new WireGuard With the legacy identity
Verifies public key matches Fails and rolls back if it doesn't
Verifies API is responding GET /wireguard/peers must return 200
Migrates all peers POST /wireguard/peers for each peer
Destroys private key from disk shred or rm

Rollback

Each script has automatic rollback on failure:

  • 00 — No rollback needed (legacy stays running until 02)
  • 01 — Removes operator-docker, restores Nginx and certs, restarts legacy
  • 02 — Stops new WireGuard, restores wg0.conf, restarts legacy

Manual rollback if needed:

# Restore SSL certificates
sudo cp -r ~/.wg-migration/letsencrypt/. /etc/letsencrypt/

# Restore Nginx
sudo cp -r ~/.wg-migration/nginx/sites-available/. /etc/nginx/sites-available/
sudo cp -r ~/.wg-migration/nginx/sites-enabled/. /etc/nginx/sites-enabled/
sudo systemctl restart nginx

# Remove operator-docker
rm -rf ~/operator-docker

# Restart legacy stack
LEGACY_DIR=$(cat ~/.wg-migration/legacy_compose_dir)
cd "$LEGACY_DIR" && docker compose up -d

WireGuard identity and peers are never modified in the legacy stack — they remain intact.


Backup location

All backups are stored in ~/.wg-migration/:

File Content
private_key WireGuard private key (deleted after 02)
public_key WireGuard public key
wg0-legacy.conf Full peer list
wg0-legacy.conf.original Unmodified copy
legacy.env Legacy stack .env
legacy_compose_dir Path to legacy stack
nginx/ Nginx sites and config
letsencrypt/ SSL certificates
ufw-snapshot.txt UFW rules
network_info IPv4/IPv6 detection result
ssh_pubkey SSH public key for repo access
migration.log Full log of all steps

Notes

  • Existing VPN clients reconnect automatically after 02 completes — no config changes needed.
  • The private key is destroyed from disk after successful peer migration.
  • If port 80 is blocked externally, SSL certificate issuance will fail at step 01. Contact your VPS provider or use DNS challenge manually.
  • IPv6 is detected and enabled automatically.

Español

Migración sin tiempo de inactividad desde el stack legacy WireGuard + Go API hacia operator-docker. Los clientes VPN existentes se reconectan automáticamente — no requieren ningún cambio de configuración.


Cómo funciona

Antes de la migración
  Stack legacy (sp-env-wireguard-ipv6)
    ├── wireguard        (linuxserver/wireguard)
    ├── wireguard-api    (Go)
    └── nginx-certbot

Después de la migración
  operator-docker
    ├── wireguard        (misma identidad — misma clave pública)
    ├── operator-api     (FastAPI)
    ├── marzban
    ├── hysteria2
    └── mysql

La identidad WireGuard del servidor (clave privada → clave pública) se preserva. Todos los peers se migran vía la nueva API. Los clientes se reconectan sin cambios.


Requisitos

  • Stack legacy corriendo (docker ps muestra wireguard)
  • Dominio con DNS apuntando a este servidor
  • Un subdominio por servicio (api, legacy, cdn, news o similar)
  • SSH key autorizada por Simplified Privacy (generada en el paso 00)
  • Puerto 80/TCP accesible externamente (requerido por Let's Encrypt)

Pasos de migración

Script Ejecutar como Descripción
00-migrate-root.sh root Backup, apaga legacy, limpia sistema
01-migrate-user.sh usuario Clona repo, instala operator-docker
02-migrate-peers.sh usuario Inyecta identidad, migra peers

Uso

Los scripts se pueden ejecutar desde cualquier directorio:

sudo bash ~/migration/00-migrate-root.sh
bash ~/migration/01-migrate-user.sh
bash ~/migration/02-migrate-peers.sh

Paso 00 — Backup y limpieza

Ejecutar como root:

sudo bash 00-migrate-root.sh

Acciones:

Acción Detalle
Detecta el contenedor WireGuard legacy Por imagen o nombre
Respalda clave privada y pública Guardadas en ~/.wg-migration/
Respalda todos los peers Desde wg showconf wg0
Respalda Nginx y certificados SSL /etc/nginx y /etc/letsencrypt completos
Respalda reglas UFW Solo snapshot
Genera SSH key Para acceso al repo
Apaga el stack legacy docker compose down
Limpia Nginx Elimina todos los sites para instalación limpia
Verifica que el puerto 51820 esté libre Falla si sigue en uso

Al finalizar, el script muestra la clave SSH pública. Envíala a Simplified Privacy antes de ejecutar el 01.


Paso 01 — Instalar operator-docker

Una vez que Simplified Privacy autorice la SSH key, ejecutar como usuario Linux:

bash 01-migrate-user.sh

Acciones:

Acción Detalle
Valida que existan los backups Falla si no se ejecutó el 00
Limpia instalación anterior fallida Detecta .env corrupto, repo incompleto
Clona el repo privado Vía SSH
Ejecuta install.sh en modo migración WireGuard NO se inicia todavía
Crea placeholder de wg0.conf El 02 inyectará la clave privada real
Restaura configs Nginx externos Por ejemplo, vhosts del servidor de correo

MIGRATION_MODE=1 indica al instalador que omita el inicio de WireGuard. El script 02 lo inicia después de inyectar la identidad legacy.


Paso 02 — Migrar identidad y peers

bash 02-migrate-peers.sh

Acciones:

Acción Detalle
Detiene WireGuard legacy Vía docker compose stop en el directorio legacy
Inyecta la clave privada legacy En wg0.conf y keyfiles del servidor
Inicia el nuevo WireGuard Con la identidad legacy
Verifica que la clave pública coincida Falla y hace rollback si no coincide
Verifica que la API responda GET /wireguard/peers debe devolver 200
Migra todos los peers POST /wireguard/peers por cada peer
Destruye la clave privada del disco shred o rm

Rollback

Cada script tiene rollback automático en caso de fallo:

  • 00 — Sin rollback necesario (el legacy sigue corriendo hasta el 02)
  • 01 — Elimina operator-docker, restaura Nginx y certs, reinicia legacy
  • 02 — Detiene el nuevo WireGuard, restaura wg0.conf, reinicia legacy

Rollback manual si es necesario:

# Restaurar certificados SSL
sudo cp -r ~/.wg-migration/letsencrypt/. /etc/letsencrypt/

# Restaurar Nginx
sudo cp -r ~/.wg-migration/nginx/sites-available/. /etc/nginx/sites-available/
sudo cp -r ~/.wg-migration/nginx/sites-enabled/. /etc/nginx/sites-enabled/
sudo systemctl restart nginx

# Eliminar operator-docker
rm -rf ~/operator-docker

# Reiniciar stack legacy
LEGACY_DIR=$(cat ~/.wg-migration/legacy_compose_dir)
cd "$LEGACY_DIR" && docker compose up -d

La identidad WireGuard y los peers nunca se modifican en el stack legacy — permanecen intactos.


Ubicación del backup

Todos los backups se almacenan en ~/.wg-migration/:

Archivo Contenido
private_key Clave privada WireGuard (eliminada tras el 02)
public_key Clave pública WireGuard
wg0-legacy.conf Lista completa de peers
wg0-legacy.conf.original Copia sin modificar
legacy.env .env del stack legacy
legacy_compose_dir Ruta al stack legacy
nginx/ Sites y configuración de Nginx
letsencrypt/ Certificados SSL
ufw-snapshot.txt Reglas UFW
network_info Resultado de detección IPv4/IPv6
ssh_pubkey Clave SSH pública para acceso al repo
migration.log Log completo de todos los pasos

Notas

  • Los clientes VPN existentes se reconectan automáticamente al finalizar el 02 — no requieren cambios de configuración.
  • La clave privada se destruye del disco tras la migración exitosa de peers.
  • Si el puerto 80 está bloqueado externamente, la emisión de certificados SSL fallará en el paso 01. Contacta a tu proveedor VPS o usa DNS challenge manualmente.
  • IPv6 se detecta y habilita automáticamente.