Home Lab
Self-hosted infrastructure, CI/CD, and service operations.

Home Lab Infrastructure

Self-hosted infrastructure on a Synology DS923+ NAS, fully declarative, git-driven, and recoverable from a single TOML file.

4
Stacks
Docker Compose stacks
16
Containers
Running services
100%
IaC Coverage
TOML-defined via Komodo
DS923+
Platform
Synology NAS
Reverse Proxy Routing
komodo.local.example.comlocalhost:8120Komodo
gitea.local.example.comlocalhost:3000Gitea
photos.local.example.comlocalhost:2283Immich
budget.local.example.comlocalhost:5006Finance
forecast.local.example.comlocalhost:8080Finance

Architecture

All services run on a single Synology DS923+ NAS. Komodo manages Docker via a core/periphery architecture, with Synology's reverse proxy handling HTTPS termination and domain routing.

Users
Browser, any device on the local network
HTTPS
Synology Reverse Proxy
DSM Application Portal: TLS termination & virtual host routing
Virtual host routing
Synology DS923+ NAS
Komodo
3 containers
komodo-coreUI + API
komodo-peripheryAgent
mongo:7Config DB
Gitea
3 containers
giteaGit + CI
act_runnerCI Runner
postgres:14Metadata DB
Immich
6 containers
immich-serverAPI + Web
immich-microservicesWorkers
immich-mlML Inference
redisJob Queue
pgvecto-rsVector DB
immichframeFrame
Finance
4 containers
actual-serverBudget
forecast-backendFastAPI
forecast-frontendReact/Nginx
postgres:16Forecast DB
External Integrations
Synology SSO
OIDC
Central auth for Komodo and Finance
Watchtower
Docker API
Auto image updates, DB containers excluded via labels
Periphery Agent
Docker API
Executes stack deploys and local image builds
Single-node — 16 containers across 4 stacks, 100% IaC via Komodo ResourceSync — full environment reproducible from komodo-configs + env files

Stack Explorer

Four Docker Compose stacks defined declaratively in a single resources.toml file. Select a stack to explore its containers, volumes, and networking.

Komodo Infrastructure
Docker management platform with git-native IaC. All stacks, builds, procedures, and alerters defined declaratively in TOML and synced from a git repo.
Skills Demonstrated
Infrastructure as CodeOIDC/SSO integrationWebhook-driven automationDeclarative configuration management
Containers
komodo-core
ghcr.io/moghtech/komodo-core
HTTP
Web UI + API server with OIDC authentication
komodo-periphery
ghcr.io/moghtech/komodo-periphery
Agent that executes builds, deploys stacks, and runs shell actions
komodo-mongo
mongo:7
Configuration state database

CI/CD & Infrastructure as Code

Two webhook-driven pipelines: application builds triggered by code pushes, and infrastructure updates triggered by config changes.

Application CI/CD Pipeline

Git push triggers a Komodo Procedure that builds backend and frontend images in parallel, then redeploys the Finance stack.

Git Push
main branch → Gitea
Webhook
Gitea Webhook
POST to Komodo API
Triggers
Komodo Procedure
build-and-deploy-finance
Orchestrates parallel builds then deploys
Parallel
Build Backend
forecast-backend:latest
FastAPIDocker
Build Frontend
forecast-frontend:latest
ReactNginx
Both complete
Deploy Stack
docker compose up — Finance stack
Redeploy
Near-zero-downtime for stateless containers — Compose recreates only changed images, DB containers are excluded via labels

Infrastructure-as-Code Loop

Pushing to komodo-configs triggers ResourceSync, which applies resources.toml and fans out to update Stacks, Builds, Procedures, and Alerters.

Push to komodo-configs
TOML resource definitions
Webhook
PullRepo
Sync git changes to local clone
Triggers
ResourceSync
Apply resources.toml
Declarative diff & apply to all resource types
Fan-out
Stacks
Compose files
Builds
Image configs
Procedures
Automation
Alerters
Notifications
Adding a new service means adding a TOML block — ResourceSync handles the diff, creation, and deployment automatically

Automation

Database Backups
Weekly
Automated pg_dump of all PostgreSQL databases
Scheduled Komodo procedure runs pg_dump inside each PostgreSQL container, compresses with gzip, and stores timestamped backups on NAS volumes.
Docker Cleanup
Weekly
Prune unused images, containers, and volumes
Automated system prune reclaims disk from orphaned layers and build cache. Runs after backups complete.
Watchtower Updates
Continuous
Automatic container image updates
Label-based opt-in: watches containers for new image versions, pulls and restarts automatically. Database containers excluded to prevent unplanned migrations.
Alerter Relay
Real-time
Komodo alerts forwarded to chat
Custom Flask relay receives Komodo webhooks, formats alert messages with container stats (CPU/memory), and posts to a chat channel. Shows top 5 resource consumers.
Disaster Recovery
Full environment rebuild from komodo-configs repo + env files + Synology backup restore:
1
Deploy Komodo
Single docker compose up bootstraps the management platform
2
ResourceSync
Git repo sync recreates all stacks, builds, procedures, and alerters from TOML
3
Inject secrets
Place environment files for each stack (stored separately from IaC repo)
4
Deploy stacks
Deploy all 4 stacks via Komodo; containers come up with declarative config
5
Restore data
Restore database dumps + NAS volume snapshots for stateful data
6
Verify
Health endpoint checks, SSO login test, webhook trigger verification

Decisions

Key architectural and operational decisions with rationale.

Platform

Komodo over Portainer

Replaced Portainer with Komodo for git-native infrastructure-as-code, webhook-triggered deployments, and declarative TOML resource definitions.

Thinking

Portainer is a solid GUI for Docker management but lacks native git integration. Every change was manual and not version-controlled. Komodo treats infrastructure definitions as code: a single resources.toml in a git repo defines all stacks, builds, procedures, and alerters. Push to main triggers ResourceSync, making the entire environment reproducible.

1 / 5