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:
- NextCloud runs on https://cloud.example.com
- NextCloud data is stored by
postgres
in/data/postgres
- NextCloud Office (
collabora
) runs on https://office.example.com
(Dashboard at https://office.example.com/browser/dist/admin/admin.html) - Traefik uses
docker.sock
to discover other containers and their configuration - Traefik will generate Let’s Encrypt TLS/SSL certificates, stored in
/data/traefik
- Traefik will automatically forward all
http
requests tohttps
- Traefik access log is written to
/var/log/traefik-access.log
- Traefik Dashboard at http://cloud.example.com:8080/dashboard/
(if not needed: remove all lines with8080
and all labels on servicetraefik
)
To make this run:
- adapt domains
cloud.example.com
andoffice.example.com
- adapt credentials
USER
andPASS
fornextcloud
,postgres
andcollabora
- adapt hashed password for Traefik Dashboard, replace all
$
with$$
- adapt
TZ=
,NC_default_phone_region
anddictionaries=
- 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
installCollabora Office
, it turns intoNextCloud Office
- In NextCloud menu
Settings->Office
add linkhttps://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'