openSUSE + WordPress 的奇妙滋味

作为 openSUSE 的老用户,一直对这只可爱的大蜥蜴(准确地说是变色龙)怀着深厚的感情,虽然也经过几次变心,但最终我的桌面操作系统还是稳定在 openSUSE Tumbleweed 上。

之前我的博客是部署在阿里云上的,前不久听说了 Vultr,碰巧 openSUSE 15.0 正式发布,遂萌生尝鲜之心。网上关于 openSUSE 服务器的相关资料较少,部署的过程走了不少弯路,特此将一些要点整理以供参考。

为什么选择 openSUSE Leap

在选择部署在服务器的操作系统时,不同人可能会有不同的考量,对笔者而言,主要有以下几个理由:

  • 可靠性:我看过不少对 openSUSE Leap 部署在服务器上的可靠性的质疑,由于相关讨论在网上有不少这里就不赘述了。就笔者看来,自 42.1 起,openSUSE Leap 核心组件与商业发行版 SUSE Linux Enterprise 保持一致, 同时还有 openQA 测试系统,都保证了这一发行版的可靠性。
  • 便利性:openSUSE 提供的 YaST 大幅简化了安装到设定的过程,如果受够了一个个翻配置文件编辑参数, 相信你会喜欢上 YaST(不过在大多数情况下还是需要手动编辑配置文件的,有时 YaST 会把配置文件搞乱)
  • 信仰:要说选择 openSUSE 的原因,对笔者而言可能只是一种信仰吧,毕竟 Geeko 那么可爱😏

关于 Vultr

关于 Vultr 的优点以及注册购买网上有很多教程,这里也不赘述了(点击上面的图片可以直接跳转到 Vultr 哦)

需要注意的是,截至发文前 Vultr 的 ISO 库(ISO Library)中暂未提供 openSUSE Leap 15 的镜像, 所以在创建对象的时候需要上传自定义 ISO(Upload ISO)。

在界面直接贴上 DVD 镜像地址

https://download.opensuse.org/distribution/leap/15.0/iso/openSUSE-Leap-15.0-DVD-x86_64.iso

点击上传(Upload)就好了。

关于域名购买和 DNS 解析设置不在本文讨论范围内,这里假设你已经配置好域名的 DNS 解析了。

进入正题

笔者的目标是部署一个可以使用 HTTPS 加密访问并支持 HTTP/2 的 WordPress 站点。那么现在开始咯!

openSUSE 的安装

具体安装过程可以参考这里

实例创建好后,等待镜像系统准备完成(可能需要手动重启几次),点击 View Console 即可进入安装界面(如果连接不正常可以多尝试几次或者重启)。正如前文所述,YaST 在安装过程中起向导的作用,如果鼠标不是很好使,可以按 F3 切换到文本模式,关于 YaST 在文本模式下的使用方法,可以参考这里

注意在用户界面(User Interface)处应当选择服务器(Server)。

安装完成后可以直接点击 View Console 或使用 SSH 等方式连接,这里不再赘述。建议使用安装时配置的普通账号而非 root 账号登陆。

Apache 和 PHP 的安装与配置

Apache 的安装

这几年在网页服务器市场上,Nginx 一路高升,大有超越 Apache 的趋势,二者的特点在网上有很多资料,笔者在这里使用的是 Apache。

openSUSE 官方源中就有 Apache 软件包,直接安装即可:

sudo zypper in apache2

PHP 的安装

WordPress 作为 PHP 平台的系统,使用它自然需要安装 PHP 啦。openSUSE 官方源中已经有打包好的 PHP7,直接安装即可。同时还需要安装一些扩展模块。

sudo zypper in php7 php7-bz2 php7-gd php7-mbstring php5-mysql php7-zip php7-zlib pwgen php7-gettext php7-pear

php-fpm 的安装

