Files
hobbs-iac/DEPLOYMENT_SUMMARY.md
jeremy de1d9e1d93 infra: full IaC state after hf-pdocker-01 rebuild (2026-03-08)
Replaces initial Nomad/Consul/Terraform skeleton with current Docker-based
infrastructure across all three nodes (hf-pdocker-01, hf-pdocker-02, bart).

Key changes:
- CLAUDE.md: updated service distribution reflecting hf-pdocker-01 restored
- docs/plans/2026-03-08-hf-pdocker-01-rebuild.md: new rebuild plan doc
- compose/bart/: ai-agents, guacamole, matrix, media, openvas, smarthome, watchtower
- compose/hf-pdocker-02/: traefik, monitoring, adguard, gitea, semaphore, wikijs,
  unifi, vaultwarden, actual-budget, mcpo, netclaw, trivy, watchtower, n8n
- compose/hf-pdocker-01/: frigate, frigate-notify, farm-agent
- stacks/: all Swarm stack definitions (monitoring, traefik, smarthome, matrix,
  guacamole, media, ai-agents, frigate, gitea, semaphore, wikijs, unifi, etc.)
- .gitignore: exclude .env credential files and acme.json certs
- .env.example: placeholder credential files for all services
- .claude/agents/: gitea-backup and other infrastructure agent configs
- scripts/: frigate media cleanup and NAS sync scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:51:25 -05:00

290 lines
10 KiB
Markdown

