sha256:50dc5b7c3d61d980e91d11140425a733f678a89f56dd3da53e84d0446615f2d7
Last pushed
2 days by harlenalvarez
Type
Compose
Manifest digest
sha256:50dc5b7c3d61d980e91d11140425a733f678a89f56dd3da53e84d0446615f2d7
name: huddle
services:
postgres:
image: docker.io/${DOCKER_HUB_NAMESPACE:-local}/huddle-postgres:${HUDDLE_IMAGE_TAG:-dev}
environment:
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
POSTGRES_ALLOWED_HOSTS: postgres
volumes:
- postgres_data:/var/lib/postgresql
networks:
- backend
healthcheck:
# Check the private listener without assuming a role from DATABASE_URL;
# the custom entrypoint may initialize any configured username.
test:
[
'CMD',
'python3',
'-c',
"import socket; connection = socket.create_connection(('127.0.0.1', 5432), 3); connection.close()",
]
interval: 5s
timeout: 5s
retries: 20
start_period: 15s
restart: unless-stopped
redis:
image: redis:8-alpine
command: ['redis-server', '--appendonly', 'yes']
volumes:
- redis_data:/data
networks:
- backend
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 3s
retries: 20
restart: unless-stopped
nats:
image: nats:2-alpine
command: ['-js', '-sd', '/data', '-m', '8222']
volumes:
- nats_data:/data
networks:
- backend
healthcheck:
test: ['CMD', 'wget', '--quiet', '--spider', 'http://127.0.0.1:8222/healthz']
interval: 5s
timeout: 3s
retries: 20
restart: unless-stopped
nats-tools:
image: natsio/nats-box:latest
profiles: ['tools']
entrypoint: ['sleep', 'infinity']
depends_on:
nats:
condition: service_healthy
networks:
- backend
artifact-storage-init:
image: docker.io/${DOCKER_HUB_NAMESPACE:-local}/huddle-api:${HUDDLE_IMAGE_TAG:-dev}
user: '0:0'
entrypoint: ['sh', '-c']
command:
- mkdir -p /var/lib/huddle/artifacts && chown -R 10001:10001 /var/lib/huddle/artifacts
volumes:
- artifact_data:/var/lib/huddle/artifacts
restart: 'no'
api:
image: docker.io/${DOCKER_HUB_NAMESPACE:-local}/huddle-api:${HUDDLE_IMAGE_TAG:-dev}
environment:
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
DATABASE_STARTUP_TIMEOUT: ${DATABASE_STARTUP_TIMEOUT:-120}
FERNET_KEY: ${FERNET_KEY:?FERNET_KEY is required}
ARTIFACT_BLOB_ROOT: /var/lib/huddle/artifacts
HTTP_TIMEOUT: ${HTTP_TIMEOUT:-300}
HTTPX_MAX_CONNECTIONS: ${HTTPX_MAX_CONNECTIONS:-100}
HTTP_MAX_KEEPALIVE: ${HTTP_MAX_KEEPALIVE:-20}
ASR_WS_URL: ${ASR_WS_URL:-ws://spark-427e.local:8005/v1/audio/transcriptions/realtime}
VLLM_API_KEY: ${VLLM_API_KEY:-EMPTY}
CHAT_HEIC_MODE: ${CHAT_HEIC_MODE:-passthrough}
EXA_API_KEY: ${EXA_API_KEY:-}
REDIS_HOST: redis:6379
REDIS_KEY_PREFIX: ${REDIS_KEY_PREFIX:-huddle:}
REDIS_MAX_CONNECTIONS: ${REDIS_MAX_CONNECTIONS:-10}
REDIS_SOCKET_CONNECT_TIMEOUT: ${REDIS_SOCKET_CONNECT_TIMEOUT:-10.0}
REDIS_SOCKET_TIMEOUT: ${REDIS_SOCKET_TIMEOUT:-30.0}
REDIS_SOCKET_KEEPALIVE: ${REDIS_SOCKET_KEEPALIVE:-true}
REDIS_SSL_ENABLED: 'false'
REDIS_IS_CLUSTER: 'false'
NATS_URL: nats://nats:4222
LOG_LEVEL: ${LOG_LEVEL:-INFO}
WEB_PUSH_ENABLED: ${WEB_PUSH_ENABLED:-false}
WEB_PUSH_VAPID_PUBLIC_KEY: ${WEB_PUSH_VAPID_PUBLIC_KEY:-}
OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID:-}
OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET:-}
HUDDLE_PUBLIC_ORIGIN: ${HUDDLE_PUBLIC_ORIGIN:-https://localhost}
EBAY_ENVIRONMENT: ${EBAY_ENVIRONMENT:-sandbox}
EBAY_CLIENT_ID: ${EBAY_CLIENT_ID:-}
EBAY_CLIENT_SECRET: ${EBAY_CLIENT_SECRET:-}
EBAY_REDIRECT_URI: ${EBAY_REDIRECT_URI:-}
EBAY_ALLOW_PRODUCTION: ${EBAY_ALLOW_PRODUCTION:-false}
EBAY_ACCOUNT_DELETION_VERIFICATION_TOKEN: ${EBAY_ACCOUNT_DELETION_VERIFICATION_TOKEN:-}
EBAY_ACCOUNT_DELETION_PUBLIC_ORIGIN: ${EBAY_ACCOUNT_DELETION_PUBLIC_ORIGIN:-}
EBAY_SANDBOX_API_URL: ${EBAY_SANDBOX_API_URL:-https://api.sandbox.ebay.com}
EBAY_PRODUCTION_API_URL: ${EBAY_PRODUCTION_API_URL:-https://api.ebay.com}
EBAY_SANDBOX_INVENTORY_API_URL: ${EBAY_SANDBOX_INVENTORY_API_URL:-https://api.sandbox.ebay.com/sell/inventory/v1}
EBAY_PRODUCTION_INVENTORY_API_URL: ${EBAY_PRODUCTION_INVENTORY_API_URL:-https://api.ebay.com/sell/inventory/v1}
depends_on:
artifact-storage-init:
condition: service_completed_successfully
postgres:
condition: service_healthy
redis:
condition: service_healthy
nats:
condition: service_healthy
volumes:
- artifact_data:/var/lib/huddle/artifacts
networks:
- backend
- frontend
- webhook_backend
healthcheck:
test:
[
'CMD',
'python',
'-c',
"import urllib.request; urllib.request.urlopen('http://127.0.0.1:9000/api/health', timeout=3)",
]
interval: 10s
timeout: 5s
retries: 12
start_period: 30s
restart: unless-stopped
schedule-publisher:
image: docker.io/${DOCKER_HUB_NAMESPACE:-local}/huddle-api:${HUDDLE_IMAGE_TAG:-dev}
entrypoint: ['python', '-m', 'huddle_api.scheduled_worker', 'scheduler']
environment:
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
DATABASE_HOST_OVERRIDE: postgres
DATABASE_PORT_OVERRIDE: '5432'
FERNET_KEY: ${FERNET_KEY:?FERNET_KEY is required}
NATS_URL: nats://nats:4222
LOG_LEVEL: ${LOG_LEVEL:-INFO}
WEB_PUSH_VAPID_PUBLIC_KEY: ${WEB_PUSH_VAPID_PUBLIC_KEY:-}
WEB_PUSH_VAPID_PRIVATE_KEY: ${WEB_PUSH_VAPID_PRIVATE_KEY:-}
WEB_PUSH_VAPID_SUBJECT: ${WEB_PUSH_VAPID_SUBJECT:-}
WEB_PUSH_ENABLED: ${WEB_PUSH_ENABLED:-false}
HUDDLE_PUBLIC_ORIGIN: ${HUDDLE_PUBLIC_ORIGIN:-https://localhost}
REDIS_HOST: redis:6379
REDIS_KEY_PREFIX: ${REDIS_KEY_PREFIX:-huddle:}
VLLM_API_KEY: ${VLLM_API_KEY:-EMPTY}
EXA_API_KEY: ${EXA_API_KEY:-}
depends_on:
postgres:
condition: service_healthy
nats:
condition: service_healthy
api:
condition: service_healthy
networks:
- backend
# Web Push must reach external browser push providers.
- frontend
restart: unless-stopped
scheduled-task-worker:
image: docker.io/${DOCKER_HUB_NAMESPACE:-local}/huddle-api:${HUDDLE_IMAGE_TAG:-dev}
entrypoint: ['python', '-m', 'huddle_api.scheduled_worker', 'worker']
environment:
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
DATABASE_HOST_OVERRIDE: postgres
DATABASE_PORT_OVERRIDE: '5432'
FERNET_KEY: ${FERNET_KEY:?FERNET_KEY is required}
ARTIFACT_BLOB_ROOT: /var/lib/huddle/artifacts
NATS_URL: nats://nats:4222
LOG_LEVEL: ${LOG_LEVEL:-INFO}
OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID:-}
OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET:-}
HUDDLE_PUBLIC_ORIGIN: ${HUDDLE_PUBLIC_ORIGIN:-https://localhost}
REDIS_HOST: redis:6379
REDIS_KEY_PREFIX: ${REDIS_KEY_PREFIX:-huddle:}
VLLM_API_KEY: ${VLLM_API_KEY:-EMPTY}
HTTP_TIMEOUT: ${HTTP_TIMEOUT:-300}
HTTPX_MAX_CONNECTIONS: ${HTTPX_MAX_CONNECTIONS:-100}
HTTP_MAX_KEEPALIVE: ${HTTP_MAX_KEEPALIVE:-20}
CHAT_HEIC_MODE: ${CHAT_HEIC_MODE:-passthrough}
EXA_API_KEY: ${EXA_API_KEY:-}
EBAY_ENVIRONMENT: ${EBAY_ENVIRONMENT:-sandbox}
EBAY_CLIENT_ID: ${EBAY_CLIENT_ID:-}
EBAY_CLIENT_SECRET: ${EBAY_CLIENT_SECRET:-}
EBAY_REDIRECT_URI: ${EBAY_REDIRECT_URI:-}
EBAY_ALLOW_PRODUCTION: ${EBAY_ALLOW_PRODUCTION:-false}
EBAY_SANDBOX_API_URL: ${EBAY_SANDBOX_API_URL:-https://api.sandbox.ebay.com}
EBAY_PRODUCTION_API_URL: ${EBAY_PRODUCTION_API_URL:-https://api.ebay.com}
EBAY_SANDBOX_INVENTORY_API_URL: ${EBAY_SANDBOX_INVENTORY_API_URL:-https://api.sandbox.ebay.com/sell/inventory/v1}
EBAY_PRODUCTION_INVENTORY_API_URL: ${EBAY_PRODUCTION_INVENTORY_API_URL:-https://api.ebay.com/sell/inventory/v1}
depends_on:
postgres:
condition: service_healthy
nats:
condition: service_healthy
api:
condition: service_healthy
volumes:
- artifact_data:/var/lib/huddle/artifacts
networks:
- backend
- frontend
- webhook_backend
restart: unless-stopped
web:
image: docker.io/${DOCKER_HUB_NAMESPACE:-local}/huddle-web:${HUDDLE_IMAGE_TAG:-dev}
networks:
- frontend
healthcheck:
test: ['CMD', 'wget', '--quiet', '--output-document=/dev/null', 'http://127.0.0.1/healthz']
interval: 10s
timeout: 5s
retries: 12
restart: unless-stopped
caddy:
image: caddy:2-alpine
environment:
HUDDLE_HOSTNAME: ${HUDDLE_HOSTNAME:-localhost}
configs:
- source: caddyfile
target: /etc/caddy/Caddyfile
ports:
- name: http
target: 80
published: ${HUDDLE_HTTP_PORT:-80}
protocol: tcp
- name: https
target: 443
published: ${HUDDLE_HTTPS_PORT:-443}
protocol: tcp
- name: http3
target: 443
published: ${HUDDLE_HTTPS_PORT:-443}
protocol: udp
volumes:
- caddy_data:/data
- caddy_config:/config
depends_on:
api:
condition: service_healthy
web:
condition: service_healthy
networks:
- frontend
healthcheck:
test:
['CMD', 'wget', '--quiet', '--output-document=/dev/null', 'http://127.0.0.1:2019/config/']
interval: 10s
timeout: 5s
retries: 12
restart: unless-stopped
ebay-webhook-gateway:
image: caddy:2-alpine
configs:
- source: ebay_webhook_caddyfile
target: /etc/caddy/Caddyfile
depends_on:
api:
condition: service_healthy
networks:
- webhook_edge
- webhook_backend
healthcheck:
test:
['CMD', 'wget', '--quiet', '--output-document=/dev/null', 'http://127.0.0.1:2019/config/']
interval: 10s
timeout: 5s
retries: 12
start_period: 5s
restart: unless-stopped
cloudflared:
image: cloudflare/cloudflared:latest
command: ['tunnel', '--no-autoupdate', '--url', 'http://ebay-webhook-gateway:8080']
depends_on:
ebay-webhook-gateway:
condition: service_healthy
networks:
- webhook_edge
restart: unless-stopped
configs:
caddyfile:
file: ./Caddyfile
ebay_webhook_caddyfile:
file: ./ebay-webhook.Caddyfile
networks:
frontend:
webhook_edge:
webhook_backend:
internal: true
backend:
internal: true
volumes:
postgres_data:
redis_data:
nats_data:
caddy_data:
caddy_config:
artifact_data:
services:
api:
image: docker.io/harlenalvarez/huddle-api:2026.09.26-1@sha256:f38a9ece2787ed062035bc0bf6df9328700a6722681ca4af48fbcd0925c4c0df
artifact-storage-init:
image: docker.io/harlenalvarez/huddle-api:2026.09.26-1@sha256:f38a9ece2787ed062035bc0bf6df9328700a6722681ca4af48fbcd0925c4c0df
caddy:
image: docker.io/library/caddy:2-alpine@sha256:6aeddd44c3078b0f9a35206472a11420648a79c184603ef95957d0a20044cb2b
cloudflared:
image: docker.io/cloudflare/cloudflared:latest@sha256:072c067d25ccbe61d46e18f0d0723255f2bb5304f7317caa95b27031520ff92c
ebay-webhook-gateway:
image: docker.io/library/caddy:2-alpine@sha256:6aeddd44c3078b0f9a35206472a11420648a79c184603ef95957d0a20044cb2b
nats:
image: docker.io/library/nats:2-alpine@sha256:ac8f88a6494bffc2c2a5289a0ca61cb28a9145c11ba5677cf24265d07f46d8d4
nats-tools:
image: docker.io/natsio/nats-box:latest@sha256:d2f04223f40e016f77922a8115d34b0cd5fad2ec10b19b39316ae92d07f3d295
postgres:
image: docker.io/harlenalvarez/huddle-postgres:2026.09.26-1@sha256:739f6d73ad08fb2db2a556254baf7e8a3513cb3ad889e61732d11b3ce58c5d61
redis:
image: docker.io/library/redis:8-alpine@sha256:3811787313eba226a2ef38658c6ccb91cd5e110edc89c37767de373120a0e5a0
schedule-publisher:
image: docker.io/harlenalvarez/huddle-api:2026.09.26-1@sha256:f38a9ece2787ed062035bc0bf6df9328700a6722681ca4af48fbcd0925c4c0df
scheduled-task-worker:
image: docker.io/harlenalvarez/huddle-api:2026.09.26-1@sha256:f38a9ece2787ed062035bc0bf6df9328700a6722681ca4af48fbcd0925c4c0df
web:
image: docker.io/harlenalvarez/huddle-web:2026.09.26-1@sha256:e215e117a98eb19acf246f41d7436aa88c7b21f5222c0b4ad50ad2b33b7cf21e
docker compose -f oci://harlenalvarez/huddle-stack:latest upUse the above command to pull and run the Compose file. Learn more.
Redis is the world’s fastest data platform for caching, vector search, and NoSQL databases.
Pulls
1B+
Stars
13619
Last Updated
4 days
Caddy 2 is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go.
Pulls
500M+
Stars
988
Last Updated
3 days
NATS is an open-source, high-performance, cloud native messaging system.
Pulls
100M+
Stars
522
Last Updated
11 days
Client for Cloudflare Tunnel, a daemon that exposes private services through the Cloudflare edge.
Pulls
100M+
Stars
587
Last Updated
4 days
Lightweight container with NATS and NATS Streaming utilities
Pulls
50M+
Stars
5
Last Updated
5 days