根据这里的说明,自 Apache 2.4.27 起,prefork 模式不再支持 HTTP/2 ,而 mod_php 模块又依赖 prefork 模式,所以为了开启 HTTP/2 ,我们需要将 Apache 的多进程模式切换到 worker 或 event,并使用 php-fpm 而非 mod_php。

openSUSE 15.0 的 Apache 默认不带 event 模式,需要安装

sudo zypper in apache2-event

然后将/etc/sysconfig/apache2 中的 APACHE_MPM="prefork"字段修改为 APACHE_MPM="event"。也可以使用 yast 的系统 - /etc/sysconfig 编辑器System - /etc/sysconfig Editor)修改

重启 Apache:

sudo apachectl restart

安装官方源中的 php-fpm:

sudo zpyyer in php7-fpm

启用模块

首先确认一下 Apache 启用的模块,使用 apachectl 可以很方便地查看启用的模块:

sudo apachectl -M

需要的模块包括了:

  • mod_rewrite(伪静态支持)
  • proxy_module、proxy_fcgi_module(FastCGI 协议支持)
  • ssl_module(HTTPS 支持)
  • http2_module(HTTP/2 支持)
  • mod_headers、mod_filter 和 mode_deflate(gzip 支持)

一些模块可能已经被启用,对照一下列表,使用 a2enmod 启用其他模块,例如要启用 mod_rewrite 的话:

sudo a2enmod rewrite

注意 proxy_module 和 proxy_fcgi_module 的启用顺序,由于后者依赖前者,所以需要先启用 proxy_module,否则会出现错误。

设置虚拟主机

使用 YaST 可以很方便地创建虚拟主机,不需要自己敲配置了。

默认可能没有安装 YaST 的 HTTP 服务配置模块,需要手动安装:

sudo zypper in yast2-http-server

然后在终端输入 sudo yast 启动文本模式的 YaST,打开网络服务(Network Services)- HTTP 服务器(HTTP Server)。

切换到主机项,Alt+A 选择添加,进入添加主机界面。

这里的配置有几个要点:

  • 服务器名填写域名
  • 服务器内容根设定为之后 WordPress 所在的根目录(即 index.php 所在的目录,默认是/srv/www/htdocs)
  • 服务器解析处应当选择 “通过服务器 IP 地址确定请求服务器”

Apache 配置

在 openSUSE 中 Apache 的配置文件分散在/etc/apache2 中,其中 httpd.conf 是主配置文件,查看该文件可以看到各个文件的说明,这一系列文件通过 Include 参数与 httpd.conf 连接。

一些文件未定义的参数建议通过在/etc/apache2/conf.d 下创建*.conf 文件配置。例如开启 gzip(开启 gzip 的方法有很多种,网上都有资料,本文就不多谈了)。

在这里我们创建一个名为 php.conf 的配置文件以让 Apache 将 php 交给 php-fpm 处理:

sudo nano /etc/apache2/conf.d/php.conf

添加如下内容:

<FilesMatch "\.php$">
    SetHandler "proxy:fcgi://127.0.0.1:9000/"
</FilesMatch>
DirectoryIndex index.php

保存即可

php-fpm 的配置

在 openSUSE Leap 15.0 中 php-fpm 的主配置文件是/etc/php7/fpm/php-fpm.conf,默认安装后只有一个 php-fpm.conf.default 文件,将其复制或重命名为 php-fpm.conf

sudo cp /etc/php7/fpm/php-fpm.conf.default /etc/php7/fpm/php-fpm.conf

/etc/php7/fpm/内默认没有 php.ini,可以从/etc/php7/fpm/cli 复制一份:

sudo cp /etc/php7/fpm/cli/php.ini /etc/php7/fpm/

关于 php-fpm.confphp.ini 的配置与优化在网上有很多教程,可以结合具体情况做出相应调整。

设置防火墙

openSUSE Leap 15 一个大的改变就是 FirewallD 成为默认防火墙,目前 YaST 未提供文本界面下的相应的配置工具,我们可以使用 firewall-cmd 工具进行防火墙配置。

首先让我们查看一下已经开放的服务:

