NextCloud安装部署(CentOS8)

本安装教程中,将在 CentOS 8 中部署 PHP 8.1、PostgreSQL、Redis 作为内存缓存和在 Nginx 上运行的 Nextcloud

基础环境准备

使用普通用户

新建一个用户

# 新建用户并设置密码
adduser username
passwd username

# 将用户添加到wheel用户组,赋予管理权限
usermod -aG whell username

限制root直接通过SSH登录

vim /etc/ssh/sshd_config

找到 PermitRootLogin 修改如下

PermitRootLogin no

启用SELinux

修改配置文件

sudo vim /etc/selinux/config

修改内容如下:

SELINUX=enforcing

上面到配置为永久配置,需要重启服务器,为节省时间直接使用以下命令开始配置。

sudo setenforce enforcing

检查 SELinux 状态

sestatus

输出类似内容:

SELinux status:               enabled
SELinuxfs mount:              /sys/fs/selinux
SELinux root directory:       /etc/selinux
Loaded policy name:           targeted
Current mode:                 enforcing
Mode from config file:        permissive
Policy MLS status:            enabled
Policy deny_unknown status:   allowed
Memory protection checking:   actual (secure)
Max kernel policy version:    33

更新软件

sudo dnf -y update

安装依赖

安装一些在安装过程中需要的依赖项

dnf install -y epel-release yum-utils unzip curl wget vim \
bash-completion policycoreutils-python-utils mlocate bzip2

安装配置PostgreSQL

安装PostgreSQL

安装PostgreSQL

启用 PostgreSQL 官方存储库

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

从 CentOS 默认库中禁用 PostgreSQL

sudo dnf module -qy disable postgresql

安装 PostgreSQL 12

sudo dnf install -y postgresql12 postgresql12-server

初始化PostgreSQL

初始化数据库,然后配置开机启动并直接启动

sudo /usr/pgsql-12/bin/postgresql-12-setup initdb
sudo systemctl enable postgresql-12 --now

设置 postgres 用户的密码

sudo passwd postgres

登录到 postgres 用户

su -l postgres

进入 Postgres 数据库

psql

配置数据库本地连接

为 IPv4 和 IPv6 本地主机配置身份验证方法

# METHOD 可以是 "trust", "reject", "md5", "password", "scram-sha-256", "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" 或 "cert"
# 注意 "password" 是以明文方式发送; "md5" 或 "scram-sha-256" 是将密码加密后发送
sudo vim /var/lib/pgsql/12/data/pg_hba.conf

找到 host IPv4 和 IPv6 线路,配置本地连接的验证方法

host all all 127.0.0.1/32 md5
host all all ::1/128 md5

重启服务启用配置

sudo systemctl restart postgresql-12

配置PostgreSQL

登录到 postgres 用户

su -l postgres

进入 Postgres 数据库

psql

创建一个数据库用户用于 NextCloud ,并设置密码

CREATE USER nextclouddbuser WITH PASSWORD 'nextclouddbuserpassword';

创建用于 NextCloud 的数据库

CREATE DATABASE nextclouddb;

授予 NextCloud 用户访问数据库的权限

GRANT ALL PRIVILEGES ON DATABASE nextclouddb TO nextclouddbuser;

使用 \q 退出数据库,然后 exit 退出 postgres 账户

安装Redis

安装

sudo dnf install -y redis

配置开机启动并直接启动

sudo systemctl enable redis --now

安装PHP8.1

启用 REMI 存储库

sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm

查找当前启用的 PHP 版本

dnf module list php

从 REMI 存储库启用模块 PHP8.1

dnf module enable php:remi-8.1

切换到其他版本

dnf module reset php
dnf module enable php:remi-8.0

安装 php 模块

dnf install -y php php-pear php-dom php-gd \
php-mbstring php-pgsql php-intl php-imap \
php-bcmath php-gmp php-json php-posix \
php-pecl-apcu php-pecl-apcu-devel php-pecl-zip \
php-pecl-redis5 php-pecl-imagick

必备模块

配置PHP

获取 PATH

printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

编辑 /etc/php-fpm.d/www.conf 文件进行配置

/etc/php-fpm.d/www.conf

找到以下内容取消注释,修改 PATH 内容,并将管理内存限制更改为 512 M

;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;env[TEMP] = /tmp
...
;php_admin_value[memory_limit] = 128M
...
;php_value[opcache.file_cache] = /var/lib/php/opcache

修改后内容如下

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
env[TEMP] = /tmp
...
php_admin_value[memory_limit] = 512M
...
php_value[opcache.file_cache] = /var/lib/php/opcache

创建以下目录来存储临时信息

sudo mkdir -p /var/lib/php/{session,opcache,wsdlcache}
sudo chown -R root:nginx /var/lib/php/{opcache,wsdlcache}
sudo chown -R nginx:nginx /var/lib/php/session

配置开机启动并直接启动

sudo systemctl enable php-fpm --now

安装Nginx

CentOS_8安装Nginx

首先添加 EPEL 存储库

sudo dnf install -y epel-release

安装Nginx

sudo dnf install -y nginx

验证安装

sudo nginx -v

配置开启启动并直接启动

sudo systemctl enable nginx --now

检查 Nginx 是否运行

curl -I 127.0.0.1

输出类似到内容

HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Sun, 02 Apr 2023 06:15:41 GMT
Content-Type: text/html
Content-Length: 3429
Last-Modified: Thu, 10 Jun 2021 09:09:03 GMT
Connection: keep-alive
ETag: "60c1d6af-d65"
Accept-Ranges: bytes

配置防火墙策略,允许Web访问

sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload

获取SSL证书

学习笔记/Linux/生成自签名SSL证书

部署NextCloud

可以从 NextCloud 官方下载页面 下载最新的版本

下载 Nextcloud

wget https://download.nextcloud.com/server/releases/nextcloud-26.0.0.tar.bz2

要验证软件包,还要下载 SHA256 哈希值

wget https://download.nextcloud.com/server/releases/nextcloud-26.0.0.tar.bz2.sha256

验证完整性

sha256sum -c nextcloud-26.0.0.tar.bz2.sha256 < nextcloud-26.0.0.tar.bz2

输出应如下例所示

nextcloud-26.0.0.tar.bz2: OK

解压

tar -xf nextcloud-26.0.0.tar.bz2

将文件夹移动到 Nginx 站点根目录下

sudo rm -rf /usr/share/nginx/html
sudo mv nextcloud /usr/share/nginx/html

新建一个目录用于存储数据

sudo mkdir /usr/share/nginx/data

确保 Nginx 可以读取和写入 NextCloud 文件夹

sudo chown -R nginx:nginx /usr/share/nginx

重启 Nginx

sudo systemctl restart nginx

配置 NextCloud 文件夹到 SELinx 上下文

sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/data(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/config(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/apps(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/.htaccess'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/.user.ini'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/nginx/html/3rdparty/aws/aws-sdk-php/src/data/logs(/.*)?'

sudo restorecon -R '/usr/share/nginx/html/'
sudo restorecon -R '/usr/share/nginx/data/'
sudo setsebool -P httpd_can_network_connect on

配置Nginx

将 /etc/nginx/nginx.conf 更改为具有以下内容

sudo vim /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }
    }
}

创建 NextCloud 网站配置文件 /etc/nginx/conf.d/nextcloud.conf ,内容如下

upstream php-handler {
    server unix:/run/php-fpm/www.sock;
}

# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}


