I'm building a small self-hosted platform in a homelab Kubernetes cluster with Gitea, Harbor, and CI runners. Gitea needs persistent repository and application storage, while Harbor can use persistent volumes or an S3-compatible service such as MinIO.
This is primarily a learning project, so performance is not important yet. I'm trying to understand how the architecture should change in a real production environment. Would it be better to run PostgreSQL or object storage on dedicated machines outside Kubernetes and let the applications access them over the network, similar to using managed database and S3 services? My concern is that placing storage and application workloads on the same worker nodes could create shared failure domains.
Kubernetes offers StatefulSets, persistent volume claims, and storage systems such as Longhorn or Rook-Ceph, but I'm unsure how much protection they provide against node failures and whether separating compute from storage is generally preferred. I'd like to understand the trade-offs involving high availability, backups, performance, scaling, operational complexity, and production practices. Is running PostgreSQL or S3-compatible storage inside Kubernetes a legitimate design, and when does external or managed infrastructure become the better choice?
4 Answers
The practical boundary is usually operational rather than purely technical. Managed services are attractive when you need a strong service-level objective but do not want to operate replication, upgrades, backups, storage, and failover yourself. In-house or in-cluster systems become more appealing when managed services are too expensive, unavailable for regulatory reasons, require specialized performance, or when the organization already has a platform team that can run them reliably. At larger scale, distributed in-cluster systems can even cost less than managed offerings, but only if you can support them properly.
Stateful workloads can share workers with stateless workloads, but you should plan their placement and failure domains carefully. Storage replication across several nodes can survive an individual node failure, but it does not replace backups and does not protect against cluster-wide mistakes, disk failures beyond the replication level, or losing an entire site. You generally need multiple suitable nodes, reliable networking, enough capacity for replicas, and control-plane availability for meaningful failover. Storage platforms also add CPU, memory, network, and operational overhead, so they are not automatically simpler than dedicated storage.
A common design is to use labels, taints, resource reservations, and topology rules so database and storage pods are not competing unpredictably with application workloads. Separating them physically can still be worthwhile when their scaling, performance, or maintenance requirements differ.
It isn’t inherently an anti-pattern. For a homelab, keeping PostgreSQL and object storage in Kubernetes is a good way to learn the operational side, especially if performance and strict uptime are not priorities. The important parts are replication, tested backups, monitoring, and a documented recovery process. Moving services outside the cluster does not automatically protect the data; it mainly creates a different failure domain and changes who operates the storage.
That makes sense for the lab. I’m mainly trying to understand whether production teams commonly run PostgreSQL in Kubernetes or usually choose managed databases and separate infrastructure.
There is no universal production answer. PostgreSQL is commonly run in Kubernetes with a mature operator such as CloudNativePG, but many companies still use managed PostgreSQL or dedicated database infrastructure. The same applies to object storage: an external service, Ceph-based storage, or another actively supported S3-compatible system may be preferable depending on requirements. Be cautious about choosing an object-storage product solely because it has a Kubernetes operator; check its maintenance status, recovery behavior, and operational complexity first.
The biggest issue is often tiering and bootstrapping. If Git hosting, container images, DNS, or storage are required to bring the cluster up, placing every dependency in one cluster can make recovery difficult. Some teams keep critical prerequisites on separate infrastructure or in a second cluster for that reason.

If the long-term destination is definitely a managed service, starting there can reduce migration work. On the other hand, a homelab is a reasonable place to learn the self-hosted model before deciding what operational burden is actually acceptable.