s3-orchestrator
★ 45About
Community Ratings
No ratings yetNew this week
Read recap →Features
- backend quotas
- replication
- access control
- object tagging
- encryption
- compression
- Terraform provider
- operator tooling
- admin API
- web dashboard
Details
- Last Updated
- Nov 2, 2026
- Created
- Feb 18, 2026
- Install Methods
- dockerpackage-managerbinaryhelmsource
- Requirements
- Go 1.27+DockerMakeSQLitePostgreSQL 14+Redis
- Authentication
- local
- API
- REST
- Backup & Export
- native-exportfile-backupdatabase-dump
- Runtime / Stack
- GoDockerdebK8S
- Privacy & Independence
- Cloud: Optional
- User Model
- Multi-User
- Deployment
Deployment: Docker Compose ✓11 Containers — heavy hosting footprintRuns as 11 containers
Run s3-orchestrator yourself
Pick how much you want to manage.
HetznerBest match
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
DigitalOcean
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
OVHcloud
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
Is this your project? Sponsor a listing
Run s3-orchestrator with Docker Compose
Compose file from the s3-orchestrator project repository.
11 services · database: postgres · infra: minio, postgres, redis · 5 unclassified (tempo, loki, alloy, prometheus, grafana)
no resource limits declared
needs persistent storage (11 volumes)
docker-compose.test.yml · @ 1cdcbd1 · scanned Nov 3, 2026
# -------------------------------------------------------------------------------
# Dev Environment Services - Docker Compose
#
# Author: Alex Freidah
#
# Provides MinIO (x3), PostgreSQL, Redis, and observability stack for local
# development ("make run" and "make dev-deps"). The Nomad and Kubernetes
# demos run their own copies of these services in the scheduler they
# target, and integration tests use testcontainers - see
# internal/integration/helpers_test.go.
#
# The MinIO images are project-owned GHCR mirrors of pinned upstream releases,
# because neither Docker Hub nor quay.io serves them to anonymous pulls.
#
# Usage: make dev-deps (or: docker compose -f docker-compose.test.yml up -d --wait)
# Cleanup: make dev-clean (or: docker compose -f docker-compose.test.yml down -v)
# -------------------------------------------------------------------------------
services:
minio-1:
image: ghcr.io/afreidah/minio:RELEASE.2025-04-22T22-12-26Z
command: server /data --console-address ":9001"
ports:
- "19000:9000"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio-1-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 2s
timeout: 5s
retries: 5
minio-2:
image: ghcr.io/afreidah/minio:RELEASE.2025-04-22T22-12-26Z
command: server /data --console-address ":9001"
ports:
- "19002:9000"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio-2-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 2s
timeout: 5s
retries: 5
minio-3:
image: ghcr.io/afreidah/minio:RELEASE.2025-04-22T22-12-26Z
command: server /data --console-address ":9001"
ports:
- "19004:9000"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio-3-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 2s
timeout: 5s
retries: 5
postgres:
# Debian rather than alpine: musl has no locale data, so text sorts by byte
# regardless of collation and the stack under test stops resembling a real
# deployment.
image: postgres:16
# The stock buffer and checkpoint settings checkpoint every 5 minutes, and
# the full-page writes after each one stall commits for long enough to show
# up as multi-second write latency in a perf run on a shared laptop disk.
command:
- postgres
- -c
- max_connections=300
- -c
- shared_buffers=512MB
- -c
- checkpoint_timeout=15min
- -c
- max_wal_size=4GB
ports:
- "15432:5432"
environment:
POSTGRES_DB: s3proxy_test
POSTGRES_USER: s3proxy
# NOSONAR - test-only docker-compose; matches the user name to keep the
# integration harness bootable without environment variables. Never used
# in production.
POSTGRES_PASSWORD: s3proxy
healthcheck:
test: ["CMD-SHELL", "pg_isready -U s3proxy -d s3proxy_test"]
interval: 2s
timeout: 5s
retries: 5
# Shared usage counters, for running more than one instance against it.
redis:
image: redis:7.4-alpine
ports:
- "16379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 2s
timeout: 5s
retries: 5
minio-setup:
image: ghcr.io/afreidah/mc:RELEASE.2025-04-16T18-13-26Z
depends_on:
minio-1:
condition: service_healthy
minio-2:
condition: service_healthy
minio-3:
condition: service_healthy
entrypoint: ["/bin/sh", "-c"]
command:
- |
mc alias set minio1 http://minio-1:9000 minioadmin minioadmin &&
mc alias set minio2 http://minio-2:9000 minioadmin minioadmin &&
mc alias set minio3 http://minio-3:9000 minioadmin minioadmin &&
mc mb --ignore-existing minio1/backend1 &&
mc mb --ignore-existing minio2/backend2 &&
mc mb --ignore-existing minio3/backend3
tempo:
image: grafana/tempo:2.10.10
network_mode: host
volumes:
- ./deploy/monitoring/tempo.yml:/etc/tempo.yml:ro
command: ["-config.file=/etc/tempo.yml", "-config.expand-env=true"]
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3200/ready"]
interval: 5s
timeout: 3s
retries: 5
loki:
image: grafana/loki:3.7.9
user: "0"
network_mode: host
volumes:
- ./deploy/monitoring/loki.yml:/etc/loki/config.yml:ro
- loki-data:/var/loki
command: ["-config.file=/etc/loki/config.yml"]
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3100/ready"]
interval: 5s
timeout: 3s
retries: 5
alloy:
image: grafana/alloy:v1.21.2
volumes:
- ./deploy/monitoring/alloy.alloy:/etc/alloy/config.alloy:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
extra_hosts:
- "host.docker.internal:host-gateway"
command: ["run", "/etc/alloy/config.alloy"]
depends_on:
loki:
condition: service_healthy
prometheus:
image: prom/prometheus:v3.15.1
network_mode: host
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--web.listen-address=:19090"
- "--web.enable-remote-write-receiver"
volumes:
- ./deploy/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
depends_on:
minio-setup:
condition: service_completed_successfully
grafana:
image: grafana/grafana:13.3.0
ports:
- "13000:3000"
environment:
GF_AUTH_ANONYMOUS_ENABLED: "true"
GF_AUTH_ANONYMOUS_ORG_ROLE: Admin
GF_AUTH_DISABLE_LOGIN_FORM: "true"
PROMETHEUS_URL: http://host.docker.internal:19090
LOKI_URL: http://host.docker.internal:3100
TEMPO_URL: http://host.docker.internal:3200
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./deploy/monitoring/grafana/provisioning:/etc/grafana/provisioning:ro
- ./grafana/s3-orchestrator.json:/var/lib/grafana/dashboards/s3-orchestrator.json:ro
depends_on:
prometheus:
condition: service_started
tempo:
condition: service_healthy
loki:
condition: service_healthy
volumes:
minio-1-data:
minio-2-data:
minio-3-data:
loki-data:
This file may be out of date. Check the s3-orchestrator documentation for current setup steps.
Track your self-hosted stack
Bookmark software to try, rate tools you've used, and keep your collection in one place.

