Document Sharing - Nextcloud + Collabora Code

With the media server more or less wrapped up (we'll probably revisit that for improvements down the line), another thing we may want to accomplish is become independent of Google Drive and the Google office applications (or OneDrive and Office 365). To that end, we'll deploy NextCloud and Collabora Code. Note that I am not proviging instructions on how to migrate your existing file shares, beyond some generalities.

First, as usual, we'll need to set up the folder structure.

$ mkdir -p /srv/data/docker/nextcloud/data
$ sudo chown -R 33:33 /srv/data/docker/nextcloud
$ sudo chmod -R g-rwx,o-rwx /src/data/docker/nextcloud

Note the UID and GID is 33 here... I haven't tested running Nextcloud as arbitrary user. The documentation claims it's possible, though.

Next, set up the secrets for Nextcloud.

$ pwgen > /home/<your user>/secrets/nextcloud
$ pwgen > /home/<your user>/secrets/nextcloud-admin

These will need to be referenced in your compose file as usual, under the "secrets" toplevel section.

Next, set up the database for Nextcloud to use, after permitting Postgres access to the "nextcloud" secret:

$ docker container ls | grep postgres
$ docker container exec -it <container ID> bash
$ psql -U postgres << EOSQL
create role nextcloud with login password '$(cat /run/secrets/nextcloud)';
create database nextcloud with owner nextcloud;
grant all privileges on database nextcloud to nextcloud;
EOSQL

The compose file snippet for Nextcloud is:

  nextcloud:
    container_name: "nextcloud"
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.nextcloud-rtr.entrypoints: websecure
        traefik.http.routers.nextcloud-rtr.middlewares: "nextcloud-dav@swarm, nextcloud-index@swarm"
        traefik.http.routers.nextcloud-rtr.rule: "Host(`nextcloud.your.domain`)"
        traefik.http.routers.nextcloud-rtr.service: "nextcloud"
        traefik.http.services.nextcloud.loadbalancer.server.port: "80"
        traefik.http.middlewares.nextcloud-dav.redirectregex.regex: "https://(.*t)/.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-index.redirectregex.regex: "https://(.*t)/.well-known/(webfinger|nodeinfo)"
        traefik.http.middlewares.nextcloud-index.redirectregex.replacement: "https://$$1/index.php/.well-known/$$2"
        traefik.http.middlewares.nextcloud-index.redirectregex.permanent: "true"
      replicas: 1
    environment:
      POSTGRES_DB: "nextcloud"
      POSTGRES_USER: "nextcloud"
      POSTGRES_PASSWORD_FILE: "/run/secrets/nextcloud"
      POSTGRES_HOST: "postgres"
      NEXTCLOUD_ADMIN_USER: "admin"
      NEXTCLOUD_ADMIN_PASSWORD_FILE: "/run/secrets/nextcloud-admin"
      NEXTCLOUD_TRUSTED_DOMAINS: "nextcloud.your.domain"
      REDIS_HOST: "valkey"
      SMTP_HOST: "your.mail.server"
      SMTP_SECURE: "starttls"
      SMTP_PORT: "25"
      SMTP_AUTHTYPE: "<your authtype - probably PLAIN or LOGIN>"
      SMTP_NAME: "<SMTP server usename>"
      SMTP_PASSWORD: "<SMTP server password - could probably be a secret>"
      MAIL_FROM_ADDRESS: "nextcloud"
      MAIL_DOMAIN: "your.domain"
      TRUSTED_PROXIES: "10.64.0.0/16"
      APACHE_DISABLE_REWRITE_IP: 1
    image: "nextcloud:production"
    logging:
      driver: journald
    networks:
      - homelab
    ports:
      - "8080:80"
    restart: on-failure
    secrets:
      - nextcloud
      - nextcloud-admin
    volumes:
      - "/srv/data/docker/nextcloud/data:/var/www/html"

For the moment, I suggest sticking with local user authentication. I'll make a post about using Authentik as an OpenID provider and integrating everything compatible with it at a later date.

You'll notice that Nextcloud defines some middlewares it uses - that is to make DAV integration work, if that's something you want.

Next, bring Nextcloud up, wait for it stabilize, and shut it back down.

$ docker stack deploy -c <compost file> --prune --detach=false homelab
$ docker service rm homelab_nextcloud

You'll need to add a few lines to the configuration both to enable Nextcloud to function behind a reverse proxy, and to silence some warnings in the admin interface. Specifically, add to the end of /srv/data/docker/nextcloud/data/config/config.php, before the closing ');':

  'allow_local_remote_servers' => true,
  'maintenance_window_start' => 8,
  'default_phone_region' => 'US',

This will allow unencrypted communication between containers, set the maintenance window to start at 0800 UTC (0000 PST), and sets phone numbers without a country code to be US phone numbers. Bring Nextcloud back up.

$ docker stack deploy -c <compose file> --prune homelap

Next, we need to get maintenance scripts running on the container. This is annoying, as the container itself does not run a cron daemon, so we can either set up a container to run one, or set up the host system's cron daemon to do the job. I opted for the latter.

$ paru -S cronie
$ sudo systemctl enable --now cronie
$ sudo EDITOR=vim crontab -e

And add the following line to the crontab:

*/5 * * * * docker exec -u 33 $(docker container ls | grep nextcloud | cut -f 1 -d ' ') php /var/www/html/cron.php

This will, on every five minute interval, extract the container ID for nextcloud from docker and run the maintenance scripts.

Now open Nextcloud in your browser, login with your admin account, and go to your profile. You'll need to configure an email address. Go to Administrative Settings. Under "basic settings," change "background jobs" to "Cron." You'll probably want to click "Send Email" to test your email configuration works.

Next, go to Apps and download Group Folders and Nextcloud Office. Group Folders is how you'll share existing files, by creating a folder for them and mapping it to your existing file store via Docker; Office, we'll come back to after Collabora is installed.

Which is what we're getting to now. Collabora Code is, in this configuration, stateless, so all we need is to add it to the compose file and bring the stack up.

  collabora:
    deploy:
      replicas: 1
      labels:
        traefik.enable: "true"
        traefik.http.routers.collabora-rtr.entrypoints: "websecure"
        traefik.http.routers.collabora-rtr.rule: "Host(`collabora.your.domain`)"
        traefik.http.routers.collabora-rtr.service: "collabora"
        traefik.http.services.collabora.loadbalancer.server.port: "9980"
    environment:
      PUID: 10021
      PGID: 10021
      password: "<secret password that is never used>"
      username: "admin"
      domain: "[collabora\\.your\\.domain]"
      extra_params: "--o:ssl.enable=false --o:ssl.termination=true"
    image: "collabora/code"
    logging:
      driver: journald
    networks:
      - homelab
    restart: on-failure
$ docker stack deploy -c <compose file> --prune homelab

`

From here, go back to Nextcloud > Administrative Settings > Office. Select "use your own server" and point it to "https://collabora.your.domain". That should be all that's necessary to make things work.

Configuration files are, as usual, on Gitea.

Subscribe to Homelab Adventures

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe