dasphere - short for data-sphere.
Find a file
2026-02-08 22:14:21 +01:00
nix Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00
scripts Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00
secrets Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00
templates Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00
.gitignore Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00
cloud-init.yaml Initial commit 2026-02-08 17:04:06 +01:00
config.yaml.example Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00
README.md Update with unreviewed LLM result 2026-02-08 22:14:21 +01:00

Dasphere

Rebuildable containerized multi-service single node (VM) deployment

Dasphere is an automated infrastructure-as-code solution for deploying self-hosted services on Hetzner Cloud using NixOS. It provides a complete platform with mandatory baseline services (VPN, firewall, reverse proxy, monitoring, backups, IdP) plus optional applications (Seafile, Jellyfin, Forgejo, etc.).

Status

🎉 Ready to Deploy! - Complete NixOS-based infrastructure with automated deployment to Hetzner Cloud.

What's Implemented

NixOS Configuration (NixOS 25.11)

  • Complete flake-based system configuration
  • Disk layout with disko (GRUB, ext4, GPT)
  • All NixOS modules for services and infrastructure

Security & Networking

  • Hardened SSH configuration
  • nftables firewall with DDoS protection
  • WireGuard VPN server (10.10.10.0/24)
  • HAProxy reverse proxy with SNI routing
  • Let's Encrypt wildcard certificates (INWX DNS-01)

Infrastructure Services

  • PostgreSQL 16 (shared, tuned for cx22)
  • Docker/OCI containers via virtualisation.oci-containers

Mandatory Services

  • Authentik IdP (identity and access management)
  • Prometheus + Grafana monitoring (with exporters)
  • Restic encrypted backups to S3 (daily, with retention)

Optional Applications (enable via config.yaml)

  • AdGuard Home (ad blocking)
  • Seafile (file storage)
  • Jellyfin (media server)
  • Paperless-NGX (document management)
  • Pyload (download manager)
  • Matrix/Element (chat)
  • Forgejo (git hosting)

Secrets Management

  • Agenix for encrypted secrets
  • setup-secrets.sh script (generates and encrypts all secrets)

Deployment Scripts - All Functional