server {
    listen 80;
    listen [::]:80;
    server_name cloud.local;

    # Prevent nginx HTTP Server Detection
    server_tokens off;

    # Enforce HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443      ssl http2;
    listen [::]:443 ssl http2;
    server_name cloud.local;

    # Path to the root of your installation
    root /usr/share/nginx/html/;

    # Use Mozilla's guidelines for SSL/TLS settings
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/
    ssl_certificate     /opt/ssl/cert.pem;
    ssl_certificate_key /opt/ssl/key.pem;

    # Prevent nginx HTTP Server Detection
    server_tokens off;

    # HSTS settings
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;

    # set max upload size and increase upload timeout:
    client_max_body_size 512M;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    # Pagespeed is not supported by Nextcloud, so if your server is built
    # with the `ngx_pagespeed` module, uncomment this line to disable it.
    #pagespeed off;

    # The settings allows you to optimize the HTTP2 bandwitdth.
    # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
    # for tunning hints
    client_body_buffer_size 512k;

    # HTTP response headers borrowed from Nextcloud `.htaccess`
    add_header Referrer-Policy                   "no-referrer"       always;
    add_header X-Content-Type-Options            "nosniff"           always;
    add_header X-Download-Options                "noopen"            always;
    add_header X-Frame-Options                   "SAMEORIGIN"        always;
    add_header X-Permitted-Cross-Domain-Policies "none"              always;
    add_header X-Robots-Tag                      "noindex, nofollow" always;
    add_header X-XSS-Protection                  "1; mode=block"     always;

    # Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

    # Add .mjs as a file extension for javascript
    # Either include it in the default mime.types list
    # or include you can include that list explicitly and add the file extension
    # only for Nextcloud like below:
    include mime.types;
    types {
        application/javascript js mjs;
    }

    # Specify how to handle directories -- specifying `/index.php$request_uri`
    # here as the fallback means that Nginx always exhibits the desired behaviour
    # when a client requests a path that corresponds to a directory that exists
    # on the server. In particular, if that directory contains an index.php file,
    # that file is correctly served; if it doesn't, then the request is passed to
    # the front-end controller. This consistent behaviour means that we don't need
    # to specify custom rules for certain paths (e.g. images and other assets,
    # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
    # `try_files $uri $uri/ /index.php$request_uri`
    # always provides the desired behaviour.
    index index.php index.html /index.php$request_uri;

    # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
    location = / {
        if ( $http_user_agent ~
{ #DavClnt}
 ) {
            return 302 /remote.php/webdav/$is_args$args;
        }
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Make a regex exception for `/.well-known` so that clients can still
    # access it despite the existence of the regex rule
    # `location ~ /(\.|autotest|...)` which would otherwise handle requests
    # for `/.well-known`.
    location ^~ /.well-known {
        # The rules in this block are an adaptation of the rules
        # in `.htaccess` that concern `/.well-known`.

        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;
    }

    # Rules borrowed from `.htaccess` to hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    # Ensure this block, which passes PHP files to the PHP process, is above the blocks
    # which handle static assets (as seen below). If this block is not declared first,
    # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
    # to the URI, resulting in a HTTP 500 error response.
    location ~ \.php(?:$|/) {
        # Required for legacy support
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;

        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;

        try_files $fastcgi_script_name =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;

        fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
        fastcgi_param front_controller_active true;     # Enable pretty urls
        fastcgi_pass php-handler;

        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463, $asset_immutable";
        access_log off;     # Optional: Don't log access to assets

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        expires 7d;         # Cache-Control policy borrowed from `.htaccess`
        access_log off;     # Optional: Don't log access to assets
    }

    # Rule borrowed from `.htaccess`
    location /remote {
        return 301 /remote.php$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }
}

/etc/nginx/conf.d/nextcloud.conf 的配置需要注意到是以下内容

# 配置站点根目录
root /usr/share/nginx/html/;

# 配置SSL证书
ssl_certificate     /opt/ssl/cert.pem;
ssl_certificate_key /opt/ssl/key.pem;

配置php

增加 PHP 内存限制

sudo vim /etc/php.ini

如下所示将 memory_limit 更改为 512 M

memory_limit = 512M

对 php-fpm 配置进行以下更改

sudo vim /etc/php-fpm.d/www.conf

将用户和组的值从 apache 更改为 nginx ,如下所示

user = nginx
group = nginx

安装NextCloud

转到 NextCloud 安装目录

cd /usr/share/nginx/html

使用以下命令安装 Nextcloud,php occ 的所有命令都需要从 /usr/share/nginx/html 目录调用;需要确保设置的数据库密码与创建数据库时的密码相同,同时这将新建一个管理员用户用于登录 NextCloud

sudo -u nginx php occ maintenance:install \
--data-dir /usr/share/nginx/data \
--database "pgsql" \
--database-name "nextclouddb" \
--database-user "nextclouddbuser" \
--database-pass "nextclouddbuserpassword" \
--admin-user "nextcloudadmin" \
--admin-pass "nextcloudadminpassword"

安装需要一点时间,完成后,通过运行以下命令配置数据库以保护服务器

sudo -u nginx php occ db:add-missing-indices

在运行文件缓存转换之前,首先启用维护模式

sudo -u nginx php occ maintenance:mode --on

修改文件 /usr/share/nginx/html/config/config.php 允许制定域名可访问 Nextcloud ,并配置使用 redis 缓存加速

...
  array (
    0 => 'localhost',
    1 => 'my.domain.com',
  ),
  'memcache.distributed' => '\OC\Memcache\Redis',
  'memcache.locking' => '\OC\Memcache\Redis',
  'memcache.local' => '\OC\Memcache\APCu',
  'redis' => array(
    'host' => 'localhost',
    'port' => 6379,
  ),
  'datadirectory' => '/usr/share/nginx/data',
...

然后运行转换并在要求确认时选择是

sudo -u nginx php occ db:convert-filecache-bigint

关闭维护模式

sudo -u nginx php occ maintenance:mode --off

配置Cron

以 nginx 的身份,编辑 crontab

crontab -u nginx -e

加入以下内容

*/5  *  *  *  * php -f /usr/share/nginx/html/cron.php

查看配置

crontab -u nginx -l

报错处理

若出现 OCP\HintException: [0]: Memcache \OC\Memcache\APCu not available for local cache (Is the matching PHP module installed and enabled?)

需要在 /etc/php.ini 中配置 apc.enable_cli = 1 ,没有就添加一下

[apcu]
apc.enable_cli=1

或在命令中添加 --define apc.enable_cli=1 临时使用

/usr/bin/php --define apc.enable_cli=1 -f /usr/share/nginx/html/cron.php