2026-06-05 12 min read

Building a FOSS Stack from Scratch

You have a fresh VPS, root access, and a commitment to FOSS. This guide takes you from bare metal to a fully self-hosted ecosystem — code hosting, CI/CD, monitoring, backups, and more — all running on FOSS tools.

Phase 0: Choose Your Base

Recommended VPS: Hetzner CX21 (€5.83/mo: 2 vCPU, 4 GB RAM, 40 GB NVMe) or Netcup RS 1000 G9.5 (€8.99/mo: 4 vCPU, 8 GB RAM, 256 GB SSD).

The Netcup plan gives more headroom for future services. The Hetzner plan handles the core stack with room to spare. Both offer KVM virtualization with full OS control.

Operating System: Debian 12 (stable, well-supported, minimal). Ubuntu 24.04 LTS is fine if you prefer the Ubuntu ecosystem.

Phase 1: Foundation (30 minutes)

apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deploy
apt install -y curl wget git ufw fail2ban
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Phase 2: Docker + Coolify (15 minutes)

Coolify provides a Heroku-like experience for deploying applications:

curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

This installs Docker, Docker Compose, and Coolify in one command. Access the web UI at http://your-server-ip:8000 and complete the initial setup.

Phase 3: Reverse Proxy (10 minutes)

Coolify includes built-in Traefik for automatic SSL via Let’s Encrypt. Configure your domain’s DNS to point to your VPS IP, then in Coolify, each application gets automatic HTTPS.

Phase 4: Core Services (2 hours)

Gitea — Code Hosting

Via Coolify: New Service → Docker Compose → paste Gitea compose. Or directly:

docker run -d --name gitea \
  -p 3000:3000 \
  -v gitea-data:/data \
  gitea/gitea:latest

Configure domain in Coolify for HTTPS. Import existing repos or start fresh.

Woodpecker CI — Continuous Integration

Connect Woodpecker to your Gitea instance. Create .woodpecker.yml in any repo to define CI pipelines.

Vaultwarden — Password Management

docker run -d --name vaultwarden \
  -v vw-data:/data \
  -e ADMIN_TOKEN=$(openssl rand -base64 48) \
  vaultwarden/server:latest

Uptime Kuma — Monitoring

docker run -d --name uptime-kuma \
  -p 3001:3001 \
  -v uptime-kuma:/app/data \
  louislam/uptime-kuma:latest

Umami — Analytics

Simple Docker Compose with PostgreSQL. Point at your website, configure domain.

Phase 5: Backups (30 minutes)

Install Restic and configure automated backups:

apt install restic -y

restic -r sftp://user@backup-server:/backups init

restic -r sftp://user@backup-server:/backups backup \
  /var/lib/docker/volumes/gitea-data \
  /var/lib/docker/volumes/vw-data \
  /etc

echo "0 2 * * * /usr/local/bin/backup.sh" | crontab -

Phase 6: Optional Extras

Nextcloud — if you need file sync, calendar, contacts. Resource-heavy but comprehensive. Allocate at least 2 GB RAM dedicated.

Matrix — if you need self-hosted chat. Start with Conduit (lightweight Rust homeserver) instead of Synapse to test whether you actually need it.

Jellyfin — if you’re hosting media. Lightweight, good performance even on modest VPS.

The Maintenance Schedule

Weekly (15 minutes):

Monthly (30 minutes):

Quarterly (1 hour):

You Now Have

A complete FOSS infrastructure stack running on your own hardware (virtual or physical), costing €6-9/month, with:

All FOSS. All self-hosted. All under your control.

Tired of managing servers?

Love the idea but not the maintenance? OpsHelp can run your FOSS stack for you — managed hosting built on Hetzner, Cloudflare, and open source tooling. From £50/month.