Optional Enhancements (Nice-to-Have)

  • 📝 Detailed documentation (docs/*.md files)
  • 🔧 WireGuard client management script
  • 🧪 NixOS VM tests for local testing
  • 📊 Pre-configured Grafana dashboards
  • 🔐 Authentik SSO integration examples

Alternatives

There are already existing implementations of the idea out there, some seem to focus more on local/home deployments rather than cloud VMs.

Functional requirements

Management UIs

Central Managemenut UI

for Development purposes and while the UI isn't avaiable the required data is provided as a YAML file.

dasphere:
  admin:
    username: "thorsten"
    password: "geheim"
  apps:
    adBlocking:
      name: "adguard"
      vpnOnly: false
    fileStore:
      name: "seafile"
      vpnOnly: true
    mediaServer:
      name: "jellyfin"
      vpnOnly: false
    documentManagement:
      name: "paperless-ngx"
      vpnOnly: true
    mediaLoader:
      name: "pyload"
      vpnOnly: true
    chat:
      name: "element"
      vpnOnly: false
    code:
      name: "forgejo"
      vpnOnly: false
  cloudProvider:
    name: "hetzner"
    apiKey: "secret"
  dnsProvider:
    name: "inwx"
    username: "test"
    password: "secret"
  s3Provider:
    name: "wasabi"
    bucket: "dovecot"
    username: "dovecot_user"
    secretKey: "secret"

Server Management UI

Currently not in scope, there will be a Server Management UI to

  • Add / remove applications
  • Check backup status
  • Trigger a new backup
  • Manage VPN Connections

Baseline

End-to-end automation:

  • Bootstrap the VM at the selected cloud provider getting a NixOS (via nix-anywhere) based installation in place.
  • In the VM install
    • VPN: Wireguard
    • Firewall
    • Web-Proxy
      • SSL termination using Certbot-generated wildcard certificates.
      • Sets up SNI routing for selected public access subdomains (others are VPN-only).
      • Stick-tables for DDoS mitigation, rate-limiting, and statistics endpoint accessible via VPN.
      • Handler for automatic reload after cert renewal based on the selected DNS provider
      • certbot_inwx
        • We start with INWX DNS plugin.
        • Automatic wildcard certificate issuance and renewal.
        • Hooks into HAProxy reload handler.
    • Container runtime
    • PostgreSQL
  • Deploy mandatory containers:
    • IdP: https://goauthentik.io/ (pgsql)
    • Monitoring: Prometheus & Grafana
      • Dashboards for Docker containers, WireGuard, HAProxy, and backups.
      • Alerting esp. for persistant volumes that might run out of storage.
    • Backups: https://restic.net/
      • Encrypted Restic backups to S3 (or other storage) for defined resources (e.g exclude media library).
      • Ensure proper delta backups, save backup status in versioned S3 file
      • Automated backup cron tasks.
      • Restore testing scripts to validate backup integrity.

Quick Start

Prerequisites

  • Nix package manager (for local testing)
  • Hetzner Cloud account
  • Domain with DNS access (INWX supported)
  • S3-compatible storage (Wasabi, Hetzner, AWS)

Deployment Workflow

# 1. Configure your deployment
cp config.yaml.example config.yaml
# Edit config.yaml with your domain, credentials, selected apps

# 2. Generate and encrypt secrets
./scripts/setup-secrets.sh

# 3. Generate cloud-init deployment artifact
./scripts/generate-cloud-init.sh  # TODO: Implement

# 4. Provision Hetzner server
./scripts/provision.sh  # TODO: Implement

# 5. Wait ~25-30 minutes for automated installation
# Access services at https://auth.yourdomain.com

Architecture Overview

Internet
   ↓
[Firewall] (nftables: SSH, HTTP/HTTPS, WireGuard)
   ↓
[HAProxy] (SNI routing, SSL termination, rate limiting)
   ├─ auth.domain.com → Authentik (9000)
   ├─ grafana.domain.com → Grafana (3000) [VPN-only]
   ├─ prometheus.domain.com → Prometheus (9090) [VPN-only]
   ├─ git.domain.com → Forgejo (3002)
   ├─ seafile.domain.com → Seafile (8082) [VPN-only]
   └─ ... other apps
   ↓
[Docker Containers] ← [PostgreSQL 16] → [Restic Backups to S3]

VPN Access: WireGuard VPN (10.10.10.0/24) provides secure access to VPN-only services.

Project Structure

dasphere/
├── config.yaml.example       # Configuration template
├── nix/
│   ├── configuration.nix     # Main NixOS config
│   ├── disk-config.nix       # Disko disk layout
│   ├── generated.nix         # Auto-generated from config.yaml
│   └── modules/              # NixOS modules
│       ├── base.nix          # SSH, users, hardening
│       ├── firewall.nix      # nftables rules
│       ├── wireguard.nix     # VPN server
│       ├── haproxy.nix       # Reverse proxy
│       ├── certbot.nix       # SSL certificates
│       ├── postgresql.nix    # Database
│       └── services/         # Container services
│           ├── authentik.nix
│           ├── monitoring.nix
│           ├── restic.nix
│           └── apps.nix      # Optional apps
├── secrets/                  # Agenix encrypted secrets
│   ├── secrets.nix           # Key definitions
│   └── *.age                 # Encrypted files
├── scripts/
│   ├── setup-secrets.sh      # ✅ Generate secrets
│   ├── generate-cloud-init.sh# ❌ TODO: Generate cloud-init.yaml
│   ├── provision.sh          # ❌ TODO: Deploy to Hetzner
│   └── teardown.sh           # ❌ TODO: Destroy server
└── templates/
    ├── flake.nix.tpl         # NixOS flake template
    └── cloud-init.yaml.tpl   # Cloud-init template

Configuration

Edit config.yaml to configure:

  • Domain: Your domain name (all services will be subdomains)
  • Admin: Username, email, SSH public key, password
  • Apps: Enable/disable optional applications
  • VPN-only: Control which apps require VPN access
  • Cloud Provider: Hetzner API key, server type, location
  • DNS Provider: INWX credentials for ACME DNS-01
  • S3 Storage: Bucket credentials for backups

See config.yaml.example for full documentation.

Security

  • Secrets: All sensitive data encrypted with agenix (age encryption)
  • SSH: Key-only authentication, hardened settings
  • Firewall: Default-drop policy, rate limiting, DDoS protection
  • SSL/TLS: TLS 1.2+, modern ciphers, wildcard certificates
  • VPN: WireGuard for secure access to internal services
  • Containers: Isolated, non-root where possible
  • Updates: Automatic security updates (no auto-reboot)

Services

Mandatory (Always Enabled)

  • Authentik: Identity provider and SSO for all services
  • Prometheus + Grafana: Metrics, dashboards, alerting
  • Restic: Encrypted backups to S3 (daily, with retention)

Optional (Enable in config.yaml)

  • AdGuard Home: Network-wide ad blocking
  • Seafile: File sync and storage (like Dropbox)
  • Jellyfin: Media server (movies, music, TV)
  • Paperless-NGX: Document management system
  • Pyload: Download manager
  • Matrix + Element: Self-hosted chat
  • Forgejo: Git hosting (like GitHub)

Monitoring

Access Grafana at https://grafana.yourdomain.com (VPN-only) to view:

  • System metrics (CPU, memory, disk, network)
  • Docker container metrics
  • HAProxy request rates and errors
  • PostgreSQL performance
  • WireGuard VPN status
  • Backup success/failure

Alerts configured for:

  • Disk usage >95%
  • Memory usage >90%
  • Service down >5 minutes
  • Certificate expiry <7 days
  • Backup failures

Backups

Restic performs daily encrypted backups to S3:

  • Included: PostgreSQL databases, container volumes, app data
  • Excluded: Jellyfin media library (too large), caches, logs
  • Retention: 7 daily, 4 weekly, 6 monthly
  • Verification: Weekly repository check, monthly restore test

Restore from backup:

ssh root@server
restic -r s3://endpoint/bucket/restic snapshots
restic restore latest --target /restore

Development

See the detailed implementation plan: ~/.claude/plans/luminous-conjuring-charm.md

Local Testing (Optional)

Test NixOS configuration locally before deploying:

# Build the system (requires Nix)
nix build .#nixosConfigurations.dasphere.config.system.build.toplevel

# Run in VM (requires KVM)
nixos-rebuild build-vm -I nixos-config=./nix/configuration.nix
./result/bin/run-nixos-vm

Disaster Recovery

  1. Provision new server: ./scripts/provision.sh
  2. Wait for NixOS installation (~25-30 min)
  3. Restore from Restic backup (~1 hour for PostgreSQL + data)
  4. Update DNS A records to new server IP

RTO: ~2 hours | RPO: 24 hours (daily backups)

Contributing

This is an early-stage project. Key areas needing work:

  1. generate-cloud-init.sh: Implement cloud-init generation logic
  2. provision.sh: Complete Hetzner provisioning automation
  3. Documentation: Create detailed guides in docs/
  4. Testing: Add NixOS VM tests
  5. App Modules: Improve app configurations, add more apps

See TODO section above for specific tasks.


Backlog / Archive