【实用的开源工具】Nextcloud AIO:用一个主容器管起整套私有网盘
「实用的开源工具」系列:我只收集值得用的开源项目,写清楚它能做什么、怎么部署、有哪些坑,并在文末标明出处。内容整理自官方文档,核对日期 2026-10-31,具体版本以官方为准。文中的命令都是照官方文档整理的,上线前请先在一台测试机上完整走一遍。
项目信息卡
| 项目 | 说明 |
|---|---|
| 名称 | Nextcloud All-in-One(简称 AIO) |
| 做什么 | 用一个“主容器”(mastercontainer)自动创建、更新整套 Nextcloud 所需的容器,并提供网页管理界面 |
| 许可证 | AGPL-3.0(仓库 LICENSE 文件为 GNU AGPL v3) |
| 仓库 | github.com/nextcloud/all-in-one |
| 最近版本 | v14.4.3(2026-10-29 发布,查询于 2026-10-31) |
| 维护状态 | 仓库未归档,2026-10-31 仍有推送。README 顶部写着项目在招募贡献者 |
| 用户数 | 官方 FAQ 写明最多 100 个用户免费,更多用户可选用 Nextcloud Enterprise |
| 运行方式 | Docker。官方支持的 CPU 架构:x86_64 和 aarch64 |
| 默认带的组件 | Nextcloud、Apache 代理、PostgreSQL、Redis、Notify Push;Office、Talk、ClamAV 等是可选容器 |
| 管理界面 | 主容器的 8080 端口(自签名证书)或 8443 端口(有效证书) |
它能做什么
README 把它描述成“Nextcloud 的官方安装方式”,特点是装一个容器、其余自动搞定:
- 一条命令起步:只需要启动主容器,主容器通过 Docker socket 去创建 Nextcloud、数据库、缓存等其他容器。
- 网页管理界面:在界面里启动、停止、更新容器,开关可选组件,查看容器日志。
- 可选组件:Nextcloud Office、Talk(含 TURN 服务)、全文搜索、ClamAV 杀毒、Imaginary 图片预览、Whiteboard 等,在界面里勾选即可。
- 内置备份:基于 BorgBackup,可以在界面里创建、恢复、检查备份,也可以开每日备份。
- 自动 HTTPS:不用自己的反向代理时,内置的代理会通过 Let's Encrypt 申请证书。
不适合的场景:README 说明它不支持用 IP 地址代替域名、不支持自签名证书、不支持子目录部署、不支持离线环境。如果你的环境满足不了这些,要先看文末的“踩坑清单”。
部署前要准备什么
- 一台装好 Docker 的 Linux 服务器。README 明确写了 不支持 snap 版 Docker(通常是 Ubuntu 上的情况),并给了检查命令:
sudo docker info | grep "Docker Root Dir" | grep "/var/snap/docker/"如果输出里出现 /var/snap/docker/,要先改装标准版 Docker。
- 一个解析到服务器的域名(后面的
cloud.example.com请换成自己的)。 - 官方对存储的建议:不推荐 SD 卡,推荐 SSD,HDD 也能用但慢很多。
- README 里没有给出最低 CPU 和内存数字,所以这里不写具体配置要求。
部署方式一:官方默认命令(不套反向代理)
README 给的启动命令如下(适用于“服务器上没有 Web 服务器、也没有反向代理”的情况):
sudo docker run \
--init \
--sig-proxy=false \
--name nextcloud-aio-mastercontainer \
--restart always \
--publish 80:80 \
--publish 8080:8080 \
--publish 8443:8443 \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
ghcr.io/nextcloud-releases/all-in-one:latest官方对几个关键参数的说明:
--name nextcloud-aio-mastercontainer:不要改容器名,主容器的更新依赖这个名字。--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config:不要改卷名,内置备份依赖它。--publish 80:80:用于 ACME http-challenge 申请证书;如果你用反向代理,可以不要。--publish 8080:8080:管理界面,自签名证书。--publish 8443:8443:管理界面,有效证书;要求 80 和 8443 都能从外网访问,且有域名指向服务器;用反向代理时可以不要。/var/run/docker.sock:主容器靠它管理其他容器;在 Windows、macOS 或 rootless Docker 下需要按文档调整路径,并设置WATCHTOWER_DOCKER_SOCKET_PATH。- 镜像标签:README 和 compose 文件里只出现
latest(以及测试用的beta),没有提到固定到某个版本号的标签,所以这里不写“固定版本”的做法。
README 也提到:生产环境更建议用仓库里的 compose.yaml,不要直接用 docker run。
部署方式二:套一层自己的反向代理(推荐已有 Nginx/Caddy 的人)
如果 443 端口已经被别的网站占用,或者你就是想用自己的反向代理,要看官方的 反向代理文档。流程是三个必做步骤:配好代理、给 Apache 容器指定端口、打开 8080 界面校验域名。
反向代理版本的启动命令,在默认命令基础上去掉 80 和 8443,加上几个环境变量(官方原文示例里 APACHE_IP_BINDING 是 0.0.0.0,我按官方“代理跑在本机时可限制为 localhost”的说法改成了 127.0.0.1):
sudo docker run \
--init \
--sig-proxy=false \
--name nextcloud-aio-mastercontainer \
--restart always \
--publish 8080:8080 \
--env APACHE_PORT=11000 \
--env APACHE_IP_BINDING=127.0.0.1 \
--env APACHE_ADDITIONAL_NETWORK="" \
--env SKIP_DOMAIN_VALIDATION=false \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
ghcr.io/nextcloud-releases/all-in-one:latestAPACHE_PORT=11000:AIO 内部的 Apache 容器发布到宿主机的端口,你的反向代理要指向它。APACHE_IP_BINDING=127.0.0.1:官方说明只有在你的反向代理用localhost或127.0.0.1连接它时才建议这样设;如果代理用别的 IP 来连,要设成0.0.0.0。- 反向代理在另一台机器上,或者在别的 Docker 网络里,官方给了三种连接方式(host 网络、
APACHE_ADDITIONAL_NETWORK、加入nextcloud-aio网络),细节请看官方文档。
同样的内容写成 compose.yaml(根据官方仓库的 compose 文件整理,只保留了需要的部分):
name: nextcloud-aio
services:
nextcloud-aio-mastercontainer:
image: ghcr.io/nextcloud-releases/all-in-one:latest
init: true
restart: always
container_name: nextcloud-aio-mastercontainer
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
network_mode: bridge
ports:
- "8080:8080"
environment:
APACHE_PORT: 11000
APACHE_IP_BINDING: 127.0.0.1
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer官方 compose 里对容器名和卷名的注释是“这一行不允许修改”,所以不要改。
Caddy 示例
官方称 Caddy 是推荐的反向代理,给的 Caddyfile 就两行:
https://cloud.example.com:443 {
reverse_proxy localhost:11000
}端口 11000 要和 APACHE_PORT 一致。
Nginx 示例
官方 Nginx 模板很长(带注释、HTTP/3、不同 Nginx 版本的写法)。下面是从官方模板里摘出来的核心部分,保留了原样的行,删掉了 HTTP/3 相关的注释和不同版本的备选行;nginx -v 看一下自己的版本,如果低于 1.25.1,http2 on; 和 listen ... ssl 的写法要按官方模板里的版本注释改:
# 以下放在 http { } 里
map $http_upgrade $connection_upgrade {
default upgrade;
"" "";
}
upstream nextcloud {
keepalive 32; # Nginx 低于 v1.29.7 时需要
server 127.0.0.1:11000; # 与 APACHE_PORT、APACHE_IP_BINDING 对应
}
server {
listen 0.0.0.0:80;
listen [::]:80;
if ($scheme = "http") {
return 301 https://$host$request_uri;
}
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
listen 0.0.0.0:443 ssl;
listen [::]:443 ssl;
http2 on; # Nginx v1.25.1 及以上
server_name cloud.example.com;
ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
proxy_buffering off;
proxy_request_buffering off;
proxy_socket_keepalive on;
client_max_body_size 0;
# NEXTCLOUD_MAX_TIME 默认 3600 秒,这里设得比它大 10 秒,保证先超时的是 Nextcloud 而不是 Nginx
proxy_read_timeout 3610s;
location / {
proxy_pass http://nextcloud;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}两点说明:官方模板里 listen 行还带有 bind reuseport deferred so_keepalive=on 这类选项,我简化掉了,需要的话照官方模板加回去;官方也提醒,如果前面还有第二层代理或 Cloudflare,要在 http 里设置 set_real_ip_from 等可信 IP。
在反向代理里要特别知道的几点
- 官方明确:只支持独立域名,不能放在
example.com/nextcloud/这样的子目录。 - 使用反向代理时,会“关闭 AIO 自带的 HTTPS”,证书由你的代理负责。
- 如果你的代理不是用
localhost/127.0.0.1连 Nextcloud,要把它的 IP 加进 Nextcloud 的trusted_proxies,官方命令是:
sudo docker exec --user www-data -it nextcloud-aio-nextcloud php occ config:system:set trusted_proxies 2 --value=ip.address.of.proxy必须开放的端口
官方 FAQ 的说法是:如果你在内网用 8080 访问管理界面,防火墙/路由器只需要放行下面这些:
| 端口 | 用途 |
|---|---|
443/TCP | Apache 容器(Nextcloud 本体) |
443/UDP | 想启用 HTTP/3 时才需要 |
3478/TCP 和 3478/UDP | Talk 容器里的 TURN 服务,只有启用 Talk 才需要 |
其他端口的作用(官方 FAQ 里的说明):8080/TCP 是主容器管理界面(自签名证书);80/TCP 用于主容器通过 ACME http-challenge 申请证书;8443/TCP 是带有效证书的管理界面(需要 80 和 8443 都放行并且有域名)。如果 3478 被占用,compose 文件里有 TALK_PORT 变量可以调整。
第一次使用
官方的步骤大致是:
- 启动主容器后,用浏览器打开 服务器的 IP 地址 加 8080 端口,例如
https://192.168.5.5:8080。官方强调:这里要用 IP 访问,不要用域名,因为 HSTS 之后可能会导致打不开。8080 用的是自签名证书,浏览器会提示风险,需要手动接受。 - 在界面里输入你的域名并做域名校验(下一节说明)。
- 在界面里勾选需要的可选组件,然后启动容器。启用 Talk 要记得放行 3478。
- 官方还说明:Nextcloud 在运行期间,直接在登录页输入 AIO passphrase 是被禁用的;需要以 Nextcloud 管理员登录后,在
https://你的域名/settings/admin/overview页面点击顶部的按钮,才能进入 AIO 登录页(容器停止期间则不受限制)。这个入口在 5 分钟后或输错 5 次密码后会重新被禁用。
README 没有写明首次访问界面时 passphrase 怎么显示、Nextcloud 管理员账号怎么初始化的具体界面步骤,所以这部分我不展开,请以你打开界面后的提示为准。
域名校验
- 官方要求:必须有域名,必须有有效证书;不支持纯 IP 访问、不支持自签名证书。想在局域网内用,要看官方的 local-instance 文档,那里的做法是依然要有有效证书;这类本地部署不需要域名校验。
- 没有域名的话,官方说可以在界面里通过 deSEC 免费注册一个
dedyn.io的子域名,注册后会自动启用 Caddy 和 dnsmasq 两个社区容器。 - 如果校验过不去,官方给了几个办法:
- 在主容器启动命令里加 --env SKIP_DOMAIN_VALIDATION=true(要放在最后一行镜像名之前);已运行的话需要停掉、删除主容器后按原命令重建(官方说数据不会丢)。 - 或者在界面地址后面加上参数跳过,官方示例:https://ip.address.of.the.server:8080/containers?skip_domain_validation。 - 报“内部或保留 IP 地址”错误时,确认域名解析正确后,在启动命令里加 --add-host yourdomain.com:<public-ip-address>。
- 官方还说明:域名校验只在最初做一次,之后即使 A 记录变了,主容器也不会再去访问这个域名。
- 如果走 Cloudflare,官方指出校验可能被 Cloudflare 拦住,可以直接跳过校验。
备份(BorgBackup)
官方文档里关于备份的要点:
- 备份基于 BorgBackup,增量、压缩、加密,只有第一次会比较慢。
- 在管理界面的备份区域填入备份目录(比如挂载的外接硬盘
/mnt/backup),点Create Backup创建备份,用Restore selected backup恢复,也有备份完整性检查。 - 备份用的加密密钥会显示在界面里,务必另外保存,官方说没有这个密钥就恢复不了备份。
- 初次备份完成后,可以开启每日备份;开启后还可以勾选“自动更新所有容器、Nextcloud 及其应用”。
- 也支持直接备份到远程 borg 仓库:界面里本地路径留空、填仓库地址,创建备份时会生成 SSH 密钥对并先失败一次,把界面里显示的公钥加到远程服务器的 authorized keys 后再试。
- 默认保留策略是
--keep-within=7d --keep-weekly=4 --keep-monthly=6,可以用环境变量BORG_RETENTION_POLICY修改,官方提醒值要合法,且不要带-a/--glob-archives。 - 通过“外部存储”应用挂载进来的文件和目录不在备份里。 备份完成后可以额外添加要备份的 Docker 卷或宿主机路径。
- 官方还提供了把 AIO 迁到另一台机器的流程:旧机上更新、停止容器、创建备份并记下路径和密码,拷贝
borg目录到新机,新机上装好 AIO 但先不启动容器,再在界面里选 “Restore former AIO instance from backup”。
更新与卸载
更新(官方 FAQ 的做法):
- 有新容器版本时,界面的
containers区域下面会提示。先点Stop containers,再点Start and update containers。 - 官方建议:在重新启动容器之前先用内置备份创建一次备份,否则更新出问题不容易恢复。
- 主容器(mastercontainer)有单独的更新流程:有新版本时,停掉容器后界面会多出一个更新主容器的按钮,更新完成后再
Start and update containers。 - 每天有一个定时任务检查容器和主容器的更新,并通知所有 Nextcloud 管理员。
- 开启每日备份后可以顺便自动更新所有容器(见上一节)。
- 官方有一篇 manual-upgrade 文档,说明如果 6 个月以上没更新,之后再更新可能会因为 nextcloud 容器内 PHP 版本不兼容而无法启动,需要按文档手动处理。所以要定期更新。
卸载: 官方没有单独的“卸载”章节,最接近的是“如何重置实例”。官方明确写了:这会删除和该 AIO 实例相关的全部数据,已经有数据时不要照做。步骤大意是:先在界面停掉所有容器,docker stop nextcloud-aio-mastercontainer,停掉 nextcloud-aio-domaincheck(如果还在),确认没有 nextcloud-aio 容器后清理已停止的容器、删除 nextcloud-aio 网络,再清理 volume;如果你把 NEXTCLOUD_DATADIR 设成了宿主机路径,还要手动删那个目录。完整命令请看官方 README 的 “How to properly reset the instance?” 一节,不要凭记忆敲。
踩坑清单
- 访问 8080 必须用 IP,不要用域名。 官方反复强调,用域名可能暂时能打开,之后会被 HSTS 卡住。
- 容器名和卷名不能改。
nextcloud-aio-mastercontainer和nextcloud_aio_mastercontainer官方都标注了“不允许修改”,否则更新和内置备份会出问题。 - 不要用 snap 版 Docker。 README 把它列为警告项。
- 不支持 IP 访问、自签名证书、子目录、非 443 端口、多个域名、离线环境。 这几项 FAQ 里都明确回答了“No”,而且说“不会增加”。需要多个域名的话,官方建议用多实例方案。
- 443 被占用时用反向代理,并且
APACHE_PORT、代理端口要一致。 官方 debug 清单里第一条就是照着文档一步步来;APACHE_IP_BINDING拿不准时设成0.0.0.0。 NEXTCLOUD_DATADIR只能在最初设置。 compose 文件里有警告:初始安装完成后不要再设置或改它。- 改域名没有界面入口。 官方说目前需要手动编辑主容器卷里的
configuration.json,改完还要手动更新 Talk、主题、App API 等几处设置,改之前先备份。 - 用 Cloudflare 代理或隧道要接受一堆限制。 官方列了很多:Cloudflare 终止 TLS 能看到明文流量;免费版单次上传限 100 MB;请求超时 100 秒;内置 Talk 的 TURN 在 Cloudflare Tunnel 后面不能用;要关闭 Rocket Loader,否则登录框不显示;域名校验可能被拦。
- RHEL/Fedora/CentOS 系统上 firewalld 可能导致容器之间不通。 官方给了把
FirewallBackend改成iptables并重启 firewalld 与 docker 的办法。启用 SELinux 时,主容器可能要加--security-opt label:disable(compose 里是security_opt: ["label:disable"])。 - 管理界面 8443 的证书机制会被陌生人“戳”。 官方说明内置 Caddy 会对任意域名接受 ACME 挑战,不会危及服务器安全,但会造成日志混乱和证书限流,建议把 AIO 界面放在 VPN 后面或限制暴露范围。
- 备份不包含外部存储,并且密钥丢了就恢复不了。 加密密钥要另存;外部存储里的文件要自己想办法备份。
- 几个 VPS 有已知问题。 官方在“不推荐”列表里写了旧版 Strato(Virtuozzo)和 Hostinger 的 VPS;一般建议用 KVM / 非容器虚拟化的 VPS。
- 主容器能控制 Docker,等同于很高权限。 因为要挂
/var/run/docker.sock,官方也提供了不暴露 socket 的 manual-install 方案。这是我的建议:只有信得过的人才应该能登录 AIO 界面。 - Docker 发布的端口会绕过 ufw 之类的防火墙。 这是通用经验,不是 AIO 文档的说法:
--publish 8080:8080会对外网开放管理界面,建议在云厂商安全组或上游防火墙里限制来源,或者只在需要时开放。
出处
有想法或问题?去留言板留言 →