将 nextcloud 移动到子 URL 但将公共文件夹放在根目录(nextcloud + nginx + nginx-docker-gen 全部在 docker 中)

将 nextcloud 移动到子 URL 但将公共文件夹放在根目录(nextcloud + nginx + nginx-docker-gen 全部在 docker 中)

我正在运行 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(之前我将其称为“内部”),我执行了以下步骤:

1.1.

在容器内创建符号链接:

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.attraefik 根 url 下选定的公共文件夹,可以使用动态替换路径,同时向访问者隐藏目标 url,这样无论在cloud.museumsstrasse.aturl 下返回什么子路径都将始终保留。

为此,必须在 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

相关内容