Nextcloud32迁移及升级排障

一、跨版本升级注意事项

跨版本升级前应首先检查PHP版本支持情况,避免无法直接运行内置更新器升级,必须进行手动升级。

如本次迁移到的目标系统环境ubuntu-server-26.04提供的PHP版本为最低8.5,导致Nextcloud32及以下版本无法运行内置更新器,最终手动升级。

手动升级前应先进入维护模式,关闭web服务器和定期刷新配置。

所有执行文件保留config.php即可,第三方应用重新安装较易,数据目录一般应与执行文件分离存储避免疏漏。

# 修改文件权限
chown -R www-data:www-data nextcloud
find nextcloud/ -type d -exec chmod 750 {} \;
find nextcloud/ -type f -exec chmod 640 {} \;

一些有用的occ命令

# 重新扫描文件
sudo -u www-data php console.php files:scan --all

# 功能修复
sudo -u www-data php occ maintenance:repair

# 修复索引
sudo -u www-data php occ db:add-missing-indices

二、安装流程

回到安装流程,首先安装前置软件。
使用Apache2作为web服务器,PHP作为执行语言,Redis和APCu作为缓存。

# 前置软件
sudo apt install apache2 mysql-server redis php php-mysql php-redis php-apcu php-common php-curl php-gd php-mbstring php-xml php-zip 
# 推荐
sudo apt install php-imagick php-bcmath php-gmp php-bz2
# 补充解决报错,修复非ASCII字符的排序问题和svg图片解析报错。
apt install php-intl  libmagickcore-dev

启用必须的Apache2模块

sudo a2enmod rewrite headers env dir mime 

修改PHP配置适应Nextcloud运行需求

# 根据实际情况修改版本号
/etc/php/8.5/apache2/php.ini 

# 上传大文件
upload_max_filesize = 16G
post_max_size = 16G

# 防止超时
max_execution_time = 3600
max_input_time = 3600

# 扩大可用内存
memory_limit = 4096M

# 修改opcache模块配置提高性能,注意需要去除注释符号“;”
opcache.enable=1
opcache.memory_consumption=1024
opcache.interned_strings_buffer=128
opcache.revalidate_freq=60
opcache.max_accelerated_files = 100000

修改config.php启用缓存,除了本地内存缓存外,其他都在Redis中缓存。

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
     'host' => 'localhost',
     'port' => 6379,
],

创建MySQL数据库

CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
GRANT ALL PRIVILEGES on nextcloud.* to 'username'@'localhost';

创建Cron服务定期执行,配置应放在/etc/systemd/system/

创建第一个NextCloudCron.Service,用以执行刷新。

[Unit]
Description=Nextcloud cron.php job

[Service]
User=www-data
ExecCondition=php -f /var/www/nextcloud/occ status -e
ExecStart=/usr/bin/php -f /var/www/nextcloud/cron.php
KillMode=process

创建第二个nextcloudcron.timer,用以定期刷新。

[Unit]
Description=Run Nextcloud cron.php every 5 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
Unit=nextcloudcron.service

[Install]
WantedBy=timers.target

简单的Apache2服务器配置

<VirtualHost *:80>
  DocumentRoot /var/www/nextcloud/
  ServerName  your.server.com

  <Directory /var/www/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    <IfModule mod_dav.c>
      Dav off
    </IfModule>
  </Directory>
</VirtualHost>

SSL通过NGINX代理实现,部署在其他服务器中。

完成后检查概述页面报错。

在本次迁移中还发现了一个系统问题,详见链接↗

具体表现执行cron时在日志中产生报错:

Warning: preg_match(): Allocation of JIT memory failed, PCRE JIT will be disabled. This is likely caused by security restrictions. Either grant PHP permission to allocate executable memory, or set pcre.jit=0 in [MY PHP FILENAME]

会导致cron无法正常执行,产生概述页面报错。

原因是PHP 8.5和Apache mod-php(非fpm)互操作导致的bug,在php-fpm中不存在。JIT 工作方式是先写入内存,然后编译正则表达式,再让内存可执行。这违反了Systemd中添加的一项更严格的保护措施MemoryDenyWriteExecute

临时的解决方法是在apache2.service中临时添加一条MemoryDenyWriteExecute=no

# 合规的修改方式
sudo systemctl edit apache2

# 添加下列信息
[Service]
MemoryDenyWriteExecute=no

# 重启Apache2生效
sudo systemctl daemon-load
sudo systemctl restart apache2