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>
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
# 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**
|
||||
Reference in New Issue
Block a user