网络拓扑
假设已有域名为nextcloud.yourhost.com
用户通过域名https访问 -> Nginx -> frps -> frpc -> NextCloud
其中Nginx 和frps 安装在具有公网IP的服务器上,frpc 和NextCloud安装在内网服务器中。
Nginx配置
通过docker安装nginx-proxy-manager
外网服务器中,新建个文件夹,创建docker-compose.yml文件
bash
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80' # http端口
- '81:81' # 管理界面端口
- '443:443' # https端口
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
docker compose up -d
启动后访问81
端口打开nginx-proxy-manager管理界面(防火墙记得打开80, 81, 443
)
nginx-proxy-manager配置
按下述文档配置nginx-proxy-manager
https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md#nginx-proxy-manager---npm
其中Domain Names
填入nextcloud.yourhost.com
由于我使用docker安装nginx-proxy-manager,Forward IP
应当填docker中的宿主机IP:127.17.0.1
(通过ip addr show docker0
查找得到)
Forward Port
改为 Frps 的vhostHTTPPort
,如10080
,与下面一致
Frps配置
下载Frp,到外网服务器中,我下载到/opt/frp/
,请根据实际情况修改路径。
配置Frps
/opt/frp//frps.toml
bash
bindPort = 37870
auth.token = xxxxx
vhostHTTPPort = 10080
vhostHTTPSPort = 10443
bindPort
为frp服务器和客户端通信端口,记得打开防火墙。
auth.token
可设置为一个随机字符串,用于通信加密。
vhostHTTPPort
和vhostHTTPSPort
为http/https服务监听端口,用于给本机的nginx访问。
配置Frps开机启动
/etc/systemd/system/frps.service
bash
[Unit]
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
ExecStart = /opt/frp/frps -c /opt/frp/frps.toml
Restart=on-failure
RestartSec=5s
[Install]
WantedBy = multi-user.target
执行
bash
sudo systemctl enable frps
sudo systemctl start frps
Frpc配置
配置Frpc
下载Frp,到内网服务器中,我下载到/opt/frp/
,请根据实际情况修改路径。
/opt/frp/frpc.toml
bash
serverAddr = "yourhost.com"
serverPort = 37870
auth.token = xxxxx
includes = ["./confd/*.toml"]
bindPort
和 auth.token
需要与Frps一致,其他根据实际填写。
/opt/frp/confd/nextcloud.toml
bash
[[proxies]]
name = "nextcloud"
type = "http"
localIP = "127.0.0.1"
localPort = 11000
customDomains = ["nextcloud.yourhost.com"]
配置通过nextcloud.yourhost.com
访问外网服务器转发到内网服务器的127.0.0.1:11000
,内外网服务器之间以及Frpc和NextCloud之间使用http通信。
这里的localPort
要与下面的APACHE_PORT
对应
配置Frpc开机启动
/etc/systemd/system/frpc.service
bash
[Unit]
Description = frp client
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
WorkingDirectory=/opt/frp
ExecStart = /opt/frp/frpc -c /opt/frp/frpc.toml
Restart=on-failure
RestartSec=5s
[Install]
WantedBy = multi-user.target
执行
bash
sudo systemctl enable frps
sudo systemctl start frps
Nextcloud AIO配置
内网服务器中新建个文件夹,创建docker-compose.yml文件:
bash
version: '3.8'
services:
nextcloud-aio-mastercontainer:
image: ghcr.io/nextcloud-releases/all-in-one:latest
container_name: nextcloud-aio-mastercontainer
restart: always
ports:
- "18080:8080"
volumes:
- aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- APACHE_PORT=11000
- APACHE_IP_BINDING=0.0.0.0
- SKIP_DOMAIN_VALIDATION=false
- NEXTCLOUD_DATADIR=/newdata/nextcloud
- NEXTCLOUD_UPLOAD_LIMIT=128G
- NEXTCLOUD_MAX_TIME=36000
- NEXTCLOUD_MEMORY_LIMIT=1024M
- NEXTCLOUD_ENABLE_DRI_DEVICE=true
init: true
sysctls:
- net.core.somaxconn=1024
deploy:
restart_policy:
condition: any
volumes:
aio_mastercontainer:
NEXTCLOUD_DATADIR
设置为你的数据储存路径
启动 docker:
bash
docker compose up -d
随后打开localhost:18080
执行初始化流程即可完成安装。
常见问题
Imagick插件无法下载
初始化过程中,容器nextcloud-aio-nextcloud
可能会卡在Enabling Imagick...
bash
2025-07-04T15:09:58.253331095Z Connection to nextcloud-aio-database (172.20.0.5) 5432 port [tcp/postgresql] succeeded!
2025-07-04T15:09:58.253810507Z + '[' -f /dev-dri-group-was-added ']'
2025-07-04T15:09:58.254285584Z ++ find /dev -maxdepth 1 -mindepth 1 -name dri
2025-07-04T15:09:58.255071763Z + '[' -n /dev/dri ']'
2025-07-04T15:09:58.255453279Z ++ find /dev/dri -maxdepth 1 -mindepth 1 -name renderD128
2025-07-04T15:09:58.256215830Z + '[' -n /dev/dri/renderD128 ']'
2025-07-04T15:09:58.256741487Z ++ stat -c %g /dev/dri/renderD128
2025-07-04T15:09:58.258725601Z + GID=993
2025-07-04T15:09:58.258744684Z + groupadd -g 993 render2
2025-07-04T15:09:58.270615549Z ++ getent group 993
2025-07-04T15:09:58.270649267Z ++ cut -d: -f1
2025-07-04T15:09:58.272696310Z + GROUP=render2
2025-07-04T15:09:58.272728341Z + usermod -aG render2 www-data
2025-07-04T15:09:58.288824588Z + touch /dev-dri-group-was-added
2025-07-04T15:09:58.291171246Z + set +x
2025-07-04T15:09:58.305853077Z Enabling Imagick...
这主要是网络问题,建议等几个小时,如果还是不行,执行下述操作禁用Imagick
插件。
禁用 Imagick 插件
在docker-compose.yml 的environment:
项中添加一行,将PHP插件列表设为空
bash
- NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS=
保存后,执行清理,然后重新运行docker compose up -d
清理安装环境
当需要还原到安装前状态时,执行清理:
bash
docker compose down --volumes
docker rm -f $(docker ps -aq --filter name=^nextcloud-aio --filter name=^nextcloud_aio)
docker volume rm $(docker volume list -q --filter name=^nextcloud-aio --filter name=^nextcloud_aio)
docker network remove nextcloud-aio
# sudo rm -r /newdata/nextcloud # 路径与上面NEXTCLOUD_DATADIR一致。执行该项会删除NextCloud中的所有用户文件
后记
由于NextCloud必需使用固定域名+SSL,因此使用该方案并不灵活,难以通过多种方式连接NextCloud服务,如在可用时流量走局域网。因此,最后采用了基于Tailscale 的方案。
其中compose.yml配置如下
bash
services:
nextcloud-aio-mastercontainer:
image: ghcr.io/nextcloud-releases/all-in-one:latest
init: true
restart: always
container_name: nextcloud-aio-mastercontainer # This line cannot be changed.
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- nextcloud-aio
ports:
- 0.0.0.0:18080:8080
environment:
APACHE_PORT: 11000
APACHE_IP_BINDING: 127.0.0.1
SKIP_DOMAIN_VALIDATION: "true"
NEXTCLOUD_DATADIR: /newdata/nextcloud
NEXTCLOUD_UPLOAD_LIMIT: 128G
NEXTCLOUD_MAX_TIME: 36000
NEXTCLOUD_MEMORY_LIMIT: 1024M
NEXTCLOUD_ENABLE_DRI_DEVICE: "true"
caddy:
build:
context: .
dockerfile: Caddy.Dockerfile
depends_on:
tailscale:
condition: service_healthy
restart: unless-stopped
environment:
NC_DOMAIN: nextcloud.tailb1a5cf.ts.net # Change this to your domain ending with .ts.net in the format {$TS_HOSTNAME}.{tailnetdomain}
volumes:
- type: bind
source: ./Caddyfile
target: /etc/caddy/Caddyfile
- type: volume
source: caddy_certs
target: /certs
- type: volume
source: caddy_data
target: /data
- type: volume
source: caddy_config
target: /config
- type: volume
source: tailscale_sock
target: /var/run/tailscale/ # Mount the volume for /var/run/tailscale/tailscale.sock
read_only: true
network_mode: service:tailscale
tailscale:
image: tailscale/tailscale:v1.82.0
environment:
TS_HOSTNAME: nextcloud # Enter the hostname for your tailnet
TS_AUTH_KEY: tskey-auth-XXXXXXXXXXXX-XXXXXXXXXXXXXX # OAuth client key recommended
TS_EXTRA_ARGS: --advertise-tags=tag:nextcloud
init: true
healthcheck:
test: tailscale status --peers=false --json | grep 'Online.*true'
start_period: 3s
interval: 1s
retries: 3
restart: unless-stopped
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- type: volume
source: tailscale
target: /var/lib/tailscale
- type: volume
source: tailscale_sock
target: /tmp # Mounting the entire /tmp folder to access tailscale.sock
cap_add:
- NET_ADMIN
networks:
- nextcloud-aio
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer # This line cannot be changed.
caddy_certs:
caddy_config:
caddy_data:
tailscale:
tailscale_sock:
networks:
nextcloud-aio:
name: nextcloud-aio
driver: bridge
enable_ipv6: false
driver_opts:
com.docker.network.driver.mtu: "1280" # You can set this to 9001 etc. to use jumbo frames, but packets may be dropped.
com.docker.network.bridge.host_binding_ipv4: "127.0.0.1" # Harden aio
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.default_bridge: "false"
com.docker.network.bridge.enable_ip_masquerade: "true"
注意事项
- 需要打开tailscale的HTTPS Certificates
- 获取ts密钥时记得勾选
Ephemeral
- 手动迁移/修改数据后输入
docker exec -it nextcloud-aio-nextcloud su www-data -c "php /var/www/html/occ files:scan --all"
扫描更新 - NextCloud 的 docker volume 存放位置无法更改,手动迁移 docker volume 时需要使用
cp -rp
保留文件权限标识