The most important bit, IMO, is that I use split dns, as every proper network should. Relying on hairpin nat/nat reflection/nat loopback will just cause problems. This is generally true for everything, hairpin nat is a security vulnerabilty, you should not be using it outside of strictly controlled scenarios with manual rules, usually for enterprise level gear like the non-recommended setup for Cisco Expressway.
I use SWAG (https://github.com/linuxserver/docker-swag) as my reverse proxy. I renamed collabora.subdomain.conf.sample to collabora.subdomain.conf,
nextcloud.subdomain.conf.sample to nextcloud.subdomain.conf, and restarted swag.
I then created DNS records (external and internal) for nextcloud and collabora.
My SWAG participates in network nc
I was recently asked what swag confs I use for this, I use collabora.subdomain.conf.sample with no modifications except renaming to remove .sample and I use nextcloud.subdomain.conf.sample with no modifications except renaming to remove .sample.
I use postgresql for my nextcloud and I also use redis. While the db setup will happen in the NC ui, you must configure config.php directly to use redis. Per Quietsy's blog (https://virtualize.link/nextcloud/), I also adjust memcache.local as shown in the config.php.
I manually create my custom bridges to ensure the subnets don't change on me. docker network create --driver=bridge --subnet=172.18.0.0/16 nc
This ensures that my nc bridge is ALWAYS 172.18.0.0/16, though containers within, using my below compose, can still change IP addresses, you'll find that doesn't matter.
services:
redis:
image: redis:alpine
container_name: redis
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 1s
timeout: 3s
retries: 5
networks:
- nc
volumes:
- ${CONFDIR}/redis:/data
- ${TIME}:${TIME}:ro
command: redis-server --save 120 1 --loglevel warning
pgsql:
image: postgres:14-alpine
container_name: postgres
healthcheck:
test: ["CMD-SHELL", "su - postgres -c 'pg_isready'"]
interval: 10s
timeout: 5s
retries: 5
networks:
- nc
environment:
- POSTGRES_PASSWORD=${MYSQL_PW}
- PGDATA=/var/lib/postgresql/data
- TZ=${TZ}
volumes:
- ${CONFDIR}/pgsql:/var/lib/postgresql/data
- ${TIME}:${TIME}:ro
nextcloud:
image: lscr.io/linuxserver/nextcloud:latest
container_name: nextcloud
networks:
- nc
depends_on:
redis:
condition: service_started
pgsql:
condition: service_healthy
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
volumes:
- ${CONFDIR}/nextcloud:/config
- ${BDDIR}/nextcloud:/data
- ${TIME}:${TIME}:ro
collabora:
image: collabora/code
container_name: collabora
networks:
- nc
depends_on:
- nextcloud
environment:
- aliasgroup1=https://nextcloud.deez.nuts
ports:
- 9980:9980
restart: unless-stopped
networks:
nc:
name: nc
external: true
docker exec -it nextcloud occ app:enable richdocuments
docker exec -it nextcloud occ config:app:set richdocuments wopi_url --value https://collabora.deez.nuts
docker exec -it nextcloud occ richdocuments:activate-config
You'll also want to set the allow list at some point to get rid of the UI error (you people all freak out about nextcloud UI warnings). In my case, the UI would not allow me to input the IP, so as usual, I used the cli which always works.
occ config:app:set richdocuments wopi_allowlist --value=<the ip nextcloud will connect from>
in my case, i had to use the docker bridge gw ip (i have not dug into why)
<?php
$CONFIG = array (
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' =>
array (
'host' => 'redis',
'port' => 6379,
),
'datadirectory' => '/data',
'instanceid' => '<removed>',
'passwordsalt' => '<removed>',
'secret' => '<removed>',
'trusted_domains' =>
array (
0 => '192.168.128.9:9443',
1 => 'nextcloud.deez.nuts',
),
'trusted_proxies' => [gethostbyname('swag')],
'overwrite.cli.url' => 'https://nextcloud.deez.nuts',
'overwritehost' => 'nextcloud.deez.nuts',
'overwriteprotocol' => 'https',
'dbtype' => 'pgsql',
'version' => '28.0.1.1',
'dbname' => 'nextcloud',
'dbhost' => 'postgres:5432',
'dbport' => '',
'dbtableprefix' => 'oc_',
'dbuser' => '<removed>',
'dbpassword' => '<removed>',
'filesystem_check_changes' => 1,
'installed' => true,
'maintenance' => false,
'loglevel' => 2,
'default_phone_region' => 'US',
'theme' => '',
'filelocking.enabled' => 'true',
'upgrade.disable-web' => true,
);
TY, i had fixed locally and not in gist! good catch