Docker Compose
Deploy a multi-container stack from a Compose YAML — Pier handles the rest.
Paste a docker-compose.yaml into Pier and ship a multi-container application — web + worker + cache + queue + database, whatever shape. Pier provisions the stack, attaches it to Traefik for TLS, manages persistent volumes, and exposes the same lifecycle controls (logs, env, restart, redeploy) as native templates.
Deploy with Pier
- 1 Open the Pier dashboard and click Add service.
- 2 Pick Docker Compose from the template list.
- 3 Choose the version, set a service name, and Pier provisions the container, storage, and ports automatically.
- 4 Attach a domain if you want HTTPS. Traefik auto-provisions the Let's Encrypt certificate.
What is Docker Compose on Pier?
This template wraps Docker Compose so you can paste a multi-container application YAML directly into the Pier UI and ship it. Pier provisions the stack, attaches it to its Traefik-fronted network for HTTPS, tracks named volumes, manages env vars, aggregates logs per service, and offers the same lifecycle controls (restart, redeploy, view logs, edit env) as native templates.
The killer use case is open-source projects that ship a canonical
docker-compose.yaml as their install method — paste, set domain,
deploy. Your own multi-service applications (web + worker + Redis +
Postgres, etc.) also fit naturally — no need to break them into
individual Pier services if they belong together.
How Pier deploys it
You paste a Compose YAML into the UI, optionally set service-level env
overrides, and Pier runs docker compose up -d on the host. Named
volumes become Pier-managed volumes that show up in the volumes page.
Networks default to a per-stack bridge; add the external pier-traefik
network to any service that should sit behind HTTPS.
Traefik integration is via standard Traefik labels on the service —
traefik.enable=true, traefik.http.routers.<name>.rule=Host(...), etc.
Pier provides Let’s Encrypt resolvers automatically; you just add the
domain.
Updates are a YAML edit + redeploy; Pier diffs the existing stack and recreates only what changed.
When NOT to use Docker Compose
For single-container apps, the Docker Image template is simpler — no YAML to manage. For a code repo (not a prebuilt image), the Dockerfile or Railpack templates build for you. For native Pier services with managed backups and version upgrades (PostgreSQL, Gitea, Grafana, etc.), pick the dedicated template — you get more lifecycle features. Compose is the right answer for “multi-container app that isn’t a native template.”
Key features
Paste-and-deploy multi-container apps
Drop a complete `docker-compose.yaml` into the Pier UI; Pier deploys all services together with the right networking, dependencies, and restart policies.
Traefik integration
Add Traefik labels to your services and Pier wires them up for HTTPS at your custom domain — no separate reverse proxy to set up.
Persistent volumes
Named volumes in your Compose YAML are tracked by Pier — backed up, listed in the UI, restorable.
Multi-service env management
Override env vars per service from the Pier UI without editing the YAML. Useful for rotating passwords or toggling features.
Logs aggregated per service
View logs of any container in the stack from the Pier UI. Tail live, search, export.
One-click redeploy
Push image updates or change YAML — redeploy from the UI; Pier handles container rebuild and rollout.
Use cases
Multi-service applications
Web + worker + Redis + Postgres + nginx — a typical Rails / Django / Laravel / Next.js + worker setup deployed as one unit.
Apps from upstream Compose files
Many open-source projects ship a docker-compose.yaml as their canonical install method. Paste it into Pier and you're done.
Local-dev → prod parity
Your local Compose file can be the same one you ship to Pier (minus volume-path differences). Reduce dev/prod drift.
Sidecar patterns
Service + sidecar (log shipper, metric exporter, init container) bundled in one Compose stack.
Pre-wired bundles
Build your own "service A + companion B + companion C" reusable bundle and re-deploy across projects.
Code examples
services:
web:
image: my-org/myapp:1.4.0
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://app:secret@db:5432/myapp
depends_on:
- db
restart: unless-stopped
db:
image: postgres:17-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
db-data: services:
web:
image: my-org/myapp:1.4.0
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
- "traefik.http.services.myapp.loadbalancer.server.port=3000"
networks:
- pier-traefik
networks:
pier-traefik:
external: true services:
web:
image: my-org/myapp:1.4.0
environment: &app-env
REDIS_URL: redis://redis:6379
DATABASE_URL: postgres://app:secret@db:5432/myapp
worker:
image: my-org/myapp:1.4.0
command: ["bundle", "exec", "sidekiq"]
environment: *app-env
redis:
image: redis:7-alpine
volumes: ["redis-data:/data"]
db:
image: postgres:17-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
volumes: ["db-data:/var/lib/postgresql/data"]
volumes:
redis-data:
db-data: Service page → Environment → add a row
Key: API_KEY
Value: sk-xxxxxxxxxxxx
Apply → restart container
The override stays in Pier, never edited into your YAML. How it compares
| vs Dockerfile (this catalog) | Dockerfile builds and runs ONE container. Compose orchestrates MULTIPLE containers together. Pick by scope. |
| vs Native Pier templates (postgresql, gitea, ...) | Native templates are pre-wired and managed by Pier (backups, version upgrades, scaling features). Compose is the "I have a multi-container app of my own design" escape hatch. |
| vs Kubernetes | K8s is for fleet-wide multi-host orchestration with autoscaling, rolling updates, service mesh. Compose is single-host. Use K8s when you need that scope; Compose when you don't. |
| vs Docker Image (this catalog) | Docker Image runs one prebuilt image. Compose runs many containers wired together. Use Image for the simplest single-service case; Compose for anything multi-container. |
Frequently asked questions
What Compose version is supported?
Can I use ${VAR} interpolation?
How do volumes work?
Healthchecks?
How do I connect Compose services to Traefik?
Resource limits?
How do I update?
Related services
Deploy on your VPS
Paste a docker-compose.yaml into Pier and ship a multi-container application — web + worker + cache + queue + database, whatever shape. Pier provisions the stack, attaches it to Traefik for TLS, manages persistent volumes, and exposes the same lifecycle controls (logs, env, restart, redeploy) as native templates.
Deploy this service →