Skip to content

Setting up NextCloud With Docker Compose

Unlike the AIO, we just use a compose file to launch a nextcloud instance. I kind of prefer this, however, you do have to set up your own Collabora and OnlyOffice containers as well, which is not a big deal.

Docker compose

Basically copying the docker-compose.yml from the github documentation here https://github.com/nextcloud/docker?tab=readme-ov-file#running-this-image-with-docker-compose.

I did make a few changes myself. I changed the docker volumes to be bind mounts with the paths defined in a .env file. I also created variables in the .env file for some of the other variables. So now we have

NextCloud docker-compose.yml
services:
  # Note: MariaDB is external service. You can find more information about the configuration here:
  # https://hub.docker.com/_/mariadb
  db:
    # Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
    image: mariadb:lts
    container_name: nextcloud-compose-db
    restart: always
    command: --transaction-isolation=READ-COMMITTED
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PW}
      - MYSQL_PASSWORD=${DB_PW}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  # Note: Redis is an external service. You can find more information about the configuration here:
  # https://hub.docker.com/_/redis
  redis:
    image: redis:alpine
    restart: always

  app:
    image: nextcloud
    container_name: nextcloud-compose
    restart: always
    ports:
      - 12000:80
    depends_on:
      - redis
      - db
    volumes:
      - ${NEXTCLOUD_LIBRARY}:/var/www/html
    environment:
      - MYSQL_PASSWORD=${DB_PW}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER={DB_USER}
      - MYSQL_HOST=db
      #
      - NEXTCLOUD_TRUSTED_DOMAINS=${TRUSTED_DOMAINS}
      - NEXTCLOUD_DEFAULT_PHONE_REGION=US

Define those variables in the .env file

# The location where your uploaded files are stored
NEXTCLOUD_LIBRARY=
# The location where your database files are stored
DB_DATA_LOCATION=

DB_ROOT_PW=
DB_USER=
DB_PW=

TRUSTED_DOMAINS=

Now if you have any trouble with routing within nextcloud, you made need to have set the OVERWRITECLIURL property to your domain, and OVERWRITEPROTOCOL to https. I should note that these only have any effect the FIRST time to you run your docker compose. After that, any modifications would need to be made to the config.php which is located in the config folder within your mounted location.

Nginx - NextCloud

Nothing crazy here, I think it speaks for itself.

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name nextcloud-compose.tail.thomasjwilde.com;

    # Let's Encrypt Certs generated by certbot container
    ssl_certificate        /etc/letsencrypt/live/local.thomasjwilde.com/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/local.thomasjwilde.com/privkey.pem;

    # Enable HTTP Strict Transport Security (HSTS) for one year, including subdomains.
    include /etc/nginx/conf.d/hsts.conf;

    # allow large file uploads
    client_max_body_size 50000M;

    # Include proxy headers
    include /etc/nginx/conf.d/proxy-headers.conf;

    # Enable Web Sockets
    include /etc/nginx/conf.d/websocket.conf;

    # Proxy settings for different subdomains
    location / {
        proxy_pass http://127.0.0.1:12000;
    }
}

Collabora

Docker Compose

We need to run our own Collabora server. This can be done with the following compose file

Collabora docker-compose.yml
services:
  collabora:
    image: collabora/code:24.04.12.3.1
    network_mode: "host"
    # ports:
    #   - 127.0.0.1:9980:9980
    container_name: collabora
    # release notes: https://www.collaboraonline.com/release-notes/
    # networks:
    #   ocis-net:
    environment:
      aliasgroup1: ${alias11}
      aliasgroup2: ${alias21} # Remove this line if you don't have any other services using Collabora
      DONT_GEN_SSL_CERT: "YES"
      extra_params: |
        --o:ssl.enable=false \
        --o:ssl.ssl_verification=true \
        --o:ssl.termination=true \
        --o:welcome.enable=false
      username: admin
      password: admin
    cap_add:
      - MKNOD
    logging:
      driver: ${LOG_DRIVER:-local}
    restart: always
    command: ["bash", "-c", "coolconfig generate-proof-key ; /start-collabora-online.sh"]
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:9980/hosting/discovery" ]

