Operations
Infrastructure
Writing the application is half the work. This page covers the other half: where it runs, how it ships, what is exposed and what is not.
Topology
The map
A Hetzner VPS with Coolify orchestrating containers. Traefik publishes only what needs a domain; everything else lives on a private Docker network.
Published to the internet
Behind Traefik, with automatically renewed TLS certificates.
Portfolio
Next.js 16, server-rendered
CRM
Next.js 16 with user sessions
Private network only
No domain and no published port. Reachable only from inside the Docker network.
facturacion-api
Laravel 13 — issuing, totals and audit trail
gotenberg
HTML to PDF conversion
postgres
Primary database
redis
Queues and cache
minio
S3-compatible object storage
Reasoning
Decisions
What holds tax records has no public door
The invoicing API is not published to the internet. It is reachable only from the private Docker network, so the service holding the records has no directly exposed attack surface. Traefik routes only the applications that actually need a domain.
A backup you have never restored is not a backup
Database dumps go encrypted to storage that lives apart from the server producing them, and the restore is exercised regularly. An untested backup is a folder taking up disk.
Deployments are deliberately boring
Every application has a multi-stage Dockerfile and a healthcheck. Coolify deploys on push to the main branch and will not promote the new container until that healthcheck answers. If the new one fails to start, the previous version keeps serving.
Cost is an architecture decision
A single Hetzner VPS running several containers costs a fraction of the equivalent stack of managed services. On the real-estate aggregator that meant going from around €400 a month to between €20 and €35.
Detail
By layer
- Server
- Hetzner VPS
- Ubuntu 24.04 LTS
- Firewall at the provider level
- Orchestration
- Coolify
- Docker
- Traefik with automatic TLS
- A private network per project
- Application
- Server-rendered Next.js 16
- Laravel 13 on PHP 8.5
- Queues and workers
- Data
- PostgreSQL
- MySQL
- Redis
- S3-compatible object storage
- Operations
- Encrypted off-server backups
- Healthchecks
- Uptime monitoring