跳至内容

Jixun's Blog 填坑还是开坑,这是个好问题。

在 RHEL 9 部署 NextCloud

这是一篇安装过程的记录,将记录我在手动安装 NextCloud 时所遇到的一些问题和解决方案。

官方有提供 AIO 的 Docker 部署方案,或许部署起来更方便;但是我更倾向于手动设定并管理。

前言 #

读者需要有一定的 Linux 管理经验,如在终端对文件进行简单编辑。对于新手来说,推荐使用简单上手的 nano 编辑器。

为什么不使用“一键脚本”呢?因为我有一些比较个人的需求,使用一键脚本反而会需要花费更多时间来抵消部分更改。

初探 NextCloud 项目 #

NextCloud 是一个基于 PHP (+数据库) 方案开发的一个数据存储与同步项目。

这个方案的技术栈决定我需要在部署前做出一些选择:

  • 选择 Apache、Nginx 或支持处理 PHP 请求的服务器程序
  • 选择 MySQL/MariaDB/PostgreSQL
  • PHP 的版本

这些问题其实在官方的系统要求页内已经有所描述,我的选择如下:

  • 兼容 RHEL 9 的发行版 - Alma Linux 9.3
  • Apache - 因为 NextCloud 的文档在 Apache 方面的内容最多
  • PHP 8.3 (8.3.2) - 支持的 PHP 版本中最新,看网友的性能测试1也挺快的。
  • MariaDB - 因为已经在另一个虚拟机中配置好了,所以本文会跳过安装部分。

※ 系统版本与 PHP 版本在本文撰写时为最新可用版本。

网络架构一览 #

网络基本架构,“内网”没有做应用隔离。

