Hosting a Docker app requires building the image, storing it in a registry, running it in an orchestrator, and routing traffic to it. The division of labor between you and the platform determines your operational burden.
The container hosting workflow
- 1Write a Dockerfile — defines how to build your app into an image
- 2Build the image — execute the Dockerfile to create a runnable image
- 3Push to a registry — store the image in Docker Hub, GitHub Container Registry, or a private registry
- 4Pull the image — the orchestrator fetches it from the registry
- 5Run the container — start a pod from the image
- 6Route traffic — send HTTPS requests to the running container
Manual workflow (self-hosted)
Build and push locally:
docker build -t myapp:v1 .
docker tag myapp:v1 ghcr.io/yourorg/myapp:v1
docker push ghcr.io/yourorg/myapp:v1Write a Kubernetes Deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: ghcr.io/yourorg/myapp:v1
ports:
- containerPort: 3000Apply it:
kubectl apply -f deployment.yamlConfigure an Ingress to route traffic. Manage TLS certificates. Monitor health checks.
Managed workflow (platform)
Push your Dockerfile to a Git repo. The platform:
- 1Clones the repo
- 2Builds the image with BuildKit in an ephemeral Job pod (no host Docker socket)
- 3Pushes the image to a registry (Google Artifact Registry, managed by the platform)
- 4Deploys the image via Helm
- 5Configures Ingress and provisions TLS automatically
You write the Dockerfile. The platform handles everything else.
Image build: rootless BuildKit
Platforms that expose the host Docker socket to build containers introduce a security risk (container escape). PandaStack uses rootless BuildKit in ephemeral Kubernetes Job pods. Each build runs in an isolated pod with no access to the host.
This is slower than sharing a Docker daemon (no build cache persists between builds) but far more secure in a multi-tenant environment.
Registry management
After building an image, it must be stored in a registry. Options:
- Docker Hub (public or private, rate-limited on free tier)
- GitHub Container Registry (tied to GitHub repos, private or public)
- Google Artifact Registry / AWS ECR (managed, private)
- Self-hosted registry (requires managing storage, backups, access control)
PandaStack pushes images to Google Artifact Registry automatically. You do not manage registry credentials or worry about storage limits.
If you need to use a custom registry (e.g., pulling a base image from a private registry), configure registry credentials in the dashboard under Project Settings → Secrets.
Orchestration: Kubernetes or serverless containers
Container orchestrators (Kubernetes, Nomad, ECS) manage running containers at scale:
- Start containers from images
- Restart crashed containers
- Scale replicas based on load
- Route traffic to healthy containers
- Roll out updates with zero downtime
PandaStack runs containers on Kubernetes (GKE). Free-tier apps run in gVisor (user-space kernel isolation) on preemptible nodes. Paid-tier apps run on stable nodes.
Serverless container platforms (Cloud Run, Fargate, Fly.io) scale containers to zero when idle and bill per-request. PandaStack free-tier apps scale to zero after 15 minutes of inactivity (cold start on next request). Paid tiers keep pods warm.
Deploy a Dockerfile via pandastack.json
Create pandastack.json in your repo root:
{
"type": "container",
"language": "docker",
"dockerfilePath": "Dockerfile",
"healthCheckPath": "/health",
"env": [
{ "name": "DATABASE_URL", "description": "PostgreSQL connection string" },
{ "name": "PORT", "description": "Port the app listens on (default 3000)" }
]
}Push to GitHub and deploy via the deploy button:
[](https://dashboard.pandastack.io/deploy?repo=yourorg/myapp&type=container&lang=docker)The platform builds the image, stores it in Artifact Registry, and deploys it via Helm. You get a live HTTPS URL.
Deploy via the CLI
Install the CLI and create a project:
panda login
panda projects create \
--name my-docker-app \
--repo yourorg/myapp \
--branch main \
--auto-deployThe platform detects the Dockerfile, builds the image, and deploys it. Watch logs in the dashboard under Logs.
Environment variables and secrets
Never bake secrets into a Docker image. Inject them at runtime:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
CMD ["node", "server.js"]// server.js
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;Set variables via the CLI:
panda projects env set my-docker-app DATABASE_URL=postgresql://user:pass@host/db
panda projects env set my-docker-app API_KEY=secret-keyOr via the API:
curl -X POST https://api.pandastack.io/v1/projects \
-H "Authorization: Bearer $PANDASTACK_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "container",
"name": "my-docker-app",
"repositoryName": "yourorg/myapp",
"branch": "main",
"autoDeploy": true,
"env": [
{ "name": "DATABASE_URL", "value": "postgresql://user:pass@host/db" },
{ "name": "API_KEY", "value": "secret-key" }
]
}'The platform injects these variables when the container starts. They are never written to the image.
Who does which part
| Task | Self-hosted | Managed platform |
|---|---|---|
| Write Dockerfile | You | You |
| Build image | You (local docker build) | Platform (BuildKit in cloud) |
| Push to registry | You (docker push) | Platform (automatic) |
| Manage registry credentials | You | Platform |
| Write Kubernetes manifests | You | Platform (Helm charts) |
| Configure Ingress | You | Platform (automatic) |
| Provision TLS certificates | You (Certbot) | Platform (Let's Encrypt) |
| Scale replicas | You (kubectl scale) | Platform (auto-scaling) |
| Monitor health checks | You (Prometheus) | Platform (built-in) |
| Aggregate logs | You (ELK stack) | Platform (Elasticsearch) |
Managed platforms eliminate infrastructure work. You write the Dockerfile, the platform handles the rest.
Free tier and cold starts
The free tier includes 5 container apps, 100 GB bandwidth/month, and 300 build minutes/month. Free-tier apps scale to zero after inactivity (cold start on next request).
Paid tiers run on stable nodes with no scale-to-zero. Pro tier ($15/mo) includes 500 GB bandwidth and stable nodes.
Container hosting is not just running docker run on a server. It is building, storing, orchestrating, routing, and monitoring. Choose a managed platform to eliminate operational burden.
References
- [Docker best practices](https://docs.docker.com/develop/dev-best-practices/)
- [Kubernetes documentation](https://kubernetes.io/docs/home/)
- [PandaStack container docs](https://docs.pandastack.io)