前言

现状的网盘大家应该也深有感受,从一开始打着免费的幌子,到后来的全面收割。其实也是资本最终的归宿。随之而来的就是大容量网盘就给你限速,128kB的感人下载速度,要不就是不限速容量很少,5G,10G空间。还有限制转存的文件数量,反正就是两个字难受。

把数据上传到网盘还有一点就是安全性,个人数据甚至还有私人敏感数据传到公有云的话是数据是很容易暴露的。机密数据商业数据更是重要。

对于私网用户无法使用,有些保密环境或者没有公网条件的,也是不能使用公有云,解决办法当然是构建自己的网盘系统。

开源网盘系统选择

个人使用开源网盘最早应该可以追溯到2017年刚购买VPS时,当时进入决赛圈的网盘系统有两个一个是onecloud,另一个是nextcloud,看资料是说nextcloudonecloud的升级免费开源版本,但是稳定性可能会稍微差一些。对于极客毫无疑问选择nextcloud,现在2025来看当时的选择还是对的。现在个人网盘系统基本都是nextcloud,一些虚拟应用提供商提供的标准解决方案也是nextcloud

nextcloud使用感受

2017年使用VPS搭建nextcloud,当时购买的服务器性能太感人,1核1G1M,部署之后单个用户打开网站要等待很久。nextcloud本身对硬件要求比较高,PHP运行效率也不是那么的高。而且带宽只有1M,不算动态资源运算,就只拉取展示数据就很慢。所以在VPS的环境下基本是网站只能够打开,无法使用。

2020年左右VPS到期,转为自建服务器。服务器性能全面提升,网络带宽也由VPS1M提升为24M,此时使用nextcloud效果就好很多,只是开始服务器使用的KVM架构,性能相对裸机也会有一定损失,打开nextcloud网页时,能明显感受到服务器风扇转速拉高。KVM架构nextcloud在虚拟机内部相当于裸机安装,需要LAMP环境,需要配置PHP的插件和最大上传大小。mysql中需要新建nextcloud所使用的用户和数据库,操作相对复杂(个人使用脚本实现了一键安装和配置,需要的可以私信)。

nextcloud Docker Compose方式安装

获取官方示例

命令行获取官方源码即可:git pull https://github.com/nextcloud/docker.git,这里需要访问github,如果没有科学上网环境,使用hosts方式也能实现访问,但是效果没有科学上网好。这里推荐一个hosts每日更新网址。https://raw.hellogithub.com/hosts,点击会自动下载,然后放到本地hosts文件即可生效。

准备需要文件

在源码中我们需要的文件如图所示:image-20250106174559739

示例文件夹中的内容如图所示:

image-20250106175131099

因为我们会用npm进行代理配置,所以我们选择insecure安全模式,数据库我这边选择的是mariadbmariadb下的目录如下:

image-20250106175454129

我们选择性能更高的fpm即可。我们把fpm下的所有内容拷贝出来。我这里直接放在/tmp/nextcloud目录下。参考命令:cp docker/.examples/docker-compose/insecure/mariadb/fpm ./ -R 复制相应目录到本地。最后所有需要文件如图所示:

image-20250106180221383

这里web目录下是compose.yamlhtml容器所需要的编译镜像需要文件,nginx+fpm实现PHP网页服务。

修改web下nginx.conf

使用vim直接修改即可vim web/nginx.conf

  • 55行去掉注释#注释
  • 58client_max_body_size修改为0,即不对body进行限制
  • 127行后面增加重写规则
location = /.well-known/webfinger { return 301 /index.php/.well-known/webfinger; }
location = /.well-known/nodeinfo  { return 301 /index.php/.well-known/nodeinfo; }

如图:

image-20250106192249064

image-20250106192322461

修改db.env增加密码

使用vim编辑器,将该文件中MYSQL_PASSWORD字段进行赋值。我喜欢使用redhat,但是要注意和主compose.yaml里配置要一样。

修改compose.yaml

直接上干货:

services:
  db:
    image: mariadb:10.11
    container_name: nextcloud-fpm-db
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW --max-binlog-size=200M --expire-logs-days=2 # 优化mysql配置
    restart: unless-stopped
    volumes:
      - ./stack/data/db:/var/lib/mysql:Z
    environment:
      - MYSQL_ROOT_PASSWORD=redhat
      - MARIADB_AUTO_UPGRADE=1
      - MARIADB_DISABLE_UPGRADE_BACKUP=1
    env_file:
      - db.env

  redis:
    image: redis:alpine
    container_name: nextcloud-fpm-cache
    restart: unless-stopped
    volumes:
     - ./stack/data/redis:/data

  app:
    image: nextcloud:fpm-alpine
    container_name: nextcloud-fpm-app
    restart: unless-stopped
    hostname: nasnext
    volumes:
      - ./stack/data/app:/var/www/html:z
      - ./stack/config/www.conf:/usr/local/etc/php-fpm.d/www.conf
      # NOTE: The `volumes` config of the `cron` and `app` containers must match
    environment:
      - MYSQL_HOST=db
      - REDIS_HOST=redis
      - TZ=Asia/Shanghai
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - db.env
    depends_on:
      - db
      - redis

  web:
    build: ./web
    container_name: nextcloud-fpm-web
    restart: unless-stopped
    hostname: nasnext
    environment:
      - TZ=Asia/Shanghai
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 8080:80
    volumes:
      - ./stack/data/app:/var/www/html
      # NOTE: The `volumes` included here should match those of the `app` container (unless you know what you're doing)
    depends_on:
      - app

  cron:
    image: nextcloud:fpm-alpine
    container_name: nextcloud-fpm-cron
    restart: unless-stopped
    hostname: nasnext
    environment:
      - TZ=Asia/Shanghai
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    volumes:
      - ./stack/data/app:/var/www/html
      # NOTE: The `volumes` config of the `cron` and `app` containers must match
    entrypoint: /cron.sh
    depends_on:
      - db
      - redis

