# Step 7 — Cloud Failover (kscloud1) **Track:** With AI (Beginner) **Time for this step:** 4–6 hours Right now, if your home computer goes off, your entire website goes offline. This step fixes that. You will turn your cloud VPS (kscloud1) into a full mirror of your homelab, so that when your home computer is off, kscloud1 keeps everything running. --- ## What You Are Building ``` Home (monk) ←—— always developing ——→ pushes to ——→ Cloud (kscloud1) always live never goes down Cloudflare routes traffic to whichever host responds. If monk is off, kscloud1 handles everything by itself. ``` --- ## Step 7A — Set Up Tailscale on Both Machines Tailscale creates a private, encrypted connection between your home computer and your VPS. You need this so both machines can share a database securely. **On your home computer:** ```bash curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up ``` Follow the link it gives you to authenticate in your browser. **On your VPS (via SSH):** ```bash curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up ``` Authenticate again. After both are connected, check their Tailscale IPs: ```bash tailscale ip -4 ``` Write down both IPs — they look like `100.x.x.x`. You will use these in the next steps. **Ask your AI:** "I have Tailscale installed on two machines. How do I verify they can reach each other using their Tailscale IPs?" --- ## Step 7B — Move the Shared Databases to kscloud1 For SSO to work properly across both machines, both Authentik instances must share one database. If they have separate databases, logins will fail roughly half the time. This means: - Move (or start fresh) Postgres and Redis on kscloud1 - Configure both monk and kscloud1's Authentik to point to kscloud1's database over Tailscale **On kscloud1**, create the database containers. Use the same passwords you used on monk: ```bash mkdir -p /opt/kitestacks/docker/authentik cd /opt/kitestacks/docker/authentik ``` Create `docker-compose.yml` with Postgres and Redis bound to the Tailscale IP: ```yaml services: authentik-postgres: image: postgres:16-alpine container_name: authentik-postgres restart: unless-stopped environment: POSTGRES_PASSWORD: your-db-password POSTGRES_USER: authentik POSTGRES_DB: authentik ports: - "100.123.x.x:5432:5432" # bind to Tailscale IP only volumes: - ./postgres:/var/lib/postgresql/data networks: - kitestacks authentik-redis: image: redis:alpine container_name: authentik-redis restart: unless-stopped ports: - "100.123.x.x:6379:6379" # bind to Tailscale IP only networks: - kitestacks networks: kitestacks: external: true ``` Replace `100.123.x.x` with kscloud1's actual Tailscale IP. ```bash docker compose up -d ``` **On monk**, update Authentik's environment to point to kscloud1's database: ``` AUTHENTIK_POSTGRESQL__HOST=100.123.x.x # kscloud1's Tailscale IP AUTHENTIK_REDIS__HOST=100.123.x.x ``` Restart Authentik on monk: ```bash cd ~/kitestacks-live/docker/authentik docker compose down docker compose up -d ``` **Ask your AI:** "I need to migrate my Authentik database from one host to another. How do I dump the data from my current Postgres and restore it on the new host?" --- ## Step 7C — Deploy All Services on kscloud1 Now deploy the same services on kscloud1. SSH into your VPS and create the same folder structure and docker-compose files that you have on monk. ```bash mkdir -p /opt/kitestacks/docker ``` For each service (forgejo, homepage, karakeep, kavita, grafana, etc.): 1. Create the folder: `mkdir -p /opt/kitestacks/docker/` 2. Copy your docker-compose.yml from monk (with any path changes for `/opt/kitestacks/`) 3. Copy your .env files 4. Run `docker compose up -d` The fastest way is to have your AI help you: > "I have all my services running on my home computer at ~/kitestacks-live/docker/. > I want to replicate them on my VPS at /opt/kitestacks/docker/. Can you help me > go through each service and identify what needs to change for the VPS environment?" **Important differences on kscloud1:** - Authentik already points to the shared Postgres/Redis (same as monk now) - Forgejo should also use the shared Postgres (add a `forgejo` database to it) - Paths use `/opt/kitestacks/` instead of `~/kitestacks-live/` --- ## Step 7D — Verify Failover Works With both machines running and both cloudflared connectors active, test that failover works: 1. In your Cloudflare Tunnel dashboard, you should see **2 connectors** 2. Visit your website from your phone (not connected to home WiFi) 3. Everything should work 4. Now stop monk's cloudflared: `cd ~/kitestacks-live/docker/cloudflared && docker compose stop` 5. Visit your website again from your phone 6. Everything should still work (kscloud1 is serving it) 7. Restart monk's cloudflared: `docker compose start cloudflared` If step 6 works, your cloud failover is complete. --- ## Step 7E — Set Up Uptime Kuma on kscloud1 Your Conky desktop widget reads Uptime Kuma from kscloud1 (not monk). Set it up there: Deploy uptime-kuma on kscloud1 the same way you did on monk. Then push your monitors from monk to kscloud1 by copying the database. **Ask your AI:** "How do I copy a SQLite database from one Docker container to another on a different machine, safely and without data corruption?" The trick is using Python's `sqlite3.backup()` method — it creates a consistent copy even while the database is in use. --- ## Checkpoint - [ ] Tailscale is installed on both machines and they can reach each other - [ ] Shared Postgres and Redis are running on kscloud1's Tailscale IP - [ ] Both Authentik instances (monk and kscloud1) point to the shared database - [ ] All 11 services are running on kscloud1 - [ ] Cloudflare Tunnel shows 2 connectors - [ ] Website works when monk's cloudflared is stopped --- **Next:** [Step 8 — Monitoring](08-monitoring.md)