This guide walks you through self-hosting Stellarbridge using container runtimes such as Docker Compose or Podman Compose. You will run the application and its dependencies (PostgreSQL, Redis, S3-compatible storage) as containers on a single host or VM.
Prerequisites
- Container runtime: Docker Engine 24+ or Podman 4+ with Compose support
- Compose: Docker Compose v2 or Podman Compose
- Resources: Minimum 4 GB RAM, 2 CPU cores; 8 GB RAM recommended for production
- Network: Outbound HTTPS for optional services (e.g. Auth0, telemetry)
Architecture Overview
A typical self-hosted deployment includes:
- Stellarbridge app: Web application and API (Go, port 8080)
- PostgreSQL: Primary database (port 5432)
- Redis: Caching and sessions (port 6379)
- S3-compatible storage: MinIO or another S3-compatible service for file storage (ports 9000, 9001)
- Optional: PDF engine, background worker, vector service (see your distribution or support for availability)
Step 1: Obtain the Compose File and Image
Use the official Stellarbridge Compose file and image provided for self-hosting. If you received a tarball or Git repository, ensure it includes:
- A
docker-compose.yml(orcompose.yaml) that defines the app, postgres, redis, minio, and minio-bootstrap services - A Dockerfile for the app, or a reference to a pre-built image (e.g.
ghcr.io/epyklab/stellarbridge/app:<tag>)
Example minimal structure:
# docker-compose.yml (conceptual)
services:
app:
image: ghcr.io/epyklab/stellarbridge/app:VERSION
ports:
- "8080:8080"
environment:
- STLLR_POSTGRES_CONN_STRING=postgresql://...
- STLLR_REDIS_CONN_STRING=redis://redis:6379
# ... (see Step 2)
depends_on:
postgres: { condition: service_healthy }
redis: { condition: service_healthy }
minio-bootstrap: { condition: service_completed_successfully }
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: stellarbridge
POSTGRES_PASSWORD: CHANGE_ME
POSTGRES_DB: stellarbridge
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stellarbridge"]
interval: 5s
timeout: 3s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: CHANGE_ME
volumes:
- minio-data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 5s
timeout: 5s
retries: 5
minio-bootstrap:
image: minio/mc:latest
entrypoint: []
command: ["sh", "/scripts/minio-bootstrap.sh"]
volumes:
- ./scripts/minio-bootstrap.sh:/scripts/minio-bootstrap.sh:ro
environment:
MINIO_HOST: http://minio:9000
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: CHANGE_ME
depends_on:
minio: { condition: service_started }
restart: "no"
networks:
default: { driver: bridge }
volumes:
postgres-data:
redis-data:
minio-data:Replace VERSION with the image tag provided to you. If you build from source, use build: . instead of image: for the app service.
Step 2: Configure Environment Variables
Create an environment file (e.g. .env) or set variables in the Compose file. Do not commit secrets to version control.
Required
- Database: Connection string and DB settings
STLLR_POSTGRES_CONN_STRING, orSTLLR_DB_HOST,STLLR_DB_PORT,STLLR_DB_USERNAME,STLLR_DB_PASSWORD,STLLR_DB_DATABASE,STLLR_DB_SSL_MODE - Redis:
STLLR_REDIS_CONN_STRING=redis://redis:6379(or your Redis URL) - S3-compatible storage:
STLLR_AWS_ACCESS_KEY_ID,STLLR_AWS_SECRET_ACCESS_KEY,STLLR_AWS_ENDPOINT_URL_S3,STLLR_AWS_REGION
For MinIO:STLLR_AWS_ENDPOINT_URL_S3=http://minio:9000, and optionallySTLLR_AWS_ENDPOINT_URL_S3_PUBLICfor presigned URLs (e.g.http://localhost:9000if clients reach MinIO on that host/port) - App identity and security:
STLLR_APP_ENV=production,STLLR_COOKIE_SECRET,STLLR_JWT_HMAC_SECRET(generate strong random values) - Domain:
STLLR_DOMAIN(e.g.https://files.yourcompany.com)
Optional but recommended for production
- Auth0 / OIDC:
STLLR_AUTH0_ISSUER,STLLR_AUTH0_AUDIENCE,STLLR_AUTH0_CLIENT_ID,STLLR_AUTH0_CLIENT_SECRET, and related Auth0 variables if you use Auth0 for sign-in - Subscription bypass (only for air-gapped or licensed self-hosted):
STLLR_SKIP_SUBSCRIPTION_CHECK=trueand/orSTLLR_IS_ENTERPRISE=trueas per your agreement - PDF engine:
STLLR_PDF_ENGINE_URL,STLLR_PDF_ENGINE_API_KEYif you run the optional PDF service - Vector service:
STLLR_VECTOR_HOST,STLLR_VECTOR_PORTif you run the optional vector component
Example .env (values are placeholders):
STLLR_APP_ENV=production
STLLR_DOMAIN=https://files.yourcompany.com
STLLR_POSTGRES_CONN_STRING=postgresql://stellarbridge:STRONG_PASSWORD@postgres:5432/stellarbridge?sslmode=disable
STLLR_REDIS_CONN_STRING=redis://redis:6379
STLLR_AWS_ACCESS_KEY_ID=minioadmin
STLLR_AWS_SECRET_ACCESS_KEY=STRONG_MINIO_PASSWORD
STLLR_AWS_ENDPOINT_URL_S3=http://minio:9000
STLLR_AWS_ENDPOINT_URL_S3_PUBLIC=http://localhost:9000
STLLR_AWS_REGION=us-east-1
STLLR_COOKIE_SECRET=GENERATE_32_BYTES_BASE64
STLLR_JWT_HMAC_SECRET=GENERATE_STRONG_SECRETUse a secrets manager or Compose secrets for production instead of plain .env if possible.
Step 3: Bootstrap Storage and Database
MinIO buckets: The
minio-bootstrapservice (or equivalent) should create the buckets required by the app and any optional services (e.g.coc-reports). The bootstrap script typically usesmcto create buckets; ensureMINIO_HOST,MINIO_ROOT_USER, andMINIO_ROOT_PASSWORDmatch the MinIO service.PostgreSQL: The database is created by the Postgres container (e.g. via
POSTGRES_DB). Schema and migrations are usually applied by the application on startup. If your distribution includes aninit-db.sqlor migrations, run them as documented.First run: Start dependencies first so health checks pass:
docker compose up -d postgres redis minio
# Wait for healthy (e.g. docker compose ps)
docker compose up -d minio-bootstrap
docker compose up -d appOr start everything and allow Compose to respect depends_on and health conditions:
docker compose up -dStep 4: Run the Stack
From the directory containing docker-compose.yml:
docker compose up -dWith Podman:
podman compose up -dCheck that all services are running and healthy:
docker compose ps
docker compose logs app --tail=50Step 5: Verify Deployment
- Health: Open the app URL (e.g.
http://localhost:8080or your configured domain). The root path may return a 200 or redirect to the app. - Login: If OIDC/Auth0 is configured, sign in and confirm you can access the dashboard.
- Database: Ensure the app logs show no connection errors; run a simple query against PostgreSQL if needed.
- Storage: Upload a small file and confirm it appears in MinIO (or your S3 backend).
Production Hardening
- Secrets: Use Docker secrets or an external secrets manager; avoid hardcoding passwords in Compose files.
- TLS: Put the app behind a reverse proxy (we recommend Caddy for automatic HTTPS; Nginx or Traefik are alternatives) and set
STLLR_DOMAINto the public HTTPS URL. - Resource limits: Add
deploy.resources.limitsandreservationsfor theapp(and other services) to avoid resource starvation. - Restart policy: Use
restart: unless-stopped(or equivalent) for app, postgres, redis, and minio. - Logging: Configure the runtime to forward container logs to your logging pipeline; the app writes to stdout/stderr.
- Backups: Back up PostgreSQL and MinIO data volumes regularly; use your preferred backup tool or managed backup features.
Troubleshooting
- App exits or unhealthy: Check
docker compose logs appfor database, Redis, or S3 connection errors. VerifySTLLR_POSTGRES_CONN_STRING,STLLR_REDIS_CONN_STRING, and AWS/MinIO variables. - Cannot upload or download files: Confirm MinIO (or S3) is reachable from the app and that
STLLR_AWS_ENDPOINT_URL_S3_PUBLICmatches how clients access the bucket if using presigned URLs. - Auth errors: Verify OIDC/Auth0 environment variables and that the app’s
STLLR_DOMAINand redirect URIs match your IdP configuration.
For more context, see Security and Managing Your Organization.