这里看一下对比官网的改动:

image-20250107084508765

这里需要注意app镜像中逻辑卷里面有自定义配置,./stack/config/www.conf该文件是PHP的配置文件,我的原始文件是从官方原版docker镜像里面拷贝出来然后做的修改,主要修改内容为PHP的线程数量:

pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18

这里可以下载我的文件,因为文件很长就不直接粘贴内容了,需要的直接下载即可。

最终所有文件如下。

.
├── compose.yaml
├── db.env
├── stack
│   ├── config
│   │   └── www.conf
│   └── data
└── web
    ├── Dockerfile
    └── nginx.conf

5 directories, 4 files

启动服务

直接docker compose up -d开始启动服务,启动服务之后不要着急登录后台服务,首先配置NPM和访问域名。

配置访问域名

在域名管理平台(根据自己的运营商)增加自己的DNS解析。

在进行测试时我直接使用hosts进行本地解析,这里比较坑,因为在错误检查时nextcloud会请求DNS服务器的ip,如果是hosts进行指向配置的,在安全检查时会有很多报错所以一定要使用DNS服务器进行解析。我这里域名使用cloud.zhangshuocauc.cn

NPM配置代理

这里比较简单,需要注意在advanced部分增加重写规则,也是为了解决检查错误提示。

location /.well-known/carddav {
    return 301 $scheme://$host/remote.php/dav;
}
 
location /.well-known/caldav {
    return 301 $scheme://$host/remote.php/dav;
}
 
location /.well-known/webfinger {
    return 301 $scheme://$host/index.php/.well-known/webfinger;
}
 
location /.well-known/nodeinfo {
    return 301 $scheme://$host/index.php/.well-known/nodeinfo;
}

如图所示:

image-20250107180009231

image-20250107175944580

image-20250107175808554

注意这里证书配置择自己的泛域名证书。

去除用户目录默认文件

应用会在用户创建第一次登录时初始化用户目录。并在目录中准备使用手册、示例文件,对于一场严肃的学术会议而言,这些内容最好去掉,可以省掉一些不必要的麻烦。

默认安装完毕后的示例文件

修改软件配置文件,配置文件所在目录为stack/data/app/config,配置文件为config.php,修改该文件增加'skeletondirectory' => '',配置,如图所示:

image-20250107145647774

配置服务

网页打开域名,进行安装即可。如果按上面配置正常应该可以看到如图安装界面:

image-20250107145751601

输入管理账号和密码点击安装即可完成。

处理告警

点击右上角管理设置自动进入告警检测,如果按我上面配置应该会出现下面这些告警,docker安装应该不会有其它问题:

image-20250107180415682

解决http不安全提示

修改应用配置文件,增加如下两行配置:

'overwritehost' => 'cloud.zhangshuocauc.cn',
'overwriteprotocol' => 'https',

服务器没有配置维护时段开始时间

增加下面两行配置:

'maintenance' => false,
'maintenance_window_start' => 1,

索引问题

解决第三第四告警执行提示命令即可解决:

docker exec -u 82 nextcloud-fpm-app /var/www/html/occ maintenance:repair --include-expensive

docker exec -u 82 nextcloud-fpm-app /var/www/html/occ db:add-missing-indices

安装过程中未设置默认的国际区号

'default_phone_region' => 'CN',

您尚未配置电子邮件服务器或尚未验证配置

这个配置好自己的邮箱即可。

优化app应用下载慢问题

使用加速节点对app下载较慢做优化配置,配置文件中增加如下配置:

'appstoreenabled' => true,
'appstoreurl' => 'https://www.orcy.net/ncapps/v2/',

处理完所有告警如图所示:

image-20250107181832964

方便对比,这里给出config.php的完整配置

