我正在运行 nextcloud https://cloud.museumsstrasse.at
,但由于我们主要使用 nextcloud 向公众开放数据,因此我希望此 nextcloud 根 URL 直接指向公共 nextcloud 文件夹,例如使用这个:https://cloud.museumsstrasse.at/s/Ytpcwos3o9o33kL
但这样公众就不需要带有共享子 URL 的 URL,而只需输入https://cloud.museumsstrasse.at
将打开此公共文件夹的位置。至于登录并与 nextcloud 同步,我想使用另一个子 URL,例如:https://cloud.museumsstrasse.at/internal
这可能吗?如何实现?
我的设置:
我在服务器上使用 docker 运行了 nextcloud Ubuntu 20.04
。由于其他服务也在此服务器上运行,因此我也使用 docker 设置了一个反向代理解决方案,包括以下镜像:nginx, jwilder/docker-gen:0.7.3, jrcs/letsencrypt-nginx-proxy-companion
它们执行反向代理并生成反向代理的配置文件。docker-compose.yml
所有这些内容如下:
version: '3'
services:
service_nginx:
image: nginx:1.13.1
container_name: container_nginx
ports:
- "80:80"
- "443:443"
networks:
- network_nginx
volumes:
- ./volumes/nginx/conf:/etc/nginx/conf.d
- ./volumes/nginx/vhost:/etc/nginx/vhost.d
- ./volumes/nginx/html:/usr/share/nginx/html
- ./volumes/nginx-letsencrypt/certs:/etc/nginx/certs
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
service_nginx-dockergen:
image: jwilder/docker-gen:0.7.3
container_name: container_nginx-dockergen
depends_on:
- service_nginx
command: -notify-sighup container_nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
networks:
- network_nginx
volumes:
- ./volumes/nginx/conf:/etc/nginx/conf.d
- ./volumes/nginx/vhost:/etc/nginx/vhost.d
- ./volumes/nginx/html:/usr/share/nginx/html
- ./volumes/nginx/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
- ./volumes/nginx-letsencrypt/certs:/etc/nginx/certs
- /var/run/docker.sock:/tmp/docker.sock:ro
service_nginx-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: container_nginx-letsencrypt
depends_on:
- service_nginx
- service_nginx-dockergen
environment:
NGINX_PROXY_CONTAINER: container_nginx
NGINX_DOCKER_GEN_CONTAINER: container_nginx-dockergen
networks:
- network_nginx
volumes:
- ./volumes/nginx/conf:/etc/nginx/conf.d
- ./volumes/nginx/vhost:/etc/nginx/vhost.d
- ./volumes/nginx/html:/usr/share/nginx/html
- ./volumes/nginx-letsencrypt/certs:/etc/nginx/certs
- /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_prod
environment:
- MYSQL_ROOT_PASSWORD=XXX
- MYSQL_PASSWORD=XXX
- MYSQL_DATABASE=XXX
- MYSQL_USER=XXX
restart: unless-stopped
service_nc:
image: nextcloud:latest
container_name: container_nc
depends_on:
- service_nc_db
- service_nginx
- service_nginx-dockergen
- service_nginx-letsencrypt
networks:
- network_nc_prod
- network_nginx
volumes:
- ./volumes/nc/html:/var/www/html
- ./volumes/nc/config:/var/www/html/config
- ./volumes/nc/custom_apps:/var/www/html/custom_apps
- ./volumes/nc/data:/var/www/html/data
- ./volumes/nc/themes:/var/www/html/themes
- /etc/localtime:/etc/localtime:ro
environment:
- VIRTUAL_HOST=cloud.museumsstrasse.at
- LETSENCRYPT_HOST=cloud.museumsstrasse.at
- LETSENCRYPT_EMAIL=XXX
restart: unless-stopped
networks:
network_ca_prod:
network_nc_prod:
network_nginx:
到目前为止,我尝试过将 nextcloud 的 html 代码推送到子文件夹中,并摆弄诸如overwritewebroot
或之overwritehost
类的设置config.php
,以及对 nginx 反向代理进行各种实验,但到目前为止都失败了。我尝试关注的是以下讨论:
https://github.com/nextcloud/docker/issues/401
https://stackoverflow.com/questions/54716909/nextcloud-installation-in-subfolder-redirect-in-apache2
Nextcloud 位于子目录 URL 中的 Ngnix 反向代理后面
无效的方法:
config.php
例如,如果我添加以下两行,则不起作用:
'overwritehost' => 'cloud.museumsstrasse.at',
'overwritewebroot' => '/internal'
然后cloud.museumsstrasse.at
使用浏览器打开会被重定向到,cloud.museumsstrasse.at/internal
但与此同时,其中的代码/var/www/html/internal/<nextcloud_code>
被删除并被 nextcloud 代码覆盖,/var/www/html/<nextcloud_code>
然后我无法打开,因为浏览器会cloud.museumsstrasse.at/internal
再次将我重定向到。
但是,即使 和 的某些功能overwritewebroot
正常工作,我如何避免从cloud.museumsstrasse.at
到 的重定向cloud.museumsstrasse.at/internal
?因为前者应该是公开的,而后者是我们内部的 nextcloud 端。因此,我不想重定向,而是希望使用两个不同的 URL 来实现不同的目的。
我假设一个务实的方法是调整 nextcloud 的 docker 镜像逻辑以指向它/var/www/html/internal/
,然后调整这个 docker 的内部 apache 以cloud.museumsstrasse.at
在提供公共文件夹的内容时显示cloud.museumsstrasse.at/s/Ytpcwos3o9o33kL
?但是我不知道该怎么做...
有人可以帮我吗?
干杯,斯蒂芬
答案1
好吧,我成功了——但付出了相当大的痛苦。
首先,我尝试过什么以及什么没有起作用(或者我无法使之起作用):
- 将 nextcloud 代码移动到子文件夹(nc 图像将始终覆盖)
- 通过 nc 映像中的 apache 服务器创建虚拟主机。我可以获得正确的重定向,但目标 URL 始终可见,而这正是我想要避免的。
- 在 nginx 反向代理层上创建重定向。
现在,我做的是:
- 1.) 通过符号链接将 nextcloud “移动” 到子路径
- 2.)使用 traefik 重新创建反向代理堆栈
细节:
1.) 将 nextcloud “移动” 到子路径
为了访问 URL 下的 nextcloud cloud.museumsstrasse.at/intern
(之前我将其称为“内部”),我执行了以下步骤:
在容器内创建符号链接:
ln -s /var/www/html/ /var/www/html/intern
chown www-data:root -h /var/www/html/intern
1.2.
然后在浏览器中打开 nextcloud,注册管理员用户,提供数据库凭据。
此步骤是必要的,因为之后会自动生成一些配置文件,这些文件将在接下来的步骤中被修改。
1.3./var/www/html/.htaccess
在自动生成的代码块中必须RewriteBase
进行修改:
如果没有这个步骤我会得到一个ERR_TOO_MANY_REDIRECTS
错误。
<IfModule mod_rewrite.c>
....
RewriteBase /intern # <-- changed from auto generated `RewriteBase /`
....
</IfModule>
1.4.
现在它基本上已经可以正常工作了,除了 Web 登录和客户端身份验证表单冻结(某种程度上与反向代理有关)。此问题在此处讨论:https://github.com/nextcloud/server/issues/19091为了修复此问题,必须将以下内容添加到/var/www/html/config/config.php
:
...
'overwriteprotocol' => 'https'
...
完成这些步骤后,即可使用所需子路径访问 nextcloud 实例cloud.museumsstrasse.at/intern
您可以在这里找到有帮助的讨论:https://github.com/nextcloud/docker/issues/401
2.)traefik 反向代理
现在,为了显示cloud.museumsstrasse.at
traefik 根 url 下选定的公共文件夹,可以使用动态替换路径,同时向访问者隐藏目标 url,这样无论在cloud.museumsstrasse.at
url 下返回什么子路径都将始终保留。
为此,必须在 traefik v2 中定义一个中间件。由于我只使用 docker-compose,因此我通过代理服务上的这些标签执行了此操作:
# 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.)完整的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.) 版本
目前我已经使用 nextcloud 运行它19.0.1
,并且如 traefik 的 docker-compose.yml 中所示2.2