Ctrl K
ComunidadGuías…

docker-compose.storage.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# ============================================================
# FreeFrame - optional bundled object storage (Silo, a MinIO fork)
# ============================================================
# Usage:
#   docker compose --env-file .env.prod \
#     -f docker-compose.prod.yml -f docker-compose.storage.yml up -d
# (add -f docker-compose.images.yml and/or -f docker-compose.https.yml as
# you need them; use the same -f flags for every later command)
#
# FreeFrame has NO local-filesystem storage backend; it speaks only the S3 API.
# This file runs an S3 server on this host and creates the bucket. It is the
# same Silo setup as the commented-out block in docker-compose.prod.yml, which
# is left as it is for installs that already uncommented it.
#
# In .env.prod set:
#   S3_STORAGE=minio
#   S3_ENDPOINT=http://minio:9000
#   S3_ACCESS_KEY / S3_SECRET_KEY = strong values
#   S3_BUCKET = lowercase letters, digits and hyphens only (no underscores)
#   S3_PUBLIC_ENDPOINT = the address the BROWSER uses to reach storage, because
#     presigned URLs go to the browser. Either:
#       * https://<STORAGE_DOMAIN> with STORAGE_ROUTED=true (Traefik routes
#         STORAGE_DOMAIN to Silo over HTTPS; needs docker-compose.https.yml, a
#         DNS record for STORAGE_DOMAIN, and ports 80 and 443 open), or
#       * http://<this host>:9000 with STORAGE_PORT_BIND=0.0.0.0:9000 for an
#         HTTP-only install (open port 9000 to the browsers that use FreeFrame).
#   FRONTEND_URL must be the exact origin people browse to; the app sets the
#   bucket's CORS rules from it and from CORS_ALLOW_ORIGINS, and Silo enforces
#   them.
#
# Optional, all with safe defaults:
#   STORAGE_ROUTED=false          true: Traefik serves STORAGE_DOMAIN over HTTPS.
#                                 false keeps Traefik away from Silo, so an
#                                 HTTP-mode install never asks Let's Encrypt for
#                                 a certificate.
#   STORAGE_DOMAIN=storage.invalid  e.g. storage.review.example.com
#   STORAGE_PORT_BIND=127.0.0.1:9000  where the S3 port is published on the
#                                 host. The console (9001) is never published.
#
# An existing miniodata volume from the old minio/minio image opens as is.
# ============================================================

services:
  minio:
    image: pgsty/silo:RELEASE.2026-09-16T00-00-00Z   # maintained MinIO fork; minio/minio is no longer pullable (#461)
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${S3_ACCESS_KEY}
      MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY}
    volumes:
      - miniodata:/data
    ports:
      - "${STORAGE_PORT_BIND:-127.0.0.1:9000}:9000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    labels:
      - traefik.enable=${STORAGE_ROUTED:-false}
      - traefik.http.routers.minio.rule=Host(`${STORAGE_DOMAIN:-storage.invalid}`)
      - traefik.http.routers.minio.entrypoints=websecure
      - traefik.http.routers.minio.tls.certresolver=letsencrypt
      - traefik.http.services.minio.loadbalancer.server.port=9000

  minio-init:                     # one-shot: create the bucket (idempotent)
    image: pgsty/mc:RELEASE.2026-09-16T00-00-00Z
    env_file:
      - .env.prod                    # the S3_* vars below are read inside the container
    depends_on:
      minio:
        condition: service_healthy
    entrypoint: >
      /bin/sh -c "
      mc alias set local http://minio:9000 $${S3_ACCESS_KEY} $${S3_SECRET_KEY} &&
      mc mb --ignore-existing local/$${S3_BUCKET}
      "

  api:
    depends_on:
      minio:
        condition: service_healthy
  worker:
    depends_on:
      minio:
        condition: service_healthy
  email_worker:
    depends_on:
      minio:
        condition: service_healthy
  maintenance_worker:
    depends_on:
      minio:
        condition: service_healthy
  beat:
    depends_on:
      minio:
        condition: service_healthy

volumes:
  miniodata: