An Idempotent, Service Deployment Engine for Fedora Server
Bash · Docker · ZFS · Nginx · Tailscale · Fedora
FedoraForge is a highly resilient, state-tracked shell orchestration engine designed to transform a fresh Fedora Linux installation into a fully configured, production-grade FedoraForge deployment.
Rather than relying on massive single-point-of-failure deployment scripts, this engine uses a Phase-based architecture (run_phase). It tracks successful deployments via a .deploy_state file, meaning if the script is interrupted, the server reboots, or an error occurs, the orchestrator will seamlessly resume exactly where it left off without duplicating containers or corrupting data.
- Phase-based over a monolithic script: A single 500-line script failing halfway through a 40-minute deployment means starting over from scratch. Phases with state tracking mean failures are recoverable in seconds, not minutes, and each phase can be re-run, debugged, or extended in isolation.
- ZFS over plain LVM: Needed copy-on-write snapshots and reliable handling of mixed NVMe/HDD pools for hot and cold data, without manually tiering storage by hand.
- Tailscale over public exposure: Zero attack surface from the public internet by default. Every service is reachable only over the tailnet, with Nginx handling internal TLS termination and routing.
- Dynamic hardware detection over hardcoded configs: Bare-metal and VM deployments shouldn't need separate codepaths maintained by hand. The orchestrator detects what's actually present (GPU via
lspci, disk layout) and adapts at runtime.
- Stateful Resumption: Built-in caching and deployment tracking via
.deploy_state. - Dynamic Hardware Detection: Automatically scans the PCI bus (
lspci) for physical GPUs. If a bare-metal GPU is found, it dynamically auto-injects hardware passthrough (/dev/dri) into resource-heavy containers (like Wolf and Immich). Safely bypasses passthrough on VMs to prevent DRM crashes. - Storage Offloading: Automatically expands Fedora LVM volumes (
xfs_growfs) and relocates Docker/Containerd image extraction layers to an NVMe ZFS pool to prevent root disk exhaustion. - Secure by Default: Integrates tightly with Tailscale (MagicDNS via
systemd-resolved), ensuring no services are exposed to the public internet. All web traffic is routed internally via an Nginx reverse proxy using secure TLS certificates. - Disaster Recovery: Includes a fully automated backup engine using Duplicati. Read-only volume mounts protect the system from ransomware, while live Postgres/MySQL databases are automatically exported to static
.sqldumps via nightly cronjobs before being encrypted and sent offsite.
The orchestrator configures the host operating system, establishes ZFS storage pools, configures the network firewall, and deploys the following microservices:
- Wolf: Ultra-low latency Cloud Gaming & Desktop streaming (GPU Accelerated).
- Immich: Self-hosted photo and video backup (Postgres
pgvecto-rs+ Redis + Hardware Accelerated Machine Learning). - Kavita: Fast, feature-rich reading server for comics and books.
- Tailscale: Zero-trust mesh VPN.
- Snort 3: Bare-metal Network/Host Intrusion Detection System (IDS).
- AdGuard Home: Network-wide ad blocking and DNS sinkholing.
- Vaultwarden: Self-hosted Bitwarden password manager API.
- Nginx: Modular Reverse Proxy handling internal Tailnet routing.
- Homepage: Highly customizable, dynamic application dashboard.
- Prometheus: Time-series metrics aggregator.
- cAdvisor & Node Exporter: Container and host-level resource telemetry.
- Gitea: Self-hosted Git service.
- Samba: High-speed network file sharing.
- SearXNG: Privacy-respecting metasearch engine.
- FreshRSS: Self-hosted RSS feed aggregator.
Warning
OS Limitation: This script is currently strictly engineered for Fedora 44 (Server/Workstation). It relies heavily on dnf5, systemd-resolved, and Fedora's default Firewalld/SELinux architecture.
[!IMPORTANT] Storage Assumptions: The script assumes a 3-Disk Architecture:
- OS Root Drive
- NVMe Drive (ZFS
fastpoolfor high-I/O databases/VMs) - HDD Drive (ZFS
datapoolfor bulk media/backups)
(Note: The script is fully modular, so you can easily alter deploy.sh to map everything to a single drive according to your specific needs).
Note
Idempotency: Because this orchestrator pulls large Docker images and compiles kernel modules, network timeouts can happen. Do not panic if a phase fails! Simply re-run sudo bash deploy.sh. The orchestrator will clean up orphaned containers from the failed phase and gracefully resume.
Failsafe: Add custom DNS (1.1.1.1 or your preferred DNS) under the Tailscale DNS settings and set it to override to avoid name resolution errors.
- Clone the repository to your Fedora bare-metal machine.
- Make the orchestrator executable:
chmod +x deploy.sh
- Run the interactive deployment wizard (requires
sudo):sudo bash deploy.sh
- Follow the on-screen prompts to select your storage disks, configure your Tailscale Auth Key, and set your administrative passwords.
- Note: The wizard securely saves your passwords and configuration to
environment/active.env. This file is git-ignored to prevent accidental credential leaks. If you ever need to change your database passwords or Tailscale settings, you can edit that file directly.
- Note: The wizard securely saves your passwords and configuration to
- The orchestrator will compile ZFS, pull Docker images, and initialize the databases.
Once finished, navigate to your server's Tailscale domain in your browser to view your Homepage dashboard!
FedoraForge is designed to be highly extensible. If you want to add a new service (e.g., Plex, Nextcloud, HomeAssistant), you can do it in under two minutes using the built-in template system.
- Copy the Template: Duplicate the
99_template_moduleto create your new module.cp -r modules/99_template_module modules/18_my_custom_service
- Tweak the Configurations:
- Edit
docker-compose.ymland replace thehello-worldimage with your desired Docker image. - Edit
configure.shto update the internal port mapping and Nginx proxy location.
- Edit
- Register the Module: Open
deploy.sh, scroll to the bottom execution list, and register your module as a new deployment phase:run_phase "18" "My Custom Service" "./modules/18_my_custom_service/install.sh && ./modules/18_my_custom_service/configure.sh"
Because FedoraForge globally handles Nginx hot-reloading, rollback trapping, TLS provisioning, and state tracking, your custom module instantly gains all of these features automatically!
---
This project is licensed under the MIT License.