Files
indee-demo/docker-compose.yml
Dorian e9c5c50ca3 Remove MinIO console port mapping to avoid host port conflicts
The MinIO S3 API is accessed internally via the Docker network.
The admin console is not needed externally and was causing
port 9001 conflicts with other services on the host.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-13 17:50:37 +00:00

225 lines
7.8 KiB
YAML

# ═══════════════════════════════════════════════════════════════
# IndeeHub — Production Stack for Portainer
# ═══════════════════════════════════════════════════════════════
#
# All ${VARIABLES} are resolved by Portainer at deploy time.
# Configure them in Portainer → Stacks → Environment variables
# before deploying.
#
# See env.portainer for the full list of required variables.
#
# For local development, use: docker compose -f docker-compose.dev.yml up
# ═══════════════════════════════════════════════════════════════
version: '3.8'
services:
# ── Frontend (nginx serving built Vue app) ──────────────────
app:
build:
context: .
dockerfile: Dockerfile
args:
VITE_USE_MOCK_DATA: "false"
VITE_CONTENT_ORIGIN: ${FRONTEND_URL}
VITE_INDEEHUB_API_URL: /api
VITE_INDEEHUB_CDN_URL: /storage
VITE_NOSTR_RELAYS: ""
restart: unless-stopped
ports:
- "${APP_PORT:-7777}:7777"
depends_on:
- relay
- api
networks:
- indeedhub-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7777/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# ── Backend API (NestJS) ────────────────────────────────────
api:
build:
context: ./backend
dockerfile: Dockerfile
restart: unless-stopped
environment:
# ── Core ─────────────────────────────────────────────
ENVIRONMENT: production
PORT: 4000
DOMAIN: ${DOMAIN}
FRONTEND_URL: ${FRONTEND_URL}
# ── Database ─────────────────────────────────────────
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_USER: ${POSTGRES_USER}
DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
DATABASE_NAME: ${POSTGRES_DB}
# ── Redis / BullMQ ───────────────────────────────────
QUEUE_HOST: redis
QUEUE_PORT: 6379
QUEUE_PASSWORD: ${REDIS_PASSWORD:-}
# ── S3 / MinIO ──────────────────────────────────────
S3_ENDPOINT: http://minio:9000
AWS_REGION: us-east-1
AWS_ACCESS_KEY: ${S3_ACCESS_KEY}
AWS_SECRET_KEY: ${S3_SECRET_KEY}
S3_PRIVATE_BUCKET_NAME: indeedhub-private
S3_PUBLIC_BUCKET_NAME: indeedhub-public
S3_PUBLIC_BUCKET_URL: ${S3_PUBLIC_BUCKET_URL}
# ── BTCPay Server ───────────────────────────────────
BTCPAY_URL: ${BTCPAY_URL}
BTCPAY_API_KEY: ${BTCPAY_API_KEY}
BTCPAY_STORE_ID: ${BTCPAY_STORE_ID}
BTCPAY_WEBHOOK_SECRET: ${BTCPAY_WEBHOOK_SECRET}
# ── Nostr Auth / JWT ─────────────────────────────────
NOSTR_JWT_SECRET: ${NOSTR_JWT_SECRET}
NOSTR_JWT_EXPIRES_IN: ${NOSTR_JWT_EXPIRES_IN:-7d}
# ── AES-128 Content Encryption ──────────────────────
AES_MASTER_SECRET: ${AES_MASTER_SECRET}
# ── Admin API ────────────────────────────────────────
ADMIN_API_KEY: ${ADMIN_API_KEY:-}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
minio:
condition: service_started
networks:
- indeedhub-network
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/nostr-auth/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
# ── PostgreSQL Database ─────────────────────────────────────
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- indeedhub-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
# ── Redis (BullMQ job queue) ────────────────────────────────
redis:
image: redis:7-alpine
restart: unless-stopped
command: >
sh -c "if [ -n '${REDIS_PASSWORD:-}' ]; then
redis-server --requirepass '${REDIS_PASSWORD}' --appendonly yes;
else
redis-server --appendonly yes;
fi"
volumes:
- redis-data:/data
networks:
- indeedhub-network
# ── MinIO (S3-compatible object storage) ────────────────────
minio:
image: minio/minio:latest
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
volumes:
- minio-data:/data
networks:
- indeedhub-network
# ── MinIO bucket init (one-shot: creates required buckets) ──
minio-init:
image: minio/mc:latest
depends_on:
- minio
entrypoint: >
/bin/sh -c "
sleep 5;
mc alias set local http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD};
mc mb local/indeedhub-private --ignore-existing;
mc mb local/indeedhub-public --ignore-existing;
mc anonymous set download local/indeedhub-public;
echo 'MinIO buckets initialized';
"
networks:
- indeedhub-network
restart: "no"
# ── FFmpeg Transcoding Worker ───────────────────────────────
ffmpeg-worker:
build:
context: ./backend
dockerfile: Dockerfile.ffmpeg
restart: unless-stopped
environment:
ENVIRONMENT: production
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_USER: ${POSTGRES_USER}
DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
DATABASE_NAME: ${POSTGRES_DB}
QUEUE_HOST: redis
QUEUE_PORT: 6379
QUEUE_PASSWORD: ${REDIS_PASSWORD:-}
S3_ENDPOINT: http://minio:9000
AWS_REGION: us-east-1
AWS_ACCESS_KEY: ${S3_ACCESS_KEY}
AWS_SECRET_KEY: ${S3_SECRET_KEY}
S3_PRIVATE_BUCKET_NAME: indeedhub-private
S3_PUBLIC_BUCKET_NAME: indeedhub-public
S3_PUBLIC_BUCKET_URL: ${S3_PUBLIC_BUCKET_URL}
AES_MASTER_SECRET: ${AES_MASTER_SECRET}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
minio:
condition: service_started
networks:
- indeedhub-network
# ── Nostr Relay ─────────────────────────────────────────────
relay:
image: scsibug/nostr-rs-relay:latest
restart: unless-stopped
volumes:
- relay-data:/usr/src/app/db
networks:
- indeedhub-network
networks:
indeedhub-network:
driver: bridge
volumes:
postgres-data:
redis-data:
minio-data:
relay-data: