Alright, I got it working - at the expense of quite some pain.
Firstly, what I tried and what did not work (or what I could not get working):
- Moving the nextcloud code into sub-folder (the nc image would always overwrite)
- Creating virtual host by the apache server within the nc image. I could get correct redirections, but the target urls were always visible, which I wanted to avoid.
- Creating redirections on the nginx reverse proxy layer.
Now, what I did instead was:
- 1.) “moved” nextcloud to subpath by symbolic linking
- 2.) recreate the reverse proxy stack with traefik
Details:
1.) “moved” nextcloud to subpath
In order to reach nextcloud under the url cloud.museumsstrasse.at/intern (before I had it called ‘internal’) I did the following steps:
1.1.
Created symbolic linking within the container:
ln -s /var/www/html/ /var/www/html/intern
chown www-data:root -h /var/www/html/intern
1.2.
Then opened nextcloud in a browser, registered an admin user, provided db credentials.
This step is necessary since afterwards some config files are auto generated which will be modified in the next steps.
1.3.
In /var/www/html/.htaccess is the auto-generated code-block where RewriteBase must be modified:
Without this step I got an ERR_TOO_MANY_REDIRECTS error.
<IfModule mod_rewrite.c>
....
RewriteBase /intern # <-- changed from auto generated `RewriteBase /`
....
</IfModule>
1.4.
Now it would work mostly already, except for the fact that the web login and client authentication form freeze (somehow related to the reverse proxying). This issue is discussed here: https://github.com/nextcloud/server/issues/19091 and to fix it, the following must be added to /var/www/html/config/config.php:
...
'overwriteprotocol' => 'https'
...
After these steps, the nextcloud instance can be reached with the desired subpath cloud.museumsstrasse.at/intern
A helpful discussion can be found here: https://github.com/nextcloud/docker/issues/401
2.) traefik reverse proxy
Now in order to show a selected public folder under the root url of cloud.museumsstrasse.at traefik can be used to replace paths on the fly while hiding the targeted urls from the visitor so that no matter what subpath is returned under cloud.museumsstrasse.at the url will always remain.
For this in traefik v2 a middleware must be defined. Since I’m using docker-compose only, I did this via these labels on the proxied service:
# defines the middleware:
- "traefik.http.routers.service_nextcloud.middlewares=custom_repath"
# the regex which the rule should match (double dollar signs for escaping):
- "traefik.http.middlewares.custom_repath.replacepathregex.regex=^/$$"
# the replacement value (the subpath of a selected public folder):
-"traefik.http.middlewares.custom_repath.replacepathregex.replacement=/intern/s/63KFWGkziffJR8j"
3.) The full docker-compose.yml
services:
service_traefik:
image: "traefik:v2.2"
container_name: container_traefik
networks:
- network_traefik
command:
# an explicit reference to the docker network must be passed when multiple networks exist:
- "--providers.docker.network=docker_network_traefik"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=XXX"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
- "8080:8080"
volumes:
- "./volumes/traefik/letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
service_nc_db:
image: mariadb
container_name: container_nc_db
volumes:
- ./volumes/nc_db:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
networks:
- network_nc
environment:
- MYSQL_ROOT_PASSWORD=XXX
- MYSQL_PASSWORD=XXX
- MYSQL_DATABASE=XXX
- MYSQL_USER=XXX
service_nc:
image: nextcloud:latest
container_name: container_nc
depends_on:
- service_traefik
- service_nc_db
networks:
- network_traefik
- network_nc
labels:
- "traefik.enable=true"
- "traefik.http.routers.service_nextcloud.rule=Host(`cloud.museumsstrasse.at`)"
- "traefik.http.routers.service_nextcloud.entrypoints=websecure"
- "traefik.http.routers.service_nextcloud.tls.certresolver=myresolver"
- "traefik.http.routers.service_nextcloud.middlewares=custom_repath"
- "traefik.http.middlewares.custom_repath.replacepathregex.regex=^/$$"
- "traefik.http.middlewares.custom_repath.replacepathregex.replacement=/intern/s/63KFWGkziffJR8j"
volumes:
- ./volumes/nc/html:/var/www/html
networks:
network_nc:
network_traefik:
4.) versions
Currently I got this running with nextcloud 19.0.1 and as seen in the docker-compose.yml with traefik 2.2