name: stoat networks: web: external: true name: web services: # MongoDB: Database database: image: docker.io/mongo:4.4 restart: unless-stopped volumes: - ./data/db:/data/db healthcheck: test: echo 'db.runCommand("ping").ok' | mongo localhost:27017/test --quiet interval: 10s timeout: 10s retries: 5 start_period: 10s # Redis: Event message broker & KV store redis: image: docker.io/redis:6-alpine restart: unless-stopped # RabbitMQ: Internal message broker rabbit: image: docker.io/rabbitmq:4 restart: unless-stopped environment: RABBITMQ_DEFAULT_USER: rabbituser RABBITMQ_DEFAULT_PASS: rabbitpass volumes: - ./data/rabbit:/var/lib/rabbitmq healthcheck: test: rabbitmq-diagnostics -q ping interval: 10s timeout: 10s retries: 3 start_period: 20s # MinIO: S3-compatible storage server minio: image: minio/minio:RELEASE.2022-10-24T18-35-07Z command: server /data volumes: - ./data/minio:/data environment: MINIO_ROOT_USER: minioautumn MINIO_ROOT_PASSWORD: minioautumn MINIO_DOMAIN: minio networks: default: aliases: - revolt-uploads.minio # legacy support: - attachments.minio - avatars.minio - backgrounds.minio - icons.minio - banners.minio - emojis.minio restart: unless-stopped # Caddy: Web server caddy: image: docker.io/caddy restart: unless-stopped env_file: .env.web volumes: - ./Caddyfile:/etc/caddy/Caddyfile - ./data/caddy-data:/data - ./data/caddy-config:/config labels: # Explicitly tell Traefik to expose this container - traefik.enable=true - traefik.docker.network=web # HTTPS - traefik.http.services.stoat-service-secure.loadbalancer.server.port=80 - traefik.http.routers.stoat-secure.service=stoat-service-secure - traefik.http.routers.stoat-secure.entrypoints=websecure - traefik.http.routers.stoat-secure.tls.certresolver=le - traefik.http.routers.stoat-secure.rule=Host(`stoat.mistergeek.fr`) - traefik.http.middlewares.stoat-secure-cache.compress=true # HTTP - traefik.http.services.stoat-service-insecure.loadbalancer.server.port=80 - traefik.http.routers.stoat-insecure.service=stoat-service-insecure - traefik.http.routers.stoat-insecure.entrypoints=web - traefik.http.routers.stoat-insecure.rule=Host(`stoat.mistergeek.fr`) - traefik.http.middlewares.stoat-insecure-cache.compress=true - traefik.http.routers.traefik.tls=true - traefik.http.routers.traefik.tls.certresolver=le # GZIP - traefik.http.routers.traefik.middlewares=traefik-compress - traefik.http.middlewares.traefik-compress.compress=true networks: - default - web # API server api: image: ghcr.io/revoltchat/server:20250930-2 depends_on: database: condition: service_healthy redis: condition: service_started rabbit: condition: service_healthy volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Events service events: image: ghcr.io/revoltchat/bonfire:20250930-2 depends_on: database: condition: service_healthy redis: condition: service_started volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Web App web: image: ghcr.io/revoltchat/client:master restart: unless-stopped env_file: .env.web # File server autumn: image: ghcr.io/revoltchat/autumn:20250930-2 depends_on: database: condition: service_healthy createbuckets: condition: service_started volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Metadata and image proxy january: image: ghcr.io/revoltchat/january:20250930-2 volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Tenor proxy gifbox: image: ghcr.io/revoltchat/gifbox:20250930-2 volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Regular task daemon crond: image: ghcr.io/revoltchat/crond:20250930-2 depends_on: database: condition: service_healthy minio: condition: service_started volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Push notification daemon pushd: image: ghcr.io/revoltchat/pushd:20250930-2 depends_on: database: condition: service_healthy redis: condition: service_started rabbit: condition: service_healthy volumes: - type: bind source: ./Revolt.toml target: /Revolt.toml restart: unless-stopped # Create buckets for minio. createbuckets: image: docker.io/minio/mc depends_on: - minio entrypoint: > /bin/sh -c " while ! /usr/bin/mc ready minio; do /usr/bin/mc alias set minio http://minio:9000 minioautumn minioautumn; echo 'Waiting minio...' && sleep 1; done; /usr/bin/mc mb minio/revolt-uploads; exit 0; "