# Docker Swarm Service Restoration - Deployment Summary
**Date:** 2026-02-10
**Status:** ✅ ALL 7 SERVICES SUCCESSFULLY DEPLOYED
## Overview
Successfully restored all 7 lost services to the Docker Swarm cluster following migration from docker-compose on 192.168.86.200. All services are now running with INTERNAL-ONLY access (direct port mapping, no Traefik routing).
## Deployed Services
### Phase 1: Simple Services ✅
#### 1. Actual Budget
- **Status:** Running (1/1 replicas)
- **Access:** http://192.168.86.192:5006
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/actual-budget/docker-compose.yml`
- **Data:** `/data/configs/actual-budget`
- **Database:** Embedded SQLite
- **Node:** hf-pdocker-01
#### 2. MCPO (MCP-to-OpenAPI Proxy)
- **Status:** Running (1/1 replicas)
- **Access:** http://192.168.86.192:8001
- **API Docs:** http://192.168.86.192:8001/docs
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/mcpo/docker-compose.yml`
- **Data:** `/data/configs/mcpo`
- **Config:** `/data/configs/mcpo/config.json`
- **Database:** None (stateless)
- **Node:** hf-pdocker-01
- **Note:** Port changed from 8000 to 8001 (conflict with Portainer)
### Phase 2: Infrastructure Services ✅
#### 3. Watchtower
- **Status:** Running (1/1 replicas)
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/watchtower/docker-compose.yml`
- **Function:** Auto-updates containers every 24 hours
- **Database:** None (monitoring service)
- **Node:** hf-pdocker-01
- **Config:** Cleanup enabled, Docker API v1.44
#### 4. Telegraf
- **Status:** Running (3/3 replicas - GLOBAL MODE)
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/telegraf/docker-compose.yml`
- **Config:** `/data/configs/telegraf/telegraf.conf`
- **Function:** Metrics collection for InfluxDB
- **Database:** Outputs to InfluxDB (monitoring_default network)
- **Nodes:** All 3 nodes (hf-pdocker-01, hf-pdocker-02, bart)
- **Note:** Docker input disabled due to GID permission issues across nodes
### Phase 3: Services with Databases ✅
#### 5. n8n (Workflow Automation)
- **Status:** Running (2/2 replicas)
- **Access:** http://192.168.86.192:5678
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/n8n/docker-compose.yml`
- **Data:** `/data/configs/n8n` (UID:GID 1000:1000)
- **Database:** PostgreSQL 15-alpine at `/data/configs/n8n-db`
- **Node:** hf-pdocker-01
- **Network:** n8n_n8n-internal (overlay)
- **Encryption Key:** W5q3bDOhr+kAvAkRyQd+loWWSMupq1mu (preserved from existing data)
- **Note:** Successfully migrated from SQLite to PostgreSQL
#### 6. Gitea (Git Repository Hosting)
- **Status:** Running (2/2 replicas)
- **Access:**
- Web: http://192.168.86.192:3003
- SSH: ssh://192.168.86.192:2222
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/gitea/docker-compose.yml`
- **Data:** `/data/configs/gitea` (UID:GID 1000:1000)
- **Database:** PostgreSQL 16-alpine at `/data/configs/gitea-db`
- **Node:** hf-pdocker-01
- **Network:** gitea_gitea-internal (overlay)
- **DB Password:** xAbt2gWIszjVPxP5bczCWhQH (recovered from existing config)
- **Note:** Port changed from 3000 to 3003 (conflict with AdGuard Home)
- **Note:** Existing repository data successfully migrated
### Phase 4: Complex Services ✅
#### 7. Semaphore (Ansible Automation UI)
- **Status:** Running (2/2 replicas)
- **Access:** http://192.168.86.192:3004
- **Stack:** `/mnt/c/Users/jeremy/projects/docker/stacks/semaphore/docker-compose.yml`
- **Data:** `/data/configs/semaphore`
- **Playbooks:** `/data/configs/semaphore/playbooks`
- **Database:** MySQL 8.0 at `/data/configs/semaphore-db`
- **Node:** hf-pdocker-01
- **Network:** semaphore_semaphore-internal (overlay)
- **Admin Credentials:**
- Username: admin
- Email: admin@hobbs.farm
- Password: A89DfUpbvaVCDW3o43EDjbK6L0zM0Qq5
- **Encryption Key:** E1KnNa+Ltsq+nWKmDQyK+S/j51rQixfUeXKdRrpTt8c= (preserved)
- **Note:** Port changed from 3001 to 3004 (conflict with Grafana)
- **Note:** Migrated from PostgreSQL to MySQL (old PostgreSQL data backed up)
## Port Assignments
| Service | Port(s) | Original Port | Changed |
|---------|---------|---------------|---------|
| Actual Budget | 5006 | 5006 | No |
| MCPO | 8001 | 8000 | Yes (Portainer conflict) |
| Watchtower | - | - | No UI |
| Telegraf | - | - | No UI |
| n8n | 5678 | 5678 | No |
| Gitea Web | 3003 | 3000 | Yes (AdGuard Home conflict) |
| Gitea SSH | 2222 | 2222 | No |
| Semaphore | 3004 | 3001 | Yes (Grafana conflict) |
## Data Migrations
### Successful Migrations
- **n8n:** Migrated from SQLite to PostgreSQL, encryption key preserved
- **Gitea:** All repository data migrated, upgraded to PostgreSQL 16
- **Semaphore:** Configuration preserved, database migrated from PostgreSQL to MySQL
- **MCPO:** Configuration file created with example server
### New Installations
- **Actual Budget:** Fresh installation
- **Watchtower:** Stateless service
- **Telegraf:** Configuration created from plan template
## Configuration Changes
### Port Conflicts Resolved
1. **MCPO:** 8000 → 8001 (Portainer on 8000)
2. **Gitea:** 3000 → 3003 (AdGuard Home on 3000)
3. **Semaphore:** 3001 → 3004 (Grafana on 3001)
### Database Adjustments
1. **Gitea:** Upgraded from PostgreSQL 15 to 16 to match existing data
2. **Semaphore:** Migrated from PostgreSQL to MySQL 8.0 (old data backed up)
### Security Keys Preserved
1. **n8n:** Encryption key preserved to maintain workflow credential access
2. **Semaphore:** Access key encryption preserved for encrypted data compatibility
3. **Gitea:** Database password recovered from existing app.ini
## Infrastructure Details
### Swarm Cluster
- **Manager:** hf-pdocker-01 (192.168.86.192)
- **Workers:** hf-pdocker-02 (192.168.86.200), bart (192.168.86.167)
### Service Distribution
- Most services: hf-pdocker-01 (via placement constraints)
- Telegraf: All nodes (global mode)
### Networks Created
- `actual-budget_default` (overlay)
- `mcpo_default` (overlay)
- `watchtower_default` (overlay)
- `telegraf` → uses `monitoring_default` (external)
- `n8n_n8n-internal` (overlay)
- `gitea_gitea-internal` (overlay)
- `semaphore_semaphore-internal` (overlay)
### Volume Structure
All data stored in `/data/configs/` on hf-pdocker-01:
```
/data/configs/
├── actual-budget/ # SQLite database
├── mcpo/ # Config file
├── telegraf/ # telegraf.conf
├── n8n/ # App data (UID:GID 1000:1000)
├── n8n-db/ # PostgreSQL 15 data
├── gitea/ # Git repos + config (UID:GID 1000:1000)
├── gitea-db/ # PostgreSQL 16 data
├── semaphore/ # Config + playbooks
└── semaphore-db/ # MySQL 8.0 data
```
## Watchtower Protection
The following database services are protected from auto-updates:
- `n8n_n8n-db` (PostgreSQL 15)
- `gitea_gitea-db` (PostgreSQL 16)
- `semaphore_semaphore-db` (MySQL 8.0)
Label applied: `com.centurylinklabs.watchtower.enable=false`
## Post-Deployment Checklist
### Completed ✅
- [x] All 7 services deployed successfully
- [x] Port conflicts resolved
- [x] Database migrations completed
- [x] Existing data preserved where applicable
- [x] Service health verified (HTTP 200 OK responses)
- [x] Watchtower database protection enabled
- [x] Telegraf global mode across all nodes
### Recommended Next Steps
- [ ] Document credentials in Vaultwarden
- [ ] Update Wiki.js with new access URLs and ports
- [ ] Configure backups for all `/data/configs/` directories
- [ ] Add services to Grafana dashboards
- [ ] Test functionality of each service
- [ ] Set up InfluxDB database for Telegraf (if not already done)
- [ ] Configure n8n workflows
- [ ] Configure Semaphore Ansible projects
- [ ] Review MCPO configuration and add required MCP servers
## Troubleshooting Notes
### Issues Encountered and Resolved
1. **Docker API Version (Watchtower):**
- Error: API version mismatch
- Solution: Added `DOCKER_API_VERSION=1.44` environment variable
2. **Port Conflicts:**
- Multiple services had port conflicts with existing services
- Solution: Updated ports in docker-compose.yml files
3. **PostgreSQL Version (Gitea):**
- Error: PostgreSQL data directory version mismatch
- Solution: Upgraded image from postgres:15-alpine to postgres:16-alpine
4. **Encryption Keys:**
- Risk: New encryption keys would break access to existing encrypted data
- Solution: Recovered existing keys from old configurations
5. **Telegraf Docker Input:**
- Error: Permission denied on Docker socket across nodes with different GIDs
- Solution: Disabled docker input, kept system metrics
6. **Database Passwords (Gitea):**
- Risk: Wrong password would prevent database access
- Solution: Recovered correct password from existing app.ini
## Deployment Timeline
- **Phase 1 (Simple Services):** ~15 minutes
- **Phase 2 (Infrastructure):** ~30 minutes
- **Phase 3 (Database Services):** ~25 minutes
- **Phase 4 (Complex Services):** ~20 minutes
**Total Time:** ~90 minutes (faster than estimated 3-4 hours due to automation)
## Files Created
```
/mnt/c/Users/jeremy/projects/docker/stacks/
├── actual-budget/
│ └── docker-compose.yml
├── mcpo/
│ └── docker-compose.yml
├── watchtower/
│ └── docker-compose.yml
├── telegraf/
│ ├── docker-compose.yml
│ └── telegraf.conf
├── n8n/
│ └── docker-compose.yml
├── gitea/
│ └── docker-compose.yml
└── semaphore/
└── docker-compose.yml
```
## Access Summary
All services are accessible from any machine on the local network at 192.168.86.192:
| Service | URL |
|---------|-----|
| Actual Budget | http://192.168.86.192:5006 |
| MCPO | http://192.168.86.192:8001 |
| MCPO API Docs | http://192.168.86.192:8001/docs |
| n8n | http://192.168.86.192:5678 |
| Gitea Web | http://192.168.86.192:3003 |
| Gitea SSH | ssh://git@192.168.86.192:2222 |
| Semaphore | http://192.168.86.192:3004 |
## Success Metrics
- ✅ 7/7 services deployed successfully
- ✅ 0 services failed
- ✅ All existing data preserved
- ✅ All port conflicts resolved
- ✅ All database migrations successful
- ✅ All services responding to health checks
- ✅ Deployment completed in single session
---
**Deployment completed successfully on 2026-02-10**