# NOTE: based on https://github.com/suitenumerique/docs/pull/855/ and https://github.com/suitenumerique/docs/pull/583/ x-common-env: &common-env DJANGO_CONFIGURATION: Production DJANGO_ALLOWED_HOSTS: "*" # DJANGO_SECRET_KEY supplied via secrets DJANGO_SETTINGS_MODULE: drive.settings # DJANGO_SUPERUSER_PASSWORD supplied via secrets # Logging # Set to DEBUG level for dev only LOGGING_LEVEL_HANDLERS_CONSOLE: LOGGING_LEVEL_LOGGERS_ROOT: LOGGING_LEVEL_LOGGERS_APP: # Python PYTHONPATH: /app PYLINTHOME: /app/.pylint.d # Mail DJANGO_EMAIL_BRAND_NAME: DJANGO_EMAIL_HOST: DJANGO_EMAIL_LOGO_IMG: DJANGO_EMAIL_PORT: DJANGO_EMAIL_HOST_USER: # DJANGO_EMAIL_HOST_PASSWORD supplied via secret DJANGO_EMAIL_USE_SSL: DJANGO_EMAIL_USE_TLS: DJANGO_EMAIL_FROM: # Backend url DRIVE_BASE_URL: "https://${DOMAIN}" # Media STORAGES_STATICFILES_BACKEND: django.contrib.staticfiles.storage.StaticFilesStorage AWS_S3_ENDPOINT_URL: http://minio:9000 AWS_S3_DOMAIN_REPLACE: https://minio.lasuite-drive.cctest.autonomic.zone # AWS_S3_ACCESS_KEY_ID supplied via secret (this is same MINIO_ROOT_USER) # AWS_S3_SECRET_ACCESS_KEY supplied via secret (this is same as MINIO_ROOT_PASSWORD) MEDIA_BASE_URL: https://${DOMAIN} AWS_STORAGE_BUCKET_NAME: drive-media-storage # OIDC - settings from .env, see .env.sample OIDC_OP_JWKS_ENDPOINT: OIDC_OP_AUTHORIZATION_ENDPOINT: OIDC_OP_TOKEN_ENDPOINT: OIDC_OP_USER_ENDPOINT: OIDC_RP_CLIENT_ID: # OIDC_RP_CLIENT_SECRET supplied via secrets OIDC_RP_SIGN_ALGO: OIDC_RP_SCOPES: LOGIN_REDIRECT_URL: LOGIN_REDIRECT_URL_FAILURE: LOGOUT_REDIRECT_URL: OIDC_REDIRECT_ALLOWED_HOSTS: OIDC_AUTH_REQUEST_EXTRA_PARAMS: # REDIS REDIS_URL: redis://${STACK_NAME}_redis:6379/0 # AI (Fixme: remove?) AI_FEATURE_ENABLED: "false" AI_BASE_URL: https://openaiendpoint.com AI_API_KEY: password AI_MODEL: llama # Collaboration COLLABORATION_API_URL: https://$DOMAIN/collaboration/api/ # WOPI WOPI_CLIENTS: "collabora,onlyoffice" WOPI_COLLABORA_DISCOVERY_URL: "https://collabora.lasuite-drive.cctest.autonomic.zone/hosting/discovery" WOPI_ONLYOFFICE_DISCOVERY_URL: "https://onlyoffice.lasuite-drive.cctest.autonomic.zone/hosting/discovery" # WOPI_SRC_BASE_URL: "http://backend:8000" WOPI_SRC_BASE_URL: "https://${DOMAIN}" x-postgres-env: &postgres-env # Postgresql db container configuration POSTGRES_DB: drive POSTGRES_USER: drive POSTGRES_PASSWORD_FILE: /run/secrets/postgres_p # App database configuration DB_HOST: db DB_NAME: drive DB_USER: drive DB_PORT: 5432 # DB_PASSWORD supplied via secrets (this is same as POSTGRES_PASSWORD) x-minio-env: &minio-env MINIO_ROOT_USER_FILE: /run/secrets/minio_ru MINIO_ROOT_PASSWORD_FILE: /run/secrets/minio_rp services: app: user: "${DOCKER_USER:-1000}" image: lasuite/drive-frontend:v0.10.1 networks: - backend deploy: labels: - "traefik.enable=false" - "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}" - "coop-cloud.${STACK_NAME}.version=0.2.4+v0.10.1" environment: <<: [ *common-env ] healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080"] interval: 15s timeout: 30s retries: 20 start_period: 10s depends_on: - backend backend: user: ${DOCKER_USER:-1000} # image: lasuite/drive-backend:v0.10.1 image: lasuite/drive-backend:main command: [ "gunicorn", "-c", "/usr/local/etc/gunicorn/drive.py", "drive.wsgi:application" ] entrypoint: [ "/abra-entrypoint.sh", "/usr/local/bin/entrypoint" ] environment: <<: [ *common-env, *postgres-env ] networks: - backend depends_on: - db configs: - source: abra_entrypoint target: /abra-entrypoint.sh mode: 0555 secrets: - django_sk - django_sp - oidc_rpcs - minio_rp - minio_ru - postgres_p - email_pass celery: user: ${DOCKER_USER:-1000} image: lasuite/drive-backend:v0.10.1 networks: - backend command: [ "celery", "-A", "drive.celery_app", "worker", "-l", "INFO" ] entrypoint: ["/abra-entrypoint.sh", "/usr/local/bin/entrypoint"] environment: <<: [*common-env, *postgres-env] configs: - source: abra_entrypoint target: /abra-entrypoint.sh mode: 0555 secrets: - django_sk - django_sp - oidc_rpcs - minio_rp - postgres_p - email_pass db: image: postgres:16 networks: - backend healthcheck: test: ["CMD", "pg_isready", "-q", "-U", "docs", "-d", "docs"] interval: 1s timeout: 2s retries: 300 environment: <<: *postgres-env PGDATA: var/lib/postgresql/data/pgdata volumes: - postgres:/var/lib/postgresql/data/pgdata deploy: labels: backupbot.backup: "${ENABLE_BACKUPS:-true}" backupbot.backup.pre-hook: "/pg_backup.sh backup" backupbot.backup.volumes.postgres.path: "backup.sql" backupbot.restore.post-hook: '/pg_backup.sh restore' configs: - source: pg_backup target: /pg_backup.sh mode: 0555 secrets: - postgres_p redis: image: redis:5 networks: - backend mailcatcher: image: sj26/mailcatcher:v0.10.0 networks: - backend minio-createbuckets: image: minio/minio:RELEASE.2025-09-07T16-13-09Z environment: *minio-env entrypoint: > sh -c " MINIO_ROOT_USER=\"\$$(cat /run/secrets/minio_ru)\" && MINIO_ROOT_PASSWORD=\"\$$(cat /run/secrets/minio_rp)\" && /usr/bin/mc alias set drive http://minio:9000 \$${MINIO_ROOT_USER} \"\$${MINIO_ROOT_PASSWORD}\" && \ /usr/bin/mc mb drive/drive-media-storage && \ /usr/bin/mc version enable drive/drive-media-storage && \ exit 0;" deploy: mode: replicated replicas: 0 restart_policy: condition: none secrets: - minio_rp - minio_ru networks: - backend minio: image: minio/minio:RELEASE.2025-09-07T16-13-09Z environment: *minio-env healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 1s timeout: 20s retries: 300 networks: - backend - proxy command: minio server /data entrypoint: ["/usr/bin/docker-entrypoint.sh"] volumes: - minio:/data configs: - source: abra_entrypoint target: /abra-entrypoint.sh mode: 0555 secrets: - minio_rp - minio_ru deploy: labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.routers.${STACK_NAME}_minio.rule=Host(`${MINIO_DOMAIN}`)" - "traefik.http.routers.${STACK_NAME}_minio.entrypoints=web-secure" - "traefik.http.routers.${STACK_NAME}_minio.tls=true" - "traefik.http.routers.${STACK_NAME}_minio.tls.certresolver=${LETS_ENCRYPT_ENV}" - "traefik.http.services.${STACK_NAME}_minio.loadbalancer.server.port=9000" - "traefik.http.middlewares.${STACK_NAME}_minio-cors.headers.accessControlAllowOriginList=https://${DOMAIN}" - "traefik.http.middlewares.${STACK_NAME}_minio-cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE,OPTIONS" - "traefik.http.middlewares.${STACK_NAME}_minio-cors.headers.accessControlAllowHeaders=*" - "traefik.http.middlewares.${STACK_NAME}_minio-cors.headers.accessControlExposeHeaders=ETag,Content-Length" - "traefik.http.middlewares.${STACK_NAME}_minio-cors.headers.accessControlMaxAge=600" - "traefik.http.middlewares.${STACK_NAME}_minio-cors.headers.addVaryHeader=true" - "traefik.http.routers.${STACK_NAME}_minio.middlewares=${STACK_NAME}_minio-cors" collabora: image: collabora/code:latest # healthcheck: # test: [ "CMD", "curl", "-f", "http://localhost:9980/hosting/discovery" ] # interval: 30s # retries: 5 # start_period: 60s # timeout: 10s networks: - backend - proxy # ports: # - "9980:9980" environment: # - extra_params=--o:ssl.enable=false - extra_params=--o:ssl.enable=false --o:ssl.termination=true # - extra_params=--o:ssl.enable=true - username=drive - password=password - server_name=collabora.lasuite-drive.cctest.autonomic.zone # - aliasgroup1=collabora.lasuite-drive.cctest.autonomic.zone # - aliasgroup1=backend:8000 deploy: labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.routers.${STACK_NAME}_collabora.rule=Host(`collabora.lasuite-drive.cctest.autonomic.zone`)" - "traefik.http.routers.${STACK_NAME}_collabora.entrypoints=web-secure" - "traefik.http.routers.${STACK_NAME}_collabora.tls=true" - "traefik.http.routers.${STACK_NAME}_collabora.tls.certresolver=${LETS_ENCRYPT_ENV}" - "traefik.http.services.${STACK_NAME}_collabora.loadbalancer.server.port=9980" - "traefik.http.middlewares.${STACK_NAME}_collabora-cors.headers.accessControlAllowOriginList=https://${DOMAIN}" - "traefik.http.middlewares.${STACK_NAME}_collabora-cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE,OPTIONS" - "traefik.http.middlewares.${STACK_NAME}_collabora-cors.headers.accessControlAllowHeaders=*" - "traefik.http.middlewares.${STACK_NAME}_collabora-cors.headers.accessControlExposeHeaders=ETag,Content-Length" - "traefik.http.middlewares.${STACK_NAME}_collabora-cors.headers.accessControlMaxAge=600" - "traefik.http.middlewares.${STACK_NAME}_collabora-cors.headers.addVaryHeader=true" - "traefik.http.routers.${STACK_NAME}_collabora.middlewares=${STACK_NAME}_collabora-cors" onlyoffice: image: onlyoffice/documentserver-de:9.2 # healthcheck: # test: [ "CMD", "curl", "-f", "http://localhost/hosting/discovery" ] # interval: 30s # retries: 5 # start_period: 60s # timeout: 10s environment: TZ: "Europe/Berlin" USE_UNAUTHORIZED_STORAGE: "true" networks: - backend - proxy configs: - source: onlyoffice_conf target: /etc/onlyoffice/documentserver/local-production-linux.json deploy: labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.routers.${STACK_NAME}_onlyoffice.rule=Host(`onlyoffice.lasuite-drive.cctest.autonomic.zone`)" - "traefik.http.routers.${STACK_NAME}_onlyoffice.entrypoints=web-secure" - "traefik.http.routers.${STACK_NAME}_onlyoffice.tls=true" - "traefik.http.routers.${STACK_NAME}_onlyoffice.tls.certresolver=${LETS_ENCRYPT_ENV}" - "traefik.http.services.${STACK_NAME}_onlyoffice.loadbalancer.server.port=80" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-cors.headers.accessControlAllowOriginList=https://${DOMAIN}" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE,OPTIONS" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-cors.headers.accessControlAllowHeaders=*" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-cors.headers.accessControlExposeHeaders=ETag,Content-Length" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-cors.headers.accessControlMaxAge=600" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-cors.headers.addVaryHeader=true" - "traefik.http.routers.${STACK_NAME}_onlyoffice.middlewares=${STACK_NAME}_onlyoffice-cors" - "traefik.http.middlewares.${STACK_NAME}_onlyoffice-fwdproto.headers.customRequestHeaders.X-Forwarded-Proto=https" - "traefik.http.routers.${STACK_NAME}_onlyoffice.middlewares=${STACK_NAME}_onlyoffice-fwdproto" web: image: nginx:1.25 configs: - source: nginx_conf target: /etc/nginx/conf.d/default.conf networks: proxy: backend: depends_on: - backend - app environment: - STACK_NAME deploy: labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.routers.${STACK_NAME}.tls=true" - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=8083" - "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})" - "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}" - "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure" networks: proxy: external: true backend: volumes: postgres: minio: configs: nginx_conf: name: ${STACK_NAME}_nginx_conf_${NGINX_CONF_VERSION} file: nginx.conf.tmpl template_driver: golang pg_backup: name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION} file: pg_backup.sh abra_entrypoint: name: ${STACK_NAME}_entrypoint_${ABRA_ENTRYPOINT_VERSION} file: abra-entrypoint.sh onlyoffice_conf: name: ${STACK_NAME}_onlyoffice_conf_${ONLYOFFICE_CONF_VERSION} file: onlyoffice-config.json secrets: django_sk: external: true name: ${STACK_NAME}_django_sk_${SECRET_DJANGO_SK_VERSION} oidc_rpcs: external: true name: ${STACK_NAME}_oidc_rpcs_${SECRET_OIDC_RPCS_VERSION} django_sp: external: true name: ${STACK_NAME}_django_sp_${SECRET_DJANGO_SP_VERSION} postgres_p: external: true name: ${STACK_NAME}_postgres_p_${SECRET_POSTGRES_P_VERSION} minio_rp: external: true name: ${STACK_NAME}_minio_rp_${SECRET_MINIO_RP_VERSION} minio_ru: external: true name: ${STACK_NAME}_minio_ru_${SECRET_MINIO_RP_VERSION} email_pass: external: true name: ${STACK_NAME}_email_pass_${SECRET_EMAIL_PASS_VERSION}