本文简单记录利用Docker-compose搭建知名开源网盘项目:Nextcloud 的全过程。
前言
Q:为什么搭建个人网盘?
A:起因确实很草率,因为我个人数据并不多,相册有iCloud和Amazon双重备份,还有喜欢把数据存放在本地设备的习惯,是数据囤鼠,但不爱整理。前些天一直在用国内的百度网盘下载游戏资源,都是大型档案。突然在某篇博客中发现博主使用自建的Nextcloud服务链接分享文件,因为我曾注册过Nextcloud官方项目的账号却不知道还有公开链接这个功能,于是准备操手自建。拥有网盘之后大概就会整理数据了吧。
Q:前置准备?
A:硬盘大小心仪的服务器一枚。
我手头目前有且只有一台超小型流量用途的VPS用来给国内的亲友翻墙用,兼职 Mastodon bot 的运行,硬盘容量可以说是忽略不计的,所以新开了一个Storage VPS。
我选择的是美国提供商interserver的最小型Storage VPS方案,月付3美元1C2G硬盘HDD1T。注册时出现了插曲,提示我拥有他们的账号。仔细一看原来两年前我薅过他家超小型VPS的年付羊毛…(真是对不起了)
环境准备
系统选择 Debian 12,Ubuntu 已经用不习惯了。root用户登入服务器,准备一些我爱用的小东西(不感兴趣可直接跳到下一节,确保安装Docker 和Docker Compose即可)。
切换为zsh
因为我平时用MacOS,把本地的终端shell换成了zsh(而且更好看),所以尝试按照Debian官方文档操刀换了一下zsh SHELL,然后安装ohmyzsh。
apt update && apt upgrade -yapt install zsh zplugapt update && apt install wget rsync git curl vim git ufw -y ## 安装常用工具
nano ~/.zshrc
编辑配置文件,填入以下内容:
# Set path if required#export PATH=$GOPATH/bin:/usr/local/go/bin:$PATH
# Aliasesalias ls='ls --color=auto'alias ll='ls -lah --color=auto'alias grep='grep --color=auto'alias ec="$EDITOR $HOME/.zshrc" # edit .zshrcalias sc="source $HOME/.zshrc" # reload zsh configuration
# Set up the prompt - if you load Theme with zplugin as in this example, this will be overriden by the Theme. If you comment out the Theme in zplugins, this will be loaded.autoload -Uz promptinitpromptinitprompt adam1 # see Zsh Prompt Theme below
# Use emacs keybindings even if our EDITOR is set to vibindkey -e
setopt histignorealldups sharehistory
# Keep 5000 lines of history within the shell and save it to ~/.zsh_history:HISTSIZE=5000SAVEHIST=5000HISTFILE=~/.zsh_history
# Use modern completion systemautoload -Uz compinitcompinit
# zplug - manage pluginssource /usr/share/zplug/init.zshzplug "plugins/git", from:oh-my-zshzplug "plugins/sudo", from:oh-my-zshzplug "plugins/command-not-found", from:oh-my-zshzplug "zsh-users/zsh-syntax-highlighting"zplug "zsh-users/zsh-autosuggestions"zplug "zsh-users/zsh-history-substring-search"zplug "zsh-users/zsh-completions"zplug "junegunn/fzf"zplug "themes/robbyrussell", from:oh-my-zsh, as:theme # Theme
# zplug - install/load new plugins when zsh is started or reloadedif ! zplug check --verbose; then printf "Install? [y/N]: " if read -q; then echo; zplug install fifizplug load --verbose
文件内容保存后启动zsh:
zsh
设置zsh为预设SHELL:
chsh -s /bin/zsh
加载刚刚编辑过的配置文件:
source $HOME/.zshrc
这样预设SHELL就换为zsh了,可以关掉vps重新登入一下看看!另外说一下切换shell建议在服务器刚开不久还没有配多少环境变量的时候切换,因为切换shell后环境变量要重新配置一遍,无用的工程量会变大。
此时虽然zsh安装了,但不是我喜欢的ohmyzsh方案,于是在刚安装的zsh基础上应用ohmyzsh。
ohmyzsh配置
root@vps3069924 ~ # sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
ohmyzsh的安装很简单,因为它是一个配置方案,只要运行如上命令即可。
按照ohmyzsh官方方法配置,报错:
The $ZSH folder already exists (/root/.zplug/repos/ohmyzsh/ohmyzsh).
You ran the installer with the $ZSH setting or the $ZSH variable isexported. You have 3 options:
1. Unset the ZSH variable when calling the installer: ZSH= sh install.sh2. Install Oh My Zsh to a directory that doesn't exist yet: ZSH=path/to/new/ohmyzsh/folder sh install.sh3. (Caution) If the folder doesn't contain important information, you can just remove it with rm -r /root/.zplug/repos/ohmyzsh/ohmyzsh
报错指出,当前已经使用zplug
管理 Zsh 插件系统,而 Oh My Zsh 自身其实也是一个插件管理框架。现在zplug 已安装并管理了一部分 oh-my-zsh 的插件,再安装 Oh My Zsh 会与现有目录冲突($ZSH
被指向了 /root/.zplug/repos/ohmyzsh/ohmyzsh
)。
于是手动清理冲突目录并安装ohmyzsh:
rm -rf /root/.zplug/repos/ohmyzsh/ohmyzshsh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
熟悉的界面,好舒服。原来最开始不安装zplug就好了,apt remove zplug
卸载zplug。
安装zsh插件
由于不再用zplug
管理 oh-my-zsh 的插件,因此卸载掉zplug
,使用 Oh My Zsh管理插件。因为刚刚卸载掉的zplug
自带了一些实用插件,我想保留其中的以下三个插件到oh my zsh:
# 快速切换目录zplug "rupa/z", use:z.sh
# 自动建议插件zplug "zsh-users/zsh-autosuggestions"
# 语法高亮zplug "zsh-users/zsh-syntax-highlighting", defer:2
这是之前zplug管理插件时自动安装的几个优秀插件,看着很心动,于是在ohmyzsh复现,不想安装zsh插件可忽略此处步骤。
Oh My Zsh 自带插件的目录在:~/.oh-my-zsh/plugins/
,运行:
# 自动建议git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
# 语法高亮git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
# 快速切换目录 zgit clone https://github.com/rupa/z.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/z
# ${ZSH_CUSTOM} 是 Oh My Zsh 的用户自定义插件路径,默认为 ~/.oh-my-zsh/custom
运行nano ~/.zshrc
编辑~/.zshrc
添加插件。
找到plugins=(git)
这一行,注释掉,添加以下内容:
plugins=( git zsh-autosuggestions zsh-syntax-highlighting z)
保存文件,运行source ~/.zshrc
使配置生效。
swap 虚拟内存添加
我的服务器内存太小了怕docker服务一起来会当机(尤其是当1c2g服务器用docker运行mastodon,谁用谁知道),所以添加一下虚拟内存。
首先运行一下free -h
看看服务器是否有厂商设定的swap空间。
total used free shared buff/cache availableMem: 1.9Gi 999Mi 153Mi 84Mi 1.1Gi 967MiSwap: 0.5Gi 43Mi 0.4Gi
查看当前的 swap 使用情况(路径和设备)swapon --show
:
NAME TYPE SIZE USED PRIO/dev/sda2 partition 488M 43.7M -2
可以看到我的服务器自带配置了一个0.5G的swap来缓解内存不足情况的,但是0.5G不是很够用,我准备把swap加到内存的2倍,也就是4G。
wget https://web.archive.org/web/20200920015125if_/https://www.moerats.com/usr/shell/swap.sh && bash swap.sh
运行这个一键添加/删除Swap虚拟内存脚本,输入数字2删除当前的swap。然后bash swap.sh
重新运行脚本添加swap,输入4096(单位是MB),创建4G的虚拟内存。
重新运行swapon --show
:
NAME TYPE SIZE USED PRIO/swapfile file 4G 141.3M -2
swap 添加成功了。
docker compose环境构建
#安装dockerbash <(curl -L https://get.docker.com/)
判断服务器架构:
➜ ~ uname -sLinux➜ ~ uname -mx86_64
是linux x86_64的服务器,于是安装docker-compose:
先去docker compose releases页面看一下当前最新版本号,比如v2.36.2
。
#安装特定版本的docker-composecurl -L "https://github.com/docker/compose/releases/download/v2.36.2/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose #赋权
查看安装版本:
➜ ~ docker-compose -vDocker Compose version v2.36.2➜ ~ docker -vDocker version 28.2.2, build e6534b4
如果想要更新docker-compose
版本,先运行which docker-compose
找到安装位置(例如/usr/local/bin/docker-compose
),随后rm -rf /usr/local/bin/docker-compose
删去旧版本,然后运行脚本命令直接安装新版本docker-compose
并赋权即可。
Nginx 安装
apt install nginx -y
然后安装certbot
以管理域名证书,这里我用snap
安装certbot
(Debian也可以用apt安装但我爱snap):
apt install snapdsnap install core #安装snapsnap install certbot --classic #使用snap安装certbot
查看certbot能否运行:
➜ ~ which certbotcertbot not found➜ ~ certbot --nginxzsh: command not found: certbot
环境变量没加载出来。运行nano ~/.zshrc
,添加一行:
export PATH=$PATH:/snap/bin
保存文件,运行source ~/.zshrc
使配置生效。
➜ ~ which certbot/snap/bin/certbot
certbot
安装成功。
docker 图形化管理工具
任意目录下运行:
docker run -d --name dpanel --restart=always \\n -p 8807:8080 -e APP_NAME=dpanel \\n -v /var/run/docker.sock:/var/run/docker.sock -v dpanel:/dpanel \\n dpanel/dpanel:lite
docker 启动图形化管理工具dpanel
,将本地8807
端口映射到容器内8080
(8807
可更改成其他非常用端口),数据存放在数据卷dpanel
中,镜像是dpanel
的lite版本。
nano /etc/nginx/conf.d/dpanel.conf
编辑nginx配置文件,内容如下:
server { listen 80; server_name docker.example.com; # 修改这里为已有域名
location / { proxy_pass http://127.0.0.1:8807; # docker命令中指定的本地非常用端口 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}
测试配置文件是否有错误(试运行):
nginx -t
若没有错误,生效新的配置文件并运行 Nginx,开机启动:
nginx -s reloadsystemctl start nginxsystemctl enable nginx
在域名DNS管理面板中添加一条字段为docker
,指向服务器ip:8807
的A
记录,回到服务器运行certbot --nginx
按提示获得证书。成功后就可以用指定域名docker.example.com
HTTPS访问管理面板了,然后注册管理员账号即可用面板管理docker资源。
正式搭建过程
启动容器
新建一个目录用来存放Nextcloud的docker文件,例如/opt/nextcloud
:
cd /opt&&mkdir nextcloudcd nextcloud
nano docker-compose.yml
新建yml配置文件:
services: db: image: mariadb restart: always volumes: - "./data:/var/lib/mysql" environment: - MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD} # .envファイルに環境変数を設定 - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD} # .envファイルに環境変数を設定 - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud
app: image: nextcloud ports: - 8080:80 links: - db volumes: - "./nextcloud:/var/www/html" restart: always environment: - MYSQL_HOST=db - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - MYSQL_PASSWORD=strong_db_pass - PUID=1000 - PGID=1000 - TZ=Asia/Tokyo
redis: image: redis:alpine restart: always
nano .env
新建一个环境变量文件,用来保存Mysql数据库的密码:
# docker-compose内で利用する環境変数をここで設定します。# 下記2つの環境変数に、適当な文字列を設定してください。
ENV_MYSQL_ROOT_PASSWORD=数据库root用户密码ENV_MYSQL_PASSWORD=strong_db_pass
然后运行docker-compose up -d
,稍等一会服务就起来了。可以运行docker ps
看一下容器的运行状况。
Nginx反向代理
确保已经安装nginx和certbot。
nano /etc/nginx/conf.d/nextcloud.conf
编辑nginx配置文件,内容如下:
server { server_name nextcloud域名;
location / { proxy_pass http://127.0.0.1:8080; #8080改为nextcloud对外开放的端口,默认为8080 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
# 客户端访问 https://example.com/.well-known/carddav 时 # 自动重定向到 https://example.com/remote.php/dav location = /.well-known/carddav { return 301 $scheme://$host/remote.php/dav; } # 同上 location = /.well-known/caldav { return 301 $scheme://$host/remote.php/dav; }
client_max_body_size 0; # nginx对文件大小无限制 fastcgi_read_timeout 3600; # 超时 fastcgi_request_buffering off; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; # 解决管理控制台未设置 Strict-Transport-Security的警报}
保存之后运行
nginx -t && nginx -s reload # 重载配置systemctl reload nginx # 开机启动
添加A
记录后运行certbot --nginx
按提示获得证书,然后就可以用指定域名访问Nextcloud服务了,首先会提示创建管理员账号。
配置与修复警报
Nextcloud如果用官方镜像而且最低配置的话会在web端管理后台弹出超级多的警报,例如:
通过 HTTP 不安全地访问网站。 强烈建议您将服务器设置为需要 HTTPS。 如果没有它,一些重要的网络功能(例如 "复制到剪贴板" 或 "服务人员" )将无法工作! 了解更多详情,请参见文档 ↗。自从 May 29, 2025, 2:15:58 PM 日志中存在 3 个错误服务器没有配置维护时段开始时间。 这意味着资源密集型日常后台作业也将在您的主要使用时间执行。 我们建议将其设置为低使用率的时间,这样用户就不会受到这些繁重任务造成的负载的影响。 了解更多详情,请参见文档 ↗。One or more mimetype migrations are available. Occasionally new mimetypes are added to better handle certain file types. Migrating the mimetypes take a long time on larger instances so this is not done automatically during upgrades. Use the command occ maintenance:repair --include-expensive to perform the migrations.您的实例上的某些标头设置不正确 - 未设置 Strict-Transport-Security HTTP 标头(应至少为 15552000 秒)。为了增强安全性,建议启用 HSTS。 了解更多详情,请参见文档 ↗。检测到 MariaDB 版本"11.7.2-MariaDB-ubu2404"。建议使用 MariaDB >=10.6 和 <=11.4,以获得此版本 Nextcloud 的最佳性能、稳定性和功能。当前正在使用数据库处理事务性文件锁定。若有内存缓存可用,请进行配置以提升性能。 了解更多详情,请参见文档 ↗。您在安装过程中未设置默认的国际区号。缺失国际区号的电话号码时将使用默认的国际区号进行验证。要允许无国际区号的电话,请在您的配置文件中添加 “default_phone_region” 设置选项并依照 ISO 3166-1 进行设置。 了解更多详情,请参见文档 ↗。您尚未配置电子邮件服务器或尚未验证配置。请在“基本设置”中进行配置。配置完毕后,请点击表单下方的“发送电子邮件”按钮来验证您的设置。 了解更多详情,请参见文档 ↗。请仔细检查安装指南↗,并检查日志中是否有错误或警告。
通过我们的安全检查 ↗检查您 Nextcloud 的安全
先解决一下管理控制台英文警报的数据库更新(使用occ
命令):
docker exec -u www-data nextcloud-app-1 php occ maintenance:repair --include-expensive
除了数据库版本那条(我懒得管它)以外,这些警报解决大多只需要进入docker容器修改一下配置文件就好,例如config/config.php
。
网上看绝大多数人用nextcloud都是将持久化数据放在volume卷上,只能说踩大坑不好管理,不如像我一样在yml中指定"./nextcloud:/var/www/html"
直接将目录映射到主机内,不需要进入容器就可以修改文件。还看到有人是为了配置config.php
自己建了镜像,但这种小项目我更喜欢官方构建的镜像,升级备份的额外操作有迹可循。
cd /opt/nextcloudnano ./nextcloud/config/config.php
添加内容(记得把注释删除):
'default_phone_region' => 'JP', # 国际区号 'overwriteprotocol' => 'https', # 指定https 'maintenance_window_start' => 3, # 设置维护时段,凌晨 3 点开始执行资源密集型任务 'memcache.locking' => '\\OC\\Memcache\\Redis', # 配置redis缓存 'memcache.distributed' => '\\OC\\Memcache\\Redis', # 如果docker-compose.yml没开redis服务的话这里不需要redis相关内容,但推荐开启redis 'redis' => array ( 'host' => 'redis', 'port' => 6379, ), # 即使是小型服务器也会有性能提升。不开会提示:事务锁使用数据库而非缓存 'mail_from_address' => 'notifications', # 配置smtp邮箱发件服务,按照邮件提供商的smtp配置填写 'mail_smtpmode' => 'smtp', 'mail_smtpauthtype' => 'LOGIN', 'mail_smtpport' => '587', 'mail_smtpserver' => 'smtp.example.com', 'mail_domain' => 'example.com', 'mail_sendmailmode' => 'smtp', 'mail_smtphost' => 'smtp.example.com', 'mail_smtpauth' => true, 'mail_smtppassword' => 'password', 'tempdirectory' => '/var/www/html/data/tmp', # nextcloud应用层临时目录
刚刚设置了一个新的临时目录./data/tmp
,现在要进入容器内创建一下:
docker-compose up -ddocker exec -it nextcloud-app-1 bashmkdir -p /var/www/html/data/tmpchown -R www-data:www-data /var/www/html/data/tmpchmod 770 /var/www/html/data/tmp # 设置正确权限,Nextcloud通常以 www-data 用户运行exit
设置上传大小限制等(参考官方文档Uploading big files > 512MB):
cd /opt/nextcloudnano ./nextcloud/.user.ini
添加以下内容:
upload_max_filesize = 16Gpost_max_size = 16Gmax_execution_time = 3600max_input_time = 3600memory_limit = 512Moutput_buffering = 0
保存之后运行docker-compose up -d
即可生效。
现在重新进入管理控制台,应该不会再弹出恼人的警报了。官方镜像爱好者狂喜。