569 lines
15 KiB
Markdown
569 lines
15 KiB
Markdown
|
|
# CapRover Migration Implementation Plan
|
||
|
|
|
||
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||
|
|
|
||
|
|
**Goal:** Migrate Vaultwarden, n8n, Forgejo, and NocoDB from CapRover to the OVH production server, plus add Watchtower for automatic container updates.
|
||
|
|
|
||
|
|
**Architecture:** Each service is an independent Docker Compose stack under `~/services/SERVICE_NAME/` on the OVH server (15.204.247.153). Traefik handles SSL termination and routing. The existing `~/services/backup.sh` auto-discovers all services — no backup configuration needed per service. Services are deployed in two batches: Watchtower first, then Vaultwarden + n8n in parallel, then Forgejo + NocoDB in parallel.
|
||
|
|
|
||
|
|
**Tech Stack:** Docker Compose, Traefik v3.0, Let's Encrypt, nicholas-fedor/watchtower, vaultwarden/server, n8nio/n8n, codeberg.org/forgejo/forgejo, nocodb/nocodb
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Batch 0: Watchtower
|
||
|
|
|
||
|
|
### Task 1: Create Watchtower compose file
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Create: `configs/watchtower/docker-compose.yml` (in this repo, for reference)
|
||
|
|
|
||
|
|
**Step 1: Create the compose file locally**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# configs/watchtower/docker-compose.yml
|
||
|
|
services:
|
||
|
|
watchtower:
|
||
|
|
image: nicholas-fedor/watchtower
|
||
|
|
restart: unless-stopped
|
||
|
|
volumes:
|
||
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
||
|
|
environment:
|
||
|
|
- WATCHTOWER_SCHEDULE=0 0 3 * * *
|
||
|
|
- WATCHTOWER_CLEANUP=true
|
||
|
|
- WATCHTOWER_INCLUDE_STOPPED=false
|
||
|
|
- WATCHTOWER_NOTIFICATIONS_LEVEL=warn
|
||
|
|
command: --schedule "0 0 3 * * *"
|
||
|
|
```
|
||
|
|
|
||
|
|
Note: No networks needed — Watchtower talks to the Docker daemon directly via the socket. Runs at 3 AM daily. `WATCHTOWER_CLEANUP=true` removes old images after updating.
|
||
|
|
|
||
|
|
**Step 2: Commit the config**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add configs/watchtower/docker-compose.yml
|
||
|
|
git commit -m "chore: add watchtower compose config"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 2: Deploy Watchtower on OVH
|
||
|
|
|
||
|
|
**Step 1: Create service directory on remote server**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "mkdir -p ~/services/watchtower"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Copy compose file to server**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
scp configs/watchtower/docker-compose.yml jared@15.204.247.153:~/services/watchtower/
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 3: Start Watchtower**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "cd ~/services/watchtower && docker compose up -d"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 4: Verify it's running**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker ps | grep watchtower"
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: one `watchtower` container in `Up` state.
|
||
|
|
|
||
|
|
**Step 5: Check logs to confirm it's watching containers**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker logs watchtower --tail 20"
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: logs showing it has found and is monitoring existing containers.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Batch 1: Vaultwarden + n8n (deploy in parallel)
|
||
|
|
|
||
|
|
### Task 3: Create Vaultwarden compose file
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Create: `configs/vaultwarden/docker-compose.yml`
|
||
|
|
|
||
|
|
**Step 1: Create the compose file**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# configs/vaultwarden/docker-compose.yml
|
||
|
|
services:
|
||
|
|
vaultwarden:
|
||
|
|
image: vaultwarden/server:latest
|
||
|
|
restart: unless-stopped
|
||
|
|
volumes:
|
||
|
|
- ./data:/data
|
||
|
|
networks:
|
||
|
|
- traefik
|
||
|
|
labels:
|
||
|
|
- "traefik.enable=true"
|
||
|
|
- "traefik.http.routers.vaultwarden.rule=Host(`bitwarden.swansoncloud.com`)"
|
||
|
|
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
|
||
|
|
- "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
|
||
|
|
- "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
|
||
|
|
- "traefik.docker.network=traefik"
|
||
|
|
|
||
|
|
networks:
|
||
|
|
traefik:
|
||
|
|
external: true
|
||
|
|
```
|
||
|
|
|
||
|
|
Note: Modern Vaultwarden (post-1.25) handles WebSocket on port 80 — no separate router needed for `/notifications/hub`.
|
||
|
|
|
||
|
|
**Step 2: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add configs/vaultwarden/docker-compose.yml
|
||
|
|
git commit -m "chore: add vaultwarden compose config"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 4: Migrate Vaultwarden data from CapRover
|
||
|
|
|
||
|
|
**Step 1: SSH into the CapRover server and locate the Vaultwarden data directory**
|
||
|
|
|
||
|
|
The CapRover persistent data path is typically at:
|
||
|
|
`/var/lib/docker/volumes/captain--vaultwarden--1-data/_data/`
|
||
|
|
|
||
|
|
SSH into CapRover and confirm:
|
||
|
|
```bash
|
||
|
|
# On CapRover server
|
||
|
|
ls /var/lib/docker/volumes/ | grep vaultwarden
|
||
|
|
ls /var/lib/docker/volumes/captain--vaultwarden--1-data/_data/
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected contents: `db.sqlite3`, `config.json`, `attachments/`, `sends/`
|
||
|
|
|
||
|
|
**Step 2: Copy data dir from CapRover to OVH**
|
||
|
|
|
||
|
|
Create the destination directory on OVH first:
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "mkdir -p ~/services/vaultwarden/data"
|
||
|
|
```
|
||
|
|
|
||
|
|
Then from CapRover server (or via local machine as relay):
|
||
|
|
```bash
|
||
|
|
# Option A: If you can SSH from CapRover to OVH directly
|
||
|
|
scp -r /var/lib/docker/volumes/captain--vaultwarden--1-data/_data/* jared@15.204.247.153:~/services/vaultwarden/data/
|
||
|
|
|
||
|
|
# Option B: Via your local machine (two-hop)
|
||
|
|
# First download from CapRover to local:
|
||
|
|
scp -r root@CAPROVER_IP:/var/lib/docker/volumes/captain--vaultwarden--1-data/_data/ ./vaultwarden-backup/
|
||
|
|
# Then upload to OVH:
|
||
|
|
scp -r ./vaultwarden-backup/ jared@15.204.247.153:~/services/vaultwarden/data/
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 3: Verify files landed on OVH**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "ls -la ~/services/vaultwarden/data/"
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: `db.sqlite3` present, `config.json` present.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 5: Deploy Vaultwarden on OVH
|
||
|
|
|
||
|
|
**Step 1: Copy compose file to server**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
scp configs/vaultwarden/docker-compose.yml jared@15.204.247.153:~/services/vaultwarden/
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Start Vaultwarden**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "cd ~/services/vaultwarden && docker compose up -d"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 3: Verify container is running**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker ps | grep vaultwarden"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 4: Test via temporary access (before DNS cutover)**
|
||
|
|
|
||
|
|
Access via direct IP to confirm Traefik is routing it (will show SSL warning, that's fine):
|
||
|
|
```
|
||
|
|
http://15.204.247.153
|
||
|
|
```
|
||
|
|
|
||
|
|
Or check Traefik dashboard at https://traefik.hyperthrive.app to confirm the `vaultwarden` router appears.
|
||
|
|
|
||
|
|
**Step 5: Check logs for errors**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker logs vaultwarden-vaultwarden-1 --tail 30"
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: No errors. Should see startup messages and database initialization.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 6: Cut DNS for Vaultwarden + verify
|
||
|
|
|
||
|
|
**Step 1: Update DNS**
|
||
|
|
|
||
|
|
In your DNS provider, update `bitwarden.swansoncloud.com` A record to point to `15.204.247.153`.
|
||
|
|
|
||
|
|
**Step 2: Wait for DNS propagation (~2-5 minutes), then test**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -I https://bitwarden.swansoncloud.com
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: HTTP 200 response.
|
||
|
|
|
||
|
|
**Step 3: Verify vault unlocks**
|
||
|
|
|
||
|
|
Open https://bitwarden.swansoncloud.com in browser — confirm you can log in and your vault data is present.
|
||
|
|
|
||
|
|
**Step 4: Test browser extension**
|
||
|
|
|
||
|
|
Re-connect your Bitwarden browser extension to the new server URL and confirm it syncs.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 7: Create n8n compose file
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Create: `configs/n8n-swanson/docker-compose.yml`
|
||
|
|
|
||
|
|
**Step 1: Check existing n8n instances on OVH for pattern consistency**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "cat ~/services/n8n*/docker-compose.yml 2>/dev/null || ls ~/services/ | grep n8n"
|
||
|
|
```
|
||
|
|
|
||
|
|
Adapt the compose below to match any conventions found.
|
||
|
|
|
||
|
|
**Step 2: Create the compose file**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# configs/n8n-swanson/docker-compose.yml
|
||
|
|
services:
|
||
|
|
n8n:
|
||
|
|
image: n8nio/n8n
|
||
|
|
restart: unless-stopped
|
||
|
|
environment:
|
||
|
|
- N8N_HOST=n8n.swansoncloud.com
|
||
|
|
- N8N_PORT=5678
|
||
|
|
- N8N_PROTOCOL=https
|
||
|
|
- WEBHOOK_URL=https://n8n.swansoncloud.com/
|
||
|
|
- N8N_SECURE_COOKIE=false
|
||
|
|
- TZ=America/Chicago
|
||
|
|
volumes:
|
||
|
|
- ./data:/home/node/.n8n
|
||
|
|
networks:
|
||
|
|
- traefik
|
||
|
|
labels:
|
||
|
|
- "traefik.enable=true"
|
||
|
|
- "traefik.http.routers.n8n-swanson.rule=Host(`n8n.swansoncloud.com`)"
|
||
|
|
- "traefik.http.routers.n8n-swanson.entrypoints=websecure"
|
||
|
|
- "traefik.http.routers.n8n-swanson.tls.certresolver=letsencrypt"
|
||
|
|
- "traefik.http.services.n8n-swanson.loadbalancer.server.port=5678"
|
||
|
|
- "traefik.docker.network=traefik"
|
||
|
|
|
||
|
|
networks:
|
||
|
|
traefik:
|
||
|
|
external: true
|
||
|
|
```
|
||
|
|
|
||
|
|
Note: Router name is `n8n-swanson` (not just `n8n`) to avoid collision with existing n8n instances on this server.
|
||
|
|
|
||
|
|
**Step 3: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add configs/n8n-swanson/docker-compose.yml
|
||
|
|
git commit -m "chore: add n8n swansoncloud compose config"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 8: Deploy n8n on OVH
|
||
|
|
|
||
|
|
**Step 1: Create service directory and deploy**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "mkdir -p ~/services/n8n-swanson"
|
||
|
|
scp configs/n8n-swanson/docker-compose.yml jared@15.204.247.153:~/services/n8n-swanson/
|
||
|
|
ssh jared@15.204.247.153 "cd ~/services/n8n-swanson && docker compose up -d"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Verify container is running**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker ps | grep n8n-swanson"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 3: Cut DNS**
|
||
|
|
|
||
|
|
Update `n8n.swansoncloud.com` A record → `15.204.247.153`.
|
||
|
|
|
||
|
|
**Step 4: Verify n8n is accessible**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -I https://n8n.swansoncloud.com
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: HTTP 200. Open in browser and complete initial setup (create admin account).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Batch 2: Forgejo + NocoDB (deploy in parallel)
|
||
|
|
|
||
|
|
### Task 9: Create Forgejo compose file
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Create: `configs/forgejo/docker-compose.yml`
|
||
|
|
|
||
|
|
**Step 1: Create the compose file**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# configs/forgejo/docker-compose.yml
|
||
|
|
services:
|
||
|
|
forgejo:
|
||
|
|
image: codeberg.org/forgejo/forgejo:latest
|
||
|
|
restart: unless-stopped
|
||
|
|
environment:
|
||
|
|
- USER_UID=1000
|
||
|
|
- USER_GID=1000
|
||
|
|
volumes:
|
||
|
|
- ./data:/data
|
||
|
|
networks:
|
||
|
|
- traefik
|
||
|
|
labels:
|
||
|
|
- "traefik.enable=true"
|
||
|
|
- "traefik.http.routers.forgejo.rule=Host(`forgejo.swansoncloud.com`)"
|
||
|
|
- "traefik.http.routers.forgejo.entrypoints=websecure"
|
||
|
|
- "traefik.http.routers.forgejo.tls.certresolver=letsencrypt"
|
||
|
|
- "traefik.http.services.forgejo.loadbalancer.server.port=3000"
|
||
|
|
- "traefik.docker.network=traefik"
|
||
|
|
|
||
|
|
networks:
|
||
|
|
traefik:
|
||
|
|
external: true
|
||
|
|
```
|
||
|
|
|
||
|
|
Note: SQLite is the default and sufficient for 2 repos. No external database needed. SSH git access is omitted — HTTPS is fine for personal use.
|
||
|
|
|
||
|
|
**Step 2: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add configs/forgejo/docker-compose.yml
|
||
|
|
git commit -m "chore: add forgejo compose config"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 10: Deploy Forgejo on OVH
|
||
|
|
|
||
|
|
**Step 1: Create service directory and deploy**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "mkdir -p ~/services/forgejo"
|
||
|
|
scp configs/forgejo/docker-compose.yml jared@15.204.247.153:~/services/forgejo/
|
||
|
|
ssh jared@15.204.247.153 "cd ~/services/forgejo && docker compose up -d"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Verify container is running**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker ps | grep forgejo"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 3: Cut DNS**
|
||
|
|
|
||
|
|
Update `forgejo.swansoncloud.com` A record → `15.204.247.153`.
|
||
|
|
|
||
|
|
**Step 4: Access web UI and complete initial setup**
|
||
|
|
|
||
|
|
Open https://forgejo.swansoncloud.com — Forgejo will show a first-run setup page. Configure:
|
||
|
|
- Database: SQLite (default)
|
||
|
|
- Site URL: `https://forgejo.swansoncloud.com`
|
||
|
|
- Admin username/password
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 11: Migrate Gitea repos to Forgejo
|
||
|
|
|
||
|
|
**Step 1: In Forgejo web UI, use the built-in migration tool**
|
||
|
|
|
||
|
|
Go to: https://forgejo.swansoncloud.com → `+` (New) → `Migrate Repository`
|
||
|
|
|
||
|
|
Select: **Gitea** as the source type.
|
||
|
|
|
||
|
|
**Step 2: For each repo at gitea.swansoncloud.com/explore/repos**
|
||
|
|
|
||
|
|
Fill in:
|
||
|
|
- Clone URL: `https://gitea.swansoncloud.com/USERNAME/REPO_NAME.git`
|
||
|
|
- If Gitea requires auth, provide credentials
|
||
|
|
|
||
|
|
Forgejo will pull the full git history, issues, and wiki (if any).
|
||
|
|
|
||
|
|
Repeat for all repos (there are 2).
|
||
|
|
|
||
|
|
**Step 3: Verify repos migrated**
|
||
|
|
|
||
|
|
Confirm both repos appear at https://forgejo.swansoncloud.com with full commit history.
|
||
|
|
|
||
|
|
**Step 4: Update any local git remotes**
|
||
|
|
|
||
|
|
On your local machine, update remotes from `gitea.swansoncloud.com` → `forgejo.swansoncloud.com`:
|
||
|
|
```bash
|
||
|
|
git remote set-url origin https://forgejo.swansoncloud.com/USERNAME/REPO_NAME.git
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 12: Create NocoDB compose file
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Create: `configs/nocodb/docker-compose.yml`
|
||
|
|
|
||
|
|
**Step 1: Create the compose file**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# configs/nocodb/docker-compose.yml
|
||
|
|
services:
|
||
|
|
nocodb:
|
||
|
|
image: nocodb/nocodb:latest
|
||
|
|
restart: unless-stopped
|
||
|
|
volumes:
|
||
|
|
- ./data:/usr/app/data
|
||
|
|
networks:
|
||
|
|
- traefik
|
||
|
|
labels:
|
||
|
|
- "traefik.enable=true"
|
||
|
|
- "traefik.http.routers.nocodb.rule=Host(`nocodb.swansoncloud.com`)"
|
||
|
|
- "traefik.http.routers.nocodb.entrypoints=websecure"
|
||
|
|
- "traefik.http.routers.nocodb.tls.certresolver=letsencrypt"
|
||
|
|
- "traefik.http.services.nocodb.loadbalancer.server.port=8080"
|
||
|
|
- "traefik.docker.network=traefik"
|
||
|
|
|
||
|
|
networks:
|
||
|
|
traefik:
|
||
|
|
external: true
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add configs/nocodb/docker-compose.yml
|
||
|
|
git commit -m "chore: add nocodb compose config"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 13: Deploy NocoDB on OVH
|
||
|
|
|
||
|
|
**Step 1: Create service directory and deploy**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "mkdir -p ~/services/nocodb"
|
||
|
|
scp configs/nocodb/docker-compose.yml jared@15.204.247.153:~/services/nocodb/
|
||
|
|
ssh jared@15.204.247.153 "cd ~/services/nocodb && docker compose up -d"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Verify container is running**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "docker ps | grep nocodb"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 3: Cut DNS**
|
||
|
|
|
||
|
|
Update `nocodb.swansoncloud.com` A record → `15.204.247.153`.
|
||
|
|
|
||
|
|
**Step 4: Verify NocoDB is accessible and complete setup**
|
||
|
|
|
||
|
|
Open https://nocodb.swansoncloud.com — create admin account on first run.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Batch 3: Verification & Cleanup
|
||
|
|
|
||
|
|
### Task 14: Verify backup coverage for all new services
|
||
|
|
|
||
|
|
**Step 1: Run backup script manually**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "~/services/backup.sh"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Verify all 4 new services are discovered**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh jared@15.204.247.153 "tar -tzf ~/backups/current/latest.tar.gz | grep -E 'vaultwarden|n8n-swanson|forgejo|nocodb'"
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: entries for all four services.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 15: Update services inventory doc
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `docs/services-inventory.md`
|
||
|
|
|
||
|
|
Add entries for all 4 new services + Watchtower. Follow existing format in the file. Include:
|
||
|
|
- Service name
|
||
|
|
- Domain
|
||
|
|
- Container name(s)
|
||
|
|
- Image
|
||
|
|
- Data path on server
|
||
|
|
- Deployment date (today: 2026-03-18)
|
||
|
|
- Status: ✅ LIVE
|
||
|
|
|
||
|
|
**Commit:**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add docs/services-inventory.md
|
||
|
|
git commit -m "docs: update services inventory with migrated services"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 16: Decommission CapRover services
|
||
|
|
|
||
|
|
Once all DNS records are confirmed healthy and pointing to OVH:
|
||
|
|
|
||
|
|
**Step 1: Confirm all 4 services are live on OVH**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -I https://bitwarden.swansoncloud.com
|
||
|
|
curl -I https://n8n.swansoncloud.com
|
||
|
|
curl -I https://forgejo.swansoncloud.com
|
||
|
|
curl -I https://nocodb.swansoncloud.com
|
||
|
|
```
|
||
|
|
|
||
|
|
All should return HTTP 200.
|
||
|
|
|
||
|
|
**Step 2: Stop services on CapRover**
|
||
|
|
|
||
|
|
In the CapRover dashboard, stop (do not delete yet) Vaultwarden, n8n, Gitea, and NocoDB. Leave them stopped for 48 hours as a rollback window.
|
||
|
|
|
||
|
|
**Step 3: After 48 hours, delete CapRover apps and decommission server**
|
||
|
|
|
||
|
|
Once confident everything is working, delete the CapRover apps and shut down the CapRover server.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Post-Migration Reminders
|
||
|
|
|
||
|
|
These tasks are tracked separately and should be done after all services are live:
|
||
|
|
|
||
|
|
1. **Fireflies.ai automation** — Set up n8n workflow to retrieve meeting transcripts from Fireflies.ai and back them up. (See task tracker)
|
||
|
|
2. **hyperthrive.io contact form** — Set up n8n workflow for contact form submissions on hyperthrive.io. (See task tracker)
|