sudo firewall-cmd --list-service

请确认输出结果里有 httphttps 这两个服务。

如果没有,可以开放这两个服务,将 httphttps 两个服务持久添加到默认的 public 区域:

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

这基本等效于打开 80/TCP 和 443/TCP 端口,所以也可以采用打开端口的方法,开放 80/TCP 端口:

sudo firewall-cmd --zone=public --add-port=80/tcp --permanent

开放 443/TCP 端口:

sudo firewall-cmd --zone=public --add-port=443/tcp --permanent

开放服务和开放端口两种方法二选一,然后重新加载防火墙

sudo firewall-cmd --reload

测试

到这一步我们可以进行服务器的测试了。首先激活启动 Apache 和 php-fpm:

# 激活 Apache
sudo systemctl enable apache2
# 启动 Apache
sudo systemctl start apache2
# 激活 php-fpm
sudo systemctl enable php-fpm
# 启动 php-fpm
sudo systemctl enable php-fpm

在刚刚设置的虚拟主机内容根目录(如/sev/www/htdocs)内新建一个 index.php 文件,内容为<?php phpinfo(); ?>,可以直接使用 echo 命令:

sudo sh -c "echo '<?php  phpinfo(); ?>'  > /srv/www/htdocs/index.php"

在浏览器中输入,如果出现如下图所示的界面,说明到目前为止的配置是顺利的:

MariaDB 的安装与配置

这里笔者使用 MariaDB 作为数据库。首先先安装:

sudo zypper in mariadb mariadb-tools

激活并开启 MariaDB:

sudo systemctl enable mysql
sudo systemctl start mysql

运行安全配置向导:

sudo mysql_secure_installation

In order to log into MariaDB to secure it, we’ll need the current password for the root user. If you’ve just installed MariaDB, and you haven’t set the root password yet, the password will be blank, so you should just press enter here.
Enter current password for root (enter for none):

一开始是一些说明,要求输入 root 密码(注意这里的 root 指 MariaDB 的 root 用户而非 Linux 系统用户),默认为空,直接按回车即可。

Setting the root password ensures that nobody can log into the MariaDB root user without the proper authorisation.
Set root password? [Y/n]

询问谁否设置 root 密码,输入 y 回车。

New password:

输入想要设定的 root 密码。

Re-enter new password:

再次输入 root 密码。

Reloading privilege tables.. … Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment.
Remove anonymous users? [Y/n]

输入 y 回车来删除匿名用户以增强安全性。

Normally, root should only be allowed to connect from ‘localhost’. This ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n]

输入 y 回车以禁用远程登录 root 账户。

By default, MariaDB comes with a database named ‘test’ that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment.
Remove test database and access to it? [Y/n]

输入 y 回车删除测试数据库。

… Success! – Removing privileges on test database… … Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately.
Reload privilege tables now? [Y/n]

输入 y 回车重新载入权限表以确保所有配置生效。

Cleaning up… All done! If you’ve completed all of the above steps, your MariaDB installation should now be secure.
Thanks for using MariaDB!

看到这句话说明配置成功了。

接着登陆 MariaDB 的 root 用户:

sudo mysql -u root -p

输入刚刚设置的密码,出现 mysql> 提示符后,依次输入以下命令:

-- 创建一个普通用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

-- 创建数据库
CREATE DATABASE 数据库名;

-- 给予普通用户该数据库的所有权限
GRANT ALL PRIVILEGES ON 数据库名.* TO "用户名"@"主机名";

-- 刷新权限
FLUSH PRIVILEGES;

-- 退出
EXIT

配置 HTTPS

我们可以使用 Let’s Encrypt 提供的免费证书开启 HTTPS,使用 Certbot 可以快速进行证书的申请与续期。

证书申请

openSUSE 官方源中有打包好的 Certbot 和 Apache 支持插件,安装它们:

sudo zypper in certbot python-certbot-apache

Let’s Encrypt 现在支持申请通配符证书,使用以下命令申请:

