Bianca Dominguez
Menu
← Back to work

Operating my own application infrastructure

Self-Hosted Application Platform & Migration

Built and operate a self-hosted application platform on Ubuntu using Docker, Coolify, Forgejo, Cloudflare, Infisical, PostgreSQL and Redis, migrating real applications from GitHub/Vercel-managed workflows to infrastructure I operate directly.

  • Ubuntu
  • Docker
  • Coolify
  • Forgejo
  • Cloudflare
  • Infisical
  • PostgreSQL
  • Redis
  • UFW
  • Fail2ban
  • Restic

Context

I moved beyond fully managed hosting to operate the infrastructure behind real applications myself. This meant taking responsibility for Git hosting, deployments, container networking, databases, secure access, backups and recovery rather than relying on those layers being abstracted by managed platforms.

Architecture

Compute

  • Ubuntu VPS
  • Docker
  • Coolify

Source & deployment

  • Forgejo
  • SSH deploy keys
  • Git-based deployments

Data

  • PostgreSQL
  • Redis
  • Persistent Docker volumes

Secrets

  • Self-hosted Infisical

Edge

  • Cloudflare DNS
  • Cloudflare proxy
  • Cloudflare Tunnel

Recovery

  • Restic
  • Cloudflare R2
  • PostgreSQL dumps
  • systemd automation

Security

Implemented SSH key authentication, restricted root/password login, UFW, Fail2ban, provider-edge firewalling and /32 source-IP allowlisting.

I also separated professional and private/business Git infrastructure using independent Forgejo instances, SSH identities, ports and deployment credentials.

Deployment

I configured repository authentication, deploy keys, production branch alignment and push-based deployment automation rather than treating the deployment platform as a black box.

  1. Git push
  2. Forgejo
  3. Coolify
  4. Container build & deployment
  5. Cloudflare
  6. Production

Backup & recovery

Implemented encrypted off-site Restic backups to Cloudflare R2, PostgreSQL logical dumps, archive validation and automated backup, integrity-check and retention jobs using systemd.

A controlled end-to-end restore test is the next recovery milestone.

Real troubleshooting

Operating the platform has included diagnosing:

  • SSH lockout: traced an SSH hang to a changed public IP no longer matching a provider-firewall /32 allowlist.
  • Forgejo collision: separated two Forgejo instances using host SSH ports 22222 and 22223.
  • Failed Coolify deployment: traced git upload-pack: not our ref to Coolify connecting to the wrong Forgejo and corrected the custom-port Git source using an explicit ssh:// URI.
  • Branch/deployment mismatch: verified Git ancestry before removing an obsolete master branch and standardising production on main.

What I learned

Self-hosting moved my understanding beyond simply deploying applications. I now work across the full delivery path — Git, authentication, builds, containers, networking, reverse proxying, DNS, persistent state, security and recovery — and troubleshoot failures by isolating the affected layer before making changes.

Next

Restic restore testing, Infisical backup and secrets integration, CrowdSec, attack-surface review, monitoring/alerting, Renovate/dependency security automation and a complete disaster-recovery runbook.