<?php
$CONFIG = array (
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'apps_paths' => 
  array (
    0 => 
    array (
      'path' => '/var/www/html/apps',
      'url' => '/apps',
      'writable' => false,
    ),
    1 => 
    array (
      'path' => '/var/www/html/custom_apps',
      'url' => '/custom_apps',
      'writable' => true,
    ),
  ),
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' => 
  array (
    'host' => 'redis',
    'password' => '',
    'port' => 6379,
  ),
  'upgrade.disable-web' => true,
  'instanceid' => '**********',
  'skeletondirectory' => '',
  'passwordsalt' => '**********wIimmAcN+*********',
  'secret' => '***********************',
  'trusted_domains' => 
  array (
    0 => 'cloud.zhangshuocauc.cn',
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'mysql',
  'version' => '30.0.2.2',
  'overwritehost' => 'cloud.zhangshuocauc.cn',
  'overwriteprotocol' => 'https',
  'overwrite.cli.url' => 'http://cloud.zhangshuocauc.cn',
  'mail_smtpmode' => 'smtp',
  'mail_smtpsecure' => 'ssl',
  'mail_sendmailmode' => 'smtp',
  'mail_from_address' => '*********',
  'mail_domain' => '*******',
  'mail_smtphost' => '*********',
  'mail_smtpport' => '***',
  'mail_smtpauth' => 1,
  'mail_smtpname' => '************',
  'mail_smtppassword' => '***************',
  'appstoreenabled' => true,
  'appstoreurl' => 'https://www.orcy.net/ncapps/v2/',
  'default_phone_region' => 'CN',
  'dbname' => 'nextcloud',
  'dbhost' => 'db',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud',
  'dbpassword' => '*********',
  'installed' => true,
  'maintenance' => false,
  'maintenance_window_start' => 1,
);

修改最大上传512M限制

stack/data/app目录下,也就是app的主目录下有两个隐藏文件,一个是.htaccess一个是.user.ini文件。下面对两个文件进行修改。

.htaccess文件修改

<IfModule mod_php.c>字段下增加(大约61行后面):

php_value upload_max_filesize 16G
php_value post_max_size 16G
php_value max_input_time 3600
php_value max_execution_time 3600
php_value request_terminate_timeout 17200

.user.ini文件修改

在文本后面追加如下配置:

upload_max_filesize=16G
post_max_size=16G
max_input_time=3600
max_execution_time=3600
request_terminate_timeout=17200

非443端口下的配置

家庭网络有公网ip的情况下正常不会开放80,443,8080端口,所以对于HTTPS端口需要使用自定义端口,但是对于百度或者Google爬虫是不会获取非443非80端口的网页内容的,所以如果需要被搜索引擎收录还是需要标准端口的。

修改NPM配置中重写规则增加自定义端口地址

我通常喜欢9443作为HTTPS端口,9080作为HTTP端口。

location /.well-known/carddav {
    return 301 $scheme://$host:9443/remote.php/dav;
}
 
location /.well-known/caldav {
    return 301 $scheme://$host:9443/remote.php/dav;
}
 
location /.well-known/webfinger {
    return 301 $scheme://$host:9443/index.php/.well-known/webfinger;
}
 
location /.well-known/nodeinfo {
    return 301 $scheme://$host:9443/index.php/.well-known/nodeinfo;
}

配置文件中URL增加端口

上面完整应用配置文件中,所有域名后面都带上端口号即可。

array (
    0 => 'cloud.zhangshuocauc.cn:9443',
  ),
'overwritehost' => 'cloud.zhangshuocauc.cn:9443',
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'http://cloud.zhangshuocauc.cn:9443',

NPM强制https配置

这个在之前文章中


有说明,就是跳转时指定自定义端口号。

版本升级

使用Docker部署之后的升级方式和裸机部署的升级方式是有区别的,在裸机部署LAMP的环境下,基本点击在线升级即可,升级后点开自检看是否有报错。因为版本升级之后软件会有一些改动或者优化存在和原来版本不兼容的情况,这时候可能需要查阅官网,一般会有解决办法,通常是运行occ命令或者修改配置文件。

获取最新源码

需要重复上面第三节的内容,需要下载最新源码,对比是否有改动,通常情况下是不会有变化的。

停止服务

命令:docker compose down

拉取最新镜像

compose.yaml文件中,镜像使用的标签都是latest,表示最新,所以直接使用docker compose pull拉取最新镜像,下载过程需要等待。

重新启动服务

命令:docker compose up -d

清理虚悬镜像

可以使用手动方式删除,命令:docker image rm nextcloud-*或者使用自动方式,但是会有一些风险,命令:docker image prune -a或者命令:docker system prune -a

重新修改最大上传512M限制

上一节中有描述如何修改最大上传,升级之后.htaccess.user.ini会被重置,需要再次进行编辑修改。或者可以通过docker文件映射的方式进行固化,只是不能保证新版本是否会对两个文件进行更新,至于如何权衡根据自己情况选择即可。

总结

上述描述了个人网盘的需求和为什么选择nextcloud。详细说明了使用Docker Compose安装方式,并使用NPM进行HTTPS的配置和代理。安装后的告警解决和最后的如何升级。


--EOF

最后修改:2025 年 01 月 11 日
如果觉得我的文章对你有用,请随意赞赏