sudo certbot --apache certonly  -d *. 域名 --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory

经过一系列问答后,进入验证环节:

Please deploy a DNS TXT record under the name _acme-challenge.newyingyong.cn with the following value:

一串字符

Before continuing, verify the record is deployed.

在 DNS 添加一条 TXT 记录,记录值为上面的字符串,确认生效后按回车如果顺利 Certbot 将申请好证书并自动修改相关配置文件。可以在浏览器输入 https://域名测试 HTTPS 链接是否正常。

自动续期

Let’s Encrypt 证书有效期为 90 天,我们可以设置一个 systemd 的 timer 定时器来自动续期。

新建一个服务:

sudo nano /etc/systemd/system/letsencrypt.service

填入以下内容保存:

[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew
ExecStartPost=/bin/systemctl restart apache2

新建一个 timer:

sudo nano /etc/systemd/system/letsencrypt.timer

填入以下内容保存:

[Unit]
Description=Renewal of Let‘s Encrypt

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

激活并开启这个 timer

sudo systemctl enable letsencrypt.timer
sudo systemctl start letsencrypt.timer

WordPress 的安装与配置

为了便于配置,先切换到前面设置的虚拟主机内容根目录(如/srv/www/htdocs):

cd /srv/www/htdocs

删除之前创建的 index.php

rm index.php

WordPress 简体中文官网复制最新版 .tar.gz 包的下载地址(这里 4.9.4 为例子),下载到内容根目录:

sudo wget https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz

解压:

sudo tar zxvf wordpress-4.9.4-zh_CN.tar.gz

删除压缩包:

rm wordpress-4.9.4-zh_CN.tar.gz

将 wordpress 文件夹中的所有内容移动到内容根目录:

sudo mv ./wordpress/* ./

删除 wordpress 文件夹:

rm -r wordpress

更改权限:

cd ..
sudo  chmod -R 775 ./htdocs
sudo  chown  -R  wwwrun:www ./htdocs

之后的安装步骤可以参照这里,按照向导来就行。

进入仪表盘后请确保设置-常规中的两个地址带有 https,如果没有请手动添加:

HTTP/2 配置

关于 HTTP/2 的介绍网上有很多资料,笔者认为开启是有利无害的,而且笔者相当喜欢尝试新事物。

在前面的配置中我们以已经加载了 http2_module,只需要在相应的虚拟主机配置文件中加入参数即可:

sudo nano /etc/apache2/vhosts.d/ip-based_vhosts-le-ssl.conf

在开头加入:

Protocols h2 http/1.1

重启 Apache:

sudo apachectl restart

可以通过 http2.pro 检查网站是否成功开启了 HTTP/2。

注:在/etc/apache2/protocols.conf 中默认有一系列 HTTP/2 相关配置,但该文件对虚拟主机无效

openSUSE 在 /etc/apache2/protocols.conf 中预置了配置,从而简化了 HTTP/2 的配置流程。

在前面的配置中我们以已经启用了http2_module,现在只需启用 HTTP2 标记:

sudo a2enflag HTTP2

重启 Apache 即可:

sudo systemctl restart apache2

注:使用 sudo systemctl restart 似乎无法使配置生效。

结束

至此我们的配置全部完成,后续的其他配置可以参考网上其他资料。

由于全过程较复杂,且笔者主要靠回忆写成本文,未进行再次验证,如有错误欢迎读者留言指正。

修订记录

  • 2018 年 6 月 29 日修订:补充关于 mpm 模式切换的说明,修正创建数据库处的错误
  • 2019 年 10 月 23 日修订:修改关于 HTTP/2 配置相关内容
  • 2020 年 8 月 26 日修订:新开服务器,图片已丢失,这次配置有了很多新的发现,待完善

「openSUSE + WordPress 的奇妙滋味」への1件のフィードバック

  1. ピンバック: php-fpm unix socket 权限的大坑 - 戚威生的博客

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です