The Dockerfile is your portability contract
The great thing about packaging your app as a container is that the Dockerfile becomes a portable contract: any platform that runs OCI images can run your app. The platforms differ not in *whether* they can run your container, but in everything around it — how they build it, how they scale it, how secure the build is, and how much operational work lands on you.
This post compares the spectrum, from "give me a cluster" to "just run my container."
The spectrum of Docker hosting
| Tier | Examples | You manage | Best for |
|---|---|---|---|
| Raw orchestration | Self-managed Kubernetes | Everything | Large platform teams |
| Managed Kubernetes | GKE, EKS, AKS | Cluster + workloads | Teams wanting K8s without the control plane |
| Container PaaS | Cloud Run, ECS/Fargate, Fly | Service config | Most production apps |
| Push-to-deploy PaaS | Render, Railway, PandaStack | Almost nothing | Shipping fast |
Most teams over-estimate how much orchestration they need. Unless you're building a platform, you probably want a container PaaS, not a raw cluster.
The platforms
Managed Kubernetes (GKE / EKS / AKS)
Maximum power and flexibility. You get the full Kubernetes API, every networking and scaling primitive, and an enormous ecosystem. The cost is operational: you own cluster upgrades, node pools, ingress, secrets, and the YAML. Right for teams who genuinely need Kubernetes and have the people to run it.
Google Cloud Run / AWS Fargate / ECS
Serverless containers. You hand over an image, the platform runs and scales it (Cloud Run even scales to zero). No nodes to manage. Excellent middle ground for production workloads — you get scaling and reliability without owning a cluster. Cloud Run's per-request scale-to-zero is especially good for spiky traffic.
Fly.io
Runs your container as lightweight VMs close to users in many regions. Great for latency-sensitive global apps. More control than push-to-deploy PaaS, with a fly.toml to learn.
Render / Railway
Push-to-deploy PaaS that build from your Dockerfile (or detect a buildpack) and run the container with managed databases alongside. Minimal config, fast iteration. Great for small-to-medium teams.
PandaStack
Disclosure: my platform — and Docker hosting is its core. The architectural choice worth calling out is the build pipeline: PandaStack builds your image with rootless BuildKit inside an ephemeral Kubernetes Job pod, pushes to a private registry (Google Artifact Registry), then deploys via Helm. Critically, there's no host Docker socket involved — building untrusted code by mounting the host's Docker daemon is a well-known security hole, and PandaStack avoids it by design.
# Any standard Dockerfile works
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "server.js"]Connect a repo and it builds, deploys, and goes live. Free-tier apps run in a gVisor sandbox on spot nodes with KEDA scale-to-zero — strong isolation plus cheap idle. Attach managed Postgres/MySQL/Mongo/Redis and the connection string is injected. You get live build/app logs (self-hosted Elasticsearch), custom domains, automatic SSL, rollbacks, and cronjobs.
Honest limits: PandaStack abstracts the cluster away, so if you need raw Kubernetes primitives (custom CRDs, your own operators, fine-grained node pool control), managed Kubernetes is the better tool. It's a newer platform with a growing ecosystem, and free-tier apps cold-start after scaling to zero on preemptible nodes.
Build security: the part people skip
If a platform builds your container by giving the build access to the host Docker daemon (-v /var/run/docker.sock), that build effectively has root on the host. Rootless build approaches — BuildKit rootless, Kaniko, Buildah — avoid this. When evaluating a Docker host, ask: *how do you build my image, and does the build have host access?* It's an underrated security question.
A pre-deploy checklist for any container host
- Use multi-stage builds to keep runtime images small.
- Run as a non-root user in the final stage.
- Pin base image versions; avoid
latestin production. - Define health checks (
/healthz) for the orchestrator. - Pass config via env vars/secrets, never bake them in.
- Set resource requests/limits so the scheduler can place you sanely.
References
- [Docker multi-stage builds](https://docs.docker.com/build/building/multi-stage/)
- [BuildKit rootless mode](https://github.com/moby/buildkit/blob/master/docs/rootless.md)
- [Google Cloud Run docs](https://cloud.google.com/run/docs)
- [Kubernetes documentation](https://kubernetes.io/docs/home/)
- [gVisor sandbox](https://gvisor.dev/docs/)
---
If you want secure, rootless container builds and push-to-deploy without owning a cluster, PandaStack's free tier runs 5 web services with an auto-wired database. Deploy your Dockerfile at [dashboard.pandastack.io](https://dashboard.pandastack.io).