The infrastructure behind this website began as a practical question: how much of my own small online platform could I operate without turning it into a second full-time job?
The current stack runs on an Oracle Cloud ARM instance and uses Docker for services, Caddy for HTTPS and reverse proxying, and separate subdomains for public tools, administration, monitoring, mail, and content management.
Self-hosting is valuable when it gives you ownership and understanding. It stops being valuable when every service becomes an undocumented exception.
The basic layout
The server hosts several independent services rather than one large application. Caddy is the public entry point. It handles TLS and forwards each subdomain to a service bound to the local interface. Docker Compose keeps application dependencies and persistent volumes together.
The stack currently includes the public website and Instatic CMS, Uptime Kuma for monitoring, Linkwarden for saved knowledge, a mail server with SnappyMail as a web client, and supporting databases and search services.
Bind applications locally
One of the simplest useful rules is to avoid exposing application ports directly to the internet. Services such as the CMS can listen on 127.0.0.1, while Caddy provides the public route. This reduces the number of open surfaces and keeps TLS configuration in one place.
It also makes the network map easier to explain: the public internet reaches Caddy; Caddy reaches approved local services; databases remain inside their Docker networks.
Subdomains are operational boundaries
Separate subdomains are not only branding. They make it easier to apply different access rules. A public portfolio can remain open, an administrative interface can sit behind stronger authentication, and a private document area can require a password without affecting the rest of the site.
The main website intentionally contains no link to the private notes service. More importantly, the private service still needs authentication; being unlinked is not a security control.
Monitoring before optimisation
Uptime Kuma was one of the first useful additions because it answers a basic question: is the service reachable from where it is supposed to be reachable? A small stack benefits more from clear health checks, restart policies, and backups than from premature performance tuning.
For each service, I want to know what data must persist, how it is backed up, how the container is recreated, and what a healthy response looks like.
Mail is infrastructure, not just another container
Running mail introduces DNS records, TLS, deliverability, spam controls, and client configuration. The public website will use contact@yavard.de, but that address can be an alias forwarding to an existing mailbox instead of becoming another inbox with another password.
That keeps the public identity clean while reducing maintenance.
A CMS that remains portable
Instatic fits the project because it can import a static design, manage content, and publish plain HTML. The resulting site is not trapped inside a hosted builder. It also exposes an MCP endpoint, which makes the planned blog workflow possible: Hermes can create and edit draft content, I can review it, and Hermes can publish only after explicit approval.
What this series will not expose
Infrastructure writing should be useful without becoming a map for attacking the server. Future posts can explain architecture, mistakes, backup strategy, and deployment patterns. They will not publish credentials, private paths, internal tokens, complete firewall details, or the content of private services.
What comes next
The next steps are to finish the public contact alias (already forwarding), protect selected private paths with password authentication (already in place via Authelia), and keep the documented workflow for importing the approved site into Instatic and connecting Hermes via a narrowly scoped MCP token (both operational).
This series will document those steps as reproducible engineering notes rather than pretending the final configuration appeared fully formed.