I'll note that I piggy backed this off the the OwnCloud OCIS documentation. The compose file can be found here:

https://github.com/owncloud/ocis/blob/master/deployments/examples/ocis_full/collabora.yml

Now, we're running everything behind nginx which takes care of SSL, which means ssl.enable needs to be false while ssl.termination should be true meaning that ssl is terminated upstream at the nginx proxy. Verification is fine at true.

Note that the aliasgroups are for a single server but include all aliases for that server separated by |. So aliasgroup1 could look like ${alias11}|${alias12} where alias11 is nextcloud.tail.domain.com while alias12 is nextcloud.local.domain.com. Note that these would be in the same server block in nginx.

You only need the line for aliasgroup2 if you have another host using collabora, i.e. you're also running OwnCloud OCIS.

Tip

I had the best luck running this in host mode instead of it's own nextwork. I just kept running into issues with WOPI server being trusted if this wasn't in the same network as nginx which is also in host mode.

Nginx

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    # http2 on;
    server_name collabora.tail.thomasjwilde.com collabora.local.thomasjwilde.com;

    # Let's Encrypt Certs generated by certbot container
    ssl_certificate        /etc/letsencrypt/live/local.thomasjwilde.com/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/local.thomasjwilde.com/privkey.pem;

    # Enable HTTP Strict Transport Security (HSTS) for one year, including subdomains.
    include /etc/nginx/conf.d/hsts.conf;

    # Include proxy headers
    include /etc/nginx/conf.d/proxy-headers.conf;

    # Enable Web Sockets
    include /etc/nginx/conf.d/websocket.conf;


    # allow large file uploads
    client_max_body_size 50000M;

    # Proxy settings for different subdomains
    location / {
        proxy_pass http://127.0.0.1:9980; # Use HTTP since SSL is terminated at Nginx
    }
}

Configuring Nextcloud

Make sure you have installed the NextCloud office app and choose Use your own server.

Inside the Allow List for WOPI requests depends on how you're running it. That is if you are accessing it from Tailscale nodes you might want to include all of those with 100.64.0.0/10. Running it locally, include all local IPs. 192.168.0.0/16. For docker IPs 172.17.0.0/16. And if you're having trouble determining if this is causing an issue you can set it to all IPv4 and IPv6 values with 0.0.0.0/0,::/0 just know that this is considered less secure in public environments.

OnlyOffice

OnlyOffice is a bit simpler to configure. You'll run the following docker compose

OnlyOffice docker-compose.yml
services:
  onlyoffice:
    image: onlyoffice/documentserver:latest
    container_name: onlyoffice
    restart: always
    ports:
      - 9981:80
    environment:
      - JWT_ENABLED=true
      - JWT_SECRET=${secret}

Where secret should be defined in a .env file.

Let's configure an nginx block:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    # http2 on;
    server_name onlyoffice.tail.thomasjwilde.com onlyoffice.local.thomasjwilde.com;

    # Let's Encrypt Certs generated by certbot container
    ssl_certificate        /etc/letsencrypt/live/local.thomasjwilde.com/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/local.thomasjwilde.com/privkey.pem;

    # Enable HTTP Strict Transport Security (HSTS) for one year, including subdomains.
    include /etc/nginx/conf.d/hsts.conf;

    # Include proxy headers
    include /etc/nginx/conf.d/proxy-headers.conf;

    # Enable Web Sockets
    include /etc/nginx/conf.d/websocket.conf;

    # allow large file uploads
    client_max_body_size 50000M;

    # Proxy settings for different subdomains
    location / {
        proxy_pass http://127.0.0.1:9981; # Use HTTP since SSL is terminated at Nginx
    }
}

Then go to Apps and down to Office, search for OnlyOffice and install it.

Then in Administrative Settings go to OnlyOffice and add your domain and your secret.

Collabora vs OnlyOffice

There's no doubt that OnlyOffice looks very similar to Microsoft Word but there are so drawbacks to the online version. It doesn't support Open formats like odt very well if you plan to use those, and the mobile app is not able to edit files with the community edition license.

That being said, the OnlyOffice Desktop apps are great and you can use these on desktop even if you opt for Collabora Online.

Comments