其中,本文的环境信息:

  • 反代网关 (Nginx) / IP 10.0.0.1/192.168.0.100 (https://jixun.cloud)
  • MariaDB / IP 10.0.0.100
  • NextCloud / IP 10.0.0.101

安装 + 配置 PHP 8.3 (Remi RPM) #

RHEL 9 提供 PHP 8.0 和 8.1 相关的包。8.0 已经结束支持,而 8.3 的性能比之前的版本更好。参考网上的因此选择 Remi 仓库的

直接参考 Remi’s RPM 配置向导,填入系统信息和需要的版本即可得到说明:

  • 操作系统(Operating system): RHEL 9.3
  • PHP 版本(Wanted PHP version): 8.3.2 (active support until November 2025)
  • 安装类型(Type of installation): Default / Single version (simplest way)(没有多版本共存)
  • 系统架构(Architecture): x86_64

执行下述指令安装 PHP:

# 启用 EPEL 仓库以及 RHEL 仓库
dnf install epel-release https://rpms.remirepo.net/enterprise/remi-release-9.rpm

# 重新建立包列表缓存
dnf makecache

因为我不需要多版本共存支持,因此直接默认使用 8.3 版本:

dnf module switch-to php:remi-8.3

现在开始安装:

dnf install php

php -version
# PHP 8.3.2 (cli) ...

※ 如果询问是否导入 EPEL/Remi 仓库的 GPG Key,键入 y 并回车即可。

随后调用 PHP 来看缺了哪些包2

# 注意: 你可以根据自己的需要来注释或取消注释部分扩展名
php -r '
  $installed_exts = get_loaded_extensions();
  $required_exts = [
    // 必须
    "ctype", "curl", "dom", "fileinfo", "filter", "GD", "hash",
    "JSON", "libxml", "mbstring", "openssl", "posix", "session",
    "SimpleXML", "XMLReader", "XMLWriter", "zip", "zlib",

    // 数据库:
    "pdo", "pdo_mysql",

    // 推荐但非必须
    "bz2", "intl", "sodium",

    // 某些应用所需的扩展
    // "ldap",
    // "smbclient",
    // "ftp",
    // "imap", // external user authentication
    // "bcmath", // passwordless login
    // "gmp", // passwordless login / sftp
    "exif", // 图片元信息

    // 可选,缓存相关
    "apcu",
    // "memcached",
    // "redis",

    // 可选预览生成。注意 imagick 会拉取很多 x11 / 桌面环境 相关的包…
    "imagick",

    // 可选, 命令行相关
    "pcntl",
    "phar"
  ];
  $installed_exts = array_map("strtolower", $installed_exts);
  $required_exts = array_map("strtolower", $required_exts);
  print_r(array_diff($required_exts, $installed_exts));
'

可以看到缺少的包:

Array
(
    [5] => gd
    [11] => posix
    [16] => zip
    [19] => pdo_mysql
    [21] => intl
    [24] => apcu
    [25] => imagick
)

直接安装即可:

dnf install -y php-{gd,posix,zip,intl,apcu,imagick} php-mysqlnd

※ 要使用 PHP 连接 MySQL/MariaDB,安装 php-mysqlnd;连接 PostgreSQL 的包是 php-pgsql。PHP 内置 SQLite 支持。

再次运行之前的 PHP 扩展检查代码,可以发现没有报告缺少的包了。

调整配置 #

参考官方的 PHP 配置,需要启用一些配置。

写出下述内容到 /etc/php.d/99-jixun-nextcloud.ini

; 缓存相关
apc.enabled = 1
apc.enable_cli = 1

; Opcache
opcache.enable = 1
opcache.save_comments = 1
; 启用 Opcache JIT (php 8.0+)
opcache.jit = 1255
opcache.jit_buffer_size = 128M

; 支持大文件上传
max_input_time = 3600
max_execution_time = 3600
upload_max_filesize = 1G
post_max_size = 1G
memory_limit = 1536M

; 临时文件路径,最好和数据储存在同一个设备中或使用 tmpfs 挂载的路径
upload_tmp_dir = /storage/nextcloud/tmp

; 时区
date.timezone = Europe/London

集成 Apache 2 #

安装需要的包:

dnf install httpd

# 启动服务并开机自动启动
systemctl enable --now httpd

# (默认的防火墙) 放行 80 端口
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --reload

# 允许 Apache (即 PHP) 访问数据库
setsebool -P httpd_can_network_connect_db 1

# 允许 Apache (即 PHP) 访问外部数据 (如从第三方网站下载数据)
setsebool -P httpd_can_network_connect 1

此时访问 :80 端口应该能看到默认的欢迎页面。

回到 SSH,添加配置文件 /etc/httpd/conf.d/nextcloud.conf

DocumentRoot /storage/nextcloud/www/

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

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

清空默认的 /etc/httpd/conf.d/welcome.conf

echo '# disable default welcome' > /etc/httpd/conf.d/welcome.conf

在 SELinux 允许 Apache 进程访问我们的目录,并重置所有者:

chcon -R -t httpd_sys_rw_content_t /storage/nextcloud/{www,tmp}/
chown -R apache:apache /storage/nextcloud/{www,tmp}/

此时可以尝试放入测试文件:

# 写出查看 PHP 信息的脚本
cat >/storage/nextcloud/www/index.php <<'EOF'
<?php phpinfo();
EOF

# 重启 Apache 服务
systemctl restart httpd

打开浏览器查看是否能够正常渲染。若是一切正常,则会报告当前 PHP 环境信息:

测试 Apache + PHP 集成是否正常。

配置 MariaDB #

本文将跳过安装部分。简单初始化一个单独的数据库给 NextCloud 使用:

-- 建立数据库
CREATE DATABASE `nextcloud` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 建立用户,并只允许该 IP 访问。其中 `jixun_password` 是访问密码。
CREATE USER 'nextcloud'@'10.0.0.101' IDENTIFIED BY 'jixun_password';
GRANT ALL PRIVILEGES ON `nextcloud`.* TO 'nextcloud'@'10.0.0.101' WITH GRANT OPTION;

配置网关反代 #

在安装 NextCloud 之前,需要稍微配置下网关来反代。

upstream nextcloud {
  server 10.0.0.101:80;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_name jixun.cloud;

  include "/etc/certs.d/jixun.cloud.conf"

  # 根据自己需要调整最大上传大小
  client_max_body_size 1G;

  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_buffering off;
    proxy_pass http://nextcloud;
  }

  # 修正“服务发现”支持
  location /.well-known/carddav {
    return 301 $scheme://$host/remote.php/dav;
  }
  location /.well-known/caldav {
      return 301 $scheme://$host/remote.php/dav;
  }
}

配置完后执行 nginx -t && nginx -s reload 重启服务即可。

安装 NextCloud #

首先安装下载源码包需要的依赖:

dnf install -y sudo tar bzip2 curl

然后下载最新的源码包并解压到我们的根目录:

curl -sfL https://download.nextcloud.com/server/releases/latest.tar.bz2 \
  | sudo -u apache tar -jxv --strip-components=1 -C /storage/nextcloud/www/

等上述操作完成后可以通过反代的 HTTPS 来访问首页,根据安装向导的提示完成安装。

调整配置 #

配置文件储存于 /storage/nextcloud/www/config/config.php 中。

调整配置文件的项目需要使用编辑器(如 nanovim)来更改,更改后通常不需要重启。

请注意不要破坏 PHP 文件的语法。这个配置文件看上去像这样:

<?php
$CONFIG = array (
  'instanceid' => '123456789',
  // ... 省略 ...

  // 添加你的配置项目到此处。注意保持文件结尾最后一行的内容。
  '我的设定 1' => '987654321',
  '我的设定 2' => 'https://jixun.cloud/',

);

更改前建议建立备份:

# 建立备份
cp /storage/nextcloud/www/config/config.php{,.bak}

# 还原备份
cp /storage/nextcloud/www/config/config.php{.bak,}

设定中文 #

在配置文件添加下述内容:

  'default_language' => 'zh_CN',
  'default_locale' => 'zh_Hans',

配置文件锁定优化 #

访问后台管理界面,提示警告信息:

The database is used for transactional file locking. To enhance performance, please configure memcache, if available.

当前正在使用数据库处理事务性文件锁定。若有内存缓存可用,请进行配置以提升性能。

根据文档提示安装 Redis 相关依赖,启用 Redis 并重启 PHP 服务:

dnf install -y redis php-pecl-redis6
systemctl enable --now redis
systemctl restart php-fpm

最后,在配置文件中使用 Redis 缓存来支持文件锁定:

  'filelocking.enabled' => true,
  'memcache.locking' => '\OC\Memcache\Redis',
  'redis' => array(
     'host' => '127.0.0.1',
     'port' => 6379,
     'timeout' => 0.0,
     'password' => '', // 可选,Redis 访问密码。
  ),

配置 HSTS 响应头 #

※ 该内容仅适用于使用 HTTPS 的情况。如果你不确定你是否需要,建议跳过该项。

在 Apache 配置 (/etc/httpd/conf.d/nextcloud.conf) 中加入下述高亮行:

    ...
    Options FollowSymLinks MultiViews
    Header always set Strict-Transport-Security "max-age=15552000"

    <IfModule mod_dav.c>
    ...

然后重启 Apache 服务即可:

systemctl restart httpd

使用 Cron 自动执行后台任务 #

在浏览器访问 /index.php/settings/admin,选择 Cron(推荐)

回到 SSH 终端,执行下述内容完成安装:

cat >>/var/spool/cron/apache <<'EOF'
*/5 * * * * /usr/bin/php -f /storage/nextcloud/www/cron.php
EOF

# 查看 Cron 定时任务是否被正确识别
crontab -l -u apache

配置电子邮件服务器 #

※ 此处使用的是第三方邮件服务提供商,而非自托管。

在浏览器访问 /index.php/settings/admin#mail_general_settings_form

根据电子邮件服务提供商的信息依次填写即可。

需要注意的是:即便使用的是标准的默认端口,也需要填写,否则会发信失败。

对应的配置文件项目,参考用的官方文档

  'mail_smtpmode' => 'smtp',
  
  // 服务器信息
  'mail_smtphost' => 'SMTP 域名',
  'mail_smtpport' => '465', // smtp 端口
  'mail_smtpsecure' => 'ssl', // "" 留空 (无加密或自动升级 STARTTLS) 或 "ssl" 使用 SSL/TLS

  // SMTP 认证相关
  'mail_smtpauth' => true, // 使用启用认证
  'mail_smtpname' => '认证用户名',
  'mail_smtppassword' => '认证密码',

  // 发件人
  'mail_from_address' => '发件人邮箱前缀',
  'mail_domain' => '发件人邮箱域名',

配置 Pretty URL #

未配置时,访问地址将包含 /index.php/,如 https://jixun.cloud/index.php/jixun/

首先,编辑配置文件:

  1. 确保 overwrite.cli.url 正确(我的安装情况需要手动将协议改为 https,并添加 overwriteprotocol
  2. 添加 htaccess.RewriteBase

最终添加的项目如下:

  'overwrite.cli.url' => 'https://jixun.cloud/',
  'overwriteprotocol' => 'https',
  'htaccess.RewriteBase' => '/',

然后更新 Apache 的 .htaccess 重写规则:

sudo -u www-data apache /storage/nextcloud/www/occ maintenance:update:htaccess

回到浏览器,重新输入首页地址。可以发现现在网址不会自动添加 /index.php/ 部分。

结语 #

安装完成

安装起来好麻烦。官方文档虽然有将 RHEL 9 作为推荐的操作系统,但是文档内指令大多时只适用于 Debian 及衍生版。

安装文档也没有提供“复制粘贴就能安装所有运行时需要的 PHP 扩展”的指令,得一个一个排查。

知识共享许可协议 本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

评论区