Docker Compose for Nextcloud + Collabora + Traefik?

Took an afternoon to get my own docker-compose.yml fully working. This is intended for a single server, running traefik, nextcloud, postgres and collabora in separate containers.

Some notes:

To make this run:

  • adapt domains cloud.example.com and office.example.com
  • adapt credentials USER and PASS for nextcloud, postgres and collabora
  • adapt hashed password for Traefik Dashboard, replace all $ with $$
  • adapt TZ=, NC_default_phone_region and dictionaries=
  • adapt email for Let’s Encrypt certificates
  • NextCloud emails can be enabled with SMTP variables on nextcloud
  • execute docker compose up -d --remove-orphans
  • In NextCloud menu Apps install Collabora Office, it turns into NextCloud Office
  • In NextCloud menu Settings->Office add link https://office.example.com

Let the fun begin:

# docker-compose.yml
version: '3.9'

services:
  traefik:
    image: traefik:v2.8.5
    container_name: traefik
    hostname: traefik
    restart: always
    environment:
      - TZ=Europe/Berlin
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /var/log:/var/log
      - /data/traefik:/data/traefik
    command:
      - --log.level=DEBUG
      - --accesslog=true
      - --accesslog.filepath=/var/log/traefik-access.log
      - --api.dashboard=true
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --entryPoints.web.address=:80
      - --entrypoints.web.http.redirections.entryPoint.to=websecure
      - --entrypoints.web.http.redirections.entryPoint.scheme=https
      - --entryPoints.websecure.address=:443
      - --entryPoints.traefik.address=:8080
      - --certificatesresolvers.myresolver.acme.email=<EMAIL>
      - --certificatesresolvers.myresolver.acme.storage=/data/traefik/acme.json
      - --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.dashboard.entryPoints=traefik'
      - 'traefik.http.routers.dashboard.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`) || PathPrefix(`/debug`)'
      - 'traefik.http.routers.dashboard.service=api@internal'
      - 'traefik.http.routers.dashboard.middlewares=auth'
      - 'traefik.http.middlewares.auth.basicauth.users=<TR-USER>:<TR-HASHEDPASS>'

  postgres:
    image: postgres
    container_name: postgres
    restart: always
    volumes:
      - /data/postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=<DB-USER>
      - POSTGRES_PASSWORD=<DB-PASS>

  nextcloud:
    image: nextcloud
    container_name: nextcloud
    hostname: nextcloud
    restart: always
    volumes:
      - /data/nextcloud:/var/www/html
    environment:
      - TZ=Europe/Berlin
      - POSTGRES_HOST=postgres
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=<DB-USER>
      - POSTGRES_PASSWORD=<DB-PASS>
      - NEXTCLOUD_ADMIN_USER=<NC-USER>
      - NEXTCLOUD_ADMIN_PASSWORD=<NC-PASS>
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com
      - TRUSTED_PROXIES=traefik
      - OVERWRITEPROTOCOL=https
      - NC_default_phone_region=DE
    depends_on:
      - postgres
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.nextcloud.tls=true'
      - 'traefik.http.routers.nextcloud.tls.certresolver=myresolver'
      - 'traefik.http.routers.nextcloud.entrypoints=websecure'
      - 'traefik.http.routers.nextcloud.rule=Host(`cloud.example.com`)'
      - 'traefik.http.routers.nextcloud.middlewares=nextcloud-dav,nextcloud-header'
      - 'traefik.http.services.nextcloud.loadbalancer.server.port=80'
      - 'traefik.http.middlewares.nextcloud-dav.redirectRegex.regex=https://(.*)/.well-known/(card|cal)dav'
      - 'traefik.http.middlewares.nextcloud-dav.redirectRegex.replacement=https://$${1}/remote.php/dav/'
      - 'traefik.http.middlewares.nextcloud-dav.redirectRegex.permanent=true'
      - 'traefik.http.middlewares.nextcloud-header.headers.referrerPolicy=no-referrer'
      - 'traefik.http.middlewares.nextcloud-header.headers.stsSeconds=15552000'
      - 'traefik.http.middlewares.nextcloud-header.headers.forceSTSHeader=true'
      - 'traefik.http.middlewares.nextcloud-header.headers.stsPreload=true'
      - 'traefik.http.middlewares.nextcloud-header.headers.stsIncludeSubdomains=true'
      - 'traefik.http.middlewares.nextcloud-header.headers.browserXssFilter=true'
      - 'traefik.http.middlewares.nextcloud-header.headers.customRequestHeaders.X-Forwarded-Proto=https'

  collabora:
    image: collabora/code
    container_name: collabora
    hostname: collabora
    restart: always
    environment:
      - TZ=Europe/Berlin
      - aliasgroup1=https://cloud.example.com
      - dictionaries=en_US,de_DE
      - username=<CO-USER>
      - password=<CO-PASS>
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
    tty: true
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.collabora.tls=true'
      - 'traefik.http.routers.collabora.tls.certresolver=myresolver'
      - 'traefik.http.routers.collabora.entrypoints=websecure'
      - 'traefik.http.routers.collabora.rule=Host(`office.example.com`)'
      - 'traefik.http.routers.collabora.middlewares=collabora-header'
      - 'traefik.http.services.collabora.loadbalancer.server.port=9980'
      - 'traefik.http.middlewares.collabora-header.headers.referrerPolicy=no-referrer'
      - 'traefik.http.middlewares.collabora-header.headers.stsSeconds=15552000'
      - 'traefik.http.middlewares.collabora-header.headers.forceSTSHeader=true'
      - 'traefik.http.middlewares.collabora-header.headers.stsPreload=true'
      - 'traefik.http.middlewares.collabora-header.headers.stsIncludeSubdomains=true'
      - 'traefik.http.middlewares.collabora-header.headers.browserXssFilter=true'
      - 'traefik.http.middlewares.collabora-header.headers.customRequestHeaders.X-Forwarded-Proto=https'
3 Likes