在Nextcloud中配置上传4GB或更大容量的文件

Nextcloud 是一个自由、开源的文件同步和共享软件套件。它允许你将文件储存在个人或专有服务器上,并在多个设备之间同步和共享这些文件。Nextcloud 提供了类似于Dropbox的功能,但更加安全和可自定义。它还支持许多插件和扩展,以满足个人和组织的不同需求。Nextcloud 是一个功能强大的解决方案,有助于保护您的文件和数据,并提高企业的协作效率。
很久以前我创建的 ownCloud,最近换成了 Nextcloud。
虽然换成了新的,但是似乎无论上传多少次,大于4GB的大容量文件都无法成功上传,真是没办法。
于是我研究了一下问题,重新调整了设置,终于能够成功上传超过10GB的文件了,这就是我的经历。
我将列举发生的错误以及相应的解决方法。
前提 (Qian ti)
-
- サーバースペック
AWS Lightsail
2 GB RAM
1 vCPU
60 GB SSD
Nextcloudバージョン
23.0.2
公式の docker-compose.yml で環境を作成
https://github.com/nextcloud/docker/tree/master/.examples/docker-compose/with-nginx-proxy/mariadb/fpm
nginx (proxy) + nginx (web) + Nextcloud (php-fpm) + mariaDB + redis の全部入り
S3 をプライマリストレージとして使用
发生的错误和解决方法
以下的设置方法是基于使用docker-compose创建的环境。请在其他环境中自行调整。
将PHP文件大小的上限增加
由于PHP默认配置不允许上传大于512MB的文件,因此需要进行配置更改。
在Docker配置中,存在名为PHP_MEMORY_LIMIT和PHP_UPLOAD_LIMIT的设置,需要添加它们。
您可以根据需要自行设置这些值。
diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml
index 33b3d92..d89864d 100644
--- a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml
+++ b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml
@@ -24,6 +24,16 @@ services:
environment:
- MYSQL_HOST=db
- REDIS_HOST=redis
- OVERWRITEPROTOCOL=https
- OBJECTSTORE_S3_HOST=s3.ap-northeast-1.amazonaws.com
- OBJECTSTORE_S3_BUCKET=hogehoge-drive
- OBJECTSTORE_S3_KEY=AAAAAAAAAAAAAAAA
- OBJECTSTORE_S3_SECRET=aaaaaaaaaaaaaaaaaaaaaaaaaa
- OBJECTSTORE_S3_PORT=443
- OBJECTSTORE_S3_SSL=true
- OBJECTSTORE_S3_REGION=ap-northeast-1
+ - PHP_MEMORY_LIMIT=1G
+ - PHP_UPLOAD_LIMIT=5G
env_file:
- db.env
depends_on:
尽管设置 PHP_MEMORY_LIMIT 不影响运行,但是由于我环境中有足够的内存,因此我进行了设置。
增加Nginx的文件大小限制
代理和网络的Nginx配置都需要更改,才能上传大容量文件。
默认设置限制为512MB,因此需要更改相应的配置。
更改代理设置
diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
index 7e3906e..eb05553 100644
--- a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
+++ b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
@@ -1,2 +1,6 @@
-client_max_body_size 10G;
+client_max_body_size 15G;
proxy_request_buffering off;
网络设置更改
diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
index 8fbc162..6af9b77 100644
--- a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
+++ b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
@@ -42,7 +42,7 @@ http {
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# set max upload size
- client_max_body_size 512M;
+ client_max_body_size 15G;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
設置各種超時時間
从这里开始是正题。根据之前的设置进行了同步,发现能够上传约3GB左右的文件,但是当文件大小大约达到4GB或以上时,会出现以下的错误。
组装块时出现错误,状态代码504。
组装块时的错误,状态码504。
据说,Nextcloud在上传大容量文件时会将文件分割发送,但似乎在PHP端合并分割文件花费了较长时间,在此期间nginx会因为超时而中断。此外,据说如果PHP执行本身花费了较长时间,也会导致超时并取消PHP的执行。
(参考)
以下是原文链接(需翻墙):
1. https://help.nextcloud.com/t/error-when-assembling-chunks-status-code-504/56751/6
2. https://github.com/nextcloud/server/issues/17992
3. https://github.com/linuxserver/docker-nextcloud/issues/211
为此,需要提高nginx端的超时值上限和PHP的执行时间上限。
需要分别设置proxy和web的nginx端超时值。
超时时间可以根据个人喜好进行设置。这里设定为30分钟。
更改代理设置
diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
index 7e3906e..eb05553 100644
--- a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
+++ b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
@@ -1,2 +1,6 @@
client_max_body_size 15G;
proxy_request_buffering off;
+proxy_connect_timeout 1800;
+proxy_send_timeout 1800;
+proxy_read_timeout 1800;
+send_timeout 1800;
网页的设置更改
diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
index 8fbc162..6af9b77 100644
--- a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
+++ b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
@@ -144,6 +144,11 @@ http {
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
+
+ fastcgi_read_timeout 1800;
+ fastcgi_send_timeout 1800;
+ fastcgi_connect_timeout 1800;
更改 PHP 的执行时间
由于无法直接更改PHP的执行时间,因此需要进入docker容器并修改PHP的配置文件。
首先进入docker容器内部。
$ sudo docker exec -it fpm-app-1 sh
在容器中安装编辑器,并打开PHP配置文件。
$ apk add vim
$ vim /usr/local/etc/php/conf.d/nextcloud.ini
打开PHP的配置文件,添加以下行代码。
--- nextcloud.ini
+++ /usr/local/etc/php/conf.d/nextcloud.ini
@@ -1,3 +1,5 @@
memory_limit=${PHP_MEMORY_LIMIT}
upload_max_filesize=${PHP_UPLOAD_LIMIT}
post_max_size=${PHP_UPLOAD_LIMIT}
+max_execution_time=1800
+max_input_time=1800
调整向S3的多部分上传的并行度
改变了超时值并上传后,现在出现了这种错误。
An exception occurred while uploading parts to a multipart upload. The following parts had errors:
- Part 1: Error executing \"UploadPart\" on \"https://s3.eu-central-1.wasabisys.com/example.com/urn%3Aoid%3A6899?partNumber=1&uploadId=0p_vUl_cL8R-z7o7JQacOPTjP3Vhqy_sVxwGv8CRVa39uzWZqBC_IrD0wfP9d0sLVAX_uGkLalq-Fhguy7FgJcHspt9ZeeZ3yzqYEcUbmVhY1ONPX5X57BVpRajusER6\"; AWS HTTP error: Client error: `PUT https://s3.eu-central-1.wasabisys.com/example.com/urn%3Aoid%3A6899?partNumber=1&uploadId=0p_vUl_cL8R-z7o7JQacOPTjP3Vhqy_sVxwGv8CRVa39uzWZqBC_IrD0wfP9d0sLVAX_uGkLalq-Fhguy7FgJcHspt9ZeeZ3yzqYEcUbmVhY1ONPX5X57BVpRajusER6` resulted in a `400 Bad Request` response:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Error><Code>RequestTimeout</Code><Message>Your socket connection to the server w (truncated...)
RequestTimeout (client): Your socket connection to the server was not read from or written to within the timeout period, source: read tcp 130.117.252.13:443->78.46.193.122:35876: i/o timeout - <?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Error><Code>RequestTimeout</Code><Message>Your socket connection to the server was not read from or written to within the timeout period, source: read tcp 130.117.252.13:443->78.46.193.122:35876: i/o timeout</Message><RequestId>0800D03C011B289E</RequestId><HostId>4K4Kd98tbwzYAQ9Of04l+YWtRoC4ykRJcznDiTbqFljFzHuqkVVIFAGYqpOTqzaNvYqrHRXFJk6m</HostId></Error>
- Part 2: Error executing ...
好像在向S3进行多部分上传时发生了超时问题。
当查阅有关 PR 的信息时,我了解到在 Nextcloud 中使用的 AWS SDK for PHP 能够通过指定并行度来实现并行多部分上传。然而,如果服务器规格不足,会增加负载并导致上传到 S3 的操作超时。
(参考)在下面链接的GitHub页面中,你可以找到一个关于Nextcloud服务器的拉取请求(Pull Request)编号为24330的讨论和代码更改。
所以,似乎最好不要将并行度设置为默认值5,而应该进一步减少数量。
由于在v23.0.2的Nextcloud中无法更改并行度,所以必须直接修改源代码中的PHP。
再次进入 Docker 容器内。
$ sudo docker exec -it fpm-app-1 sh
当进入容器后,打开相应处理的源代码。
$ vim lib/private/Files/ObjectStore/S3ObjectTrait.php
在执行多部分上传处理时,添加以下并发设置。
--- ./S3ObjectTrait_original.php
+++ lib/private/Files/ObjectStore/S3ObjectTrait.php
@@ -110,11 +110,10 @@
protected function writeMultiPart(string $urn, StreamInterface $stream, string $mimetype = null): void {
$uploader = new MultipartUploader($this->getConnection(), $stream, [
'bucket' => $this->bucket,
'key' => $urn,
'part_size' => $this->uploadPartSize,
+ 'concurrency' => 1,
'params' => [
'ContentType' => $mimetype
],
]);
我自己的情况下,如果选择 1,就完全不会出现错误,并且能够成功同步超过10GB的文件。真是太高兴了。

最后
最初决定转向Nextcloud时,我很高兴地创建了环境,因为官方有docker-compose.yml可用,真是太好了!。但后来发现无法同步大文件,于是我花了几天时间不断尝试和纠结。
由于大文件大小,每次尝试都需要花费很长时间,一度完全失去了兴趣,但好在最终我设法成功同步了超过10GB的文件,真是太好了。