安装 WordPress 并不难,网上也有很多教程,无非就是以下几步:
- 安装 Nginx
- 安装 MySQL
- 下载 WordPress 并解压到某个文件夹
- 配置 Nginx 和证书
事情是这样的,我原本打算将破站升级到 HTTP3,同时由于你懂的原因需要使用 Caddy。这就导致两个问题:Caddy 和 Nginx 都需要占用 443 端口,我需要让 Nginx 和 Caddy 共存;并且我当前使用的 Nginx 版本并不支持 HTTP3。于是我打算自行编译 Nginx,但是腾讯轻量云真的一言难尽,一编译直接卡死,I/O 直接爆表,重装系统后也是那样。遂弃用腾讯云,开始迁移这破站。
编译安装 Nginx
准备工作
1.安装必要软件
apt update
apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config
2.编译 BoringSSL
git clone --depth=1 https://github.com/google/boringssl.git
cd boringssl
mkdir build
cd build
cmake -GNinja ..
ninja
cd ~
3.编译ngx_brotli
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init
cd ~
ngx_brotli 也可以通过 apt 进行安装,之后直接使用 load_module 指令引入 Nginx 就行,所以这一步可以忽略。
4.clone nginx 到本地
hg clone https://hg.nginx.org/nginx
cd nginx
编译
#生成makefile文件
./auto/configure --user=www-data --group=www-data --prefix=/usr/local/nginx \
--add-module=/root/ngx_brotli \
--with-compat \
--with-debug \
--with-file-aio \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_degradation_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_perl_module=dynamic \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-http_xslt_module=dynamic \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-pcre --with-pcre-jit \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-threads \
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' \
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' \
--with-cc-opt=-I../boringssl/include \
--with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto' \
--with-http_v3_module \
自行编译的好处就是可以根据自己的需要添加或者不添加相应的模块。网上找一些模板拼接一下就行,尤其是最后几个模块,是我特别需要的。上一步完成过后,就可以开始编译和安装了。
make
make install
编译过程可能会碰到些问题,根据报错自行 Google 解决也很快,这就不多赘述了。
make install
完成后,不出意外就可以在 /usr/local/nginx/
中看到相应文件了。由于编译安装时并未将 Nginx 加入环境变量,因此直接执行 nginx -V
命令是肯定会报错的,不过设置环境变量太麻烦了,使用软链接将可执行文件链接到 /usr/local/bin/ 文件夹就行了。
ln -s /usr/local/nginx/bin /usr/local/bin/nginx
现在就没有问题了。接下来将 Nginx 加入开机自启。
:~# nginx -V
nginx version: nginx/1.25.2
built by gcc 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)
built with OpenSSL 1.1.1 (compatible; BoringSSL) (running with BoringSSL)
TLS SNI support enabled
configure arguments: --user=www-data --group=www-data --prefix=/usr/local/nginx --add-module=/root/ngx_brotli --with-compat --with-debug --with-file-aio --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --with-cc-opt=-I../boringssl/include --with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto' --with-http_v3_module
配置 service 实现自启动
cd ~
vim /usr/lib/systemd/system/nginx.service
写入如下配置
[Unit]
Description=Nginx complied with http3 module
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecReload=/usr/local/nginx/sbin/nginx -s reload
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
添加到自启动
systemctl-reload
systemctl start nginx.service
#查看一下状态
systemctl status nginx.service
#如果启动成功了,没有任何报错,就可以 enable 了
systemctl enable nginx.service
安装 MySQL
鉴于自己对后端存在巨大知识盲区,数据库我选择用 Docker 进行安装,毕竟能不在命令行用 MySQL 就不用。关于安装 Docker 可以参考官方文档:https://docs.docker.com/engine/install/ubuntu/
编辑 docker-compose 配置文件
cd ~
mkdir compose
cd compose
mkdir mysql
cd mysql
vim docker-compose-mysql.yml
写入如下配置:
services:
mysql:
command:
- --default-authentication-plugin=mysql_native_password
container_name: "mysql"
deploy:
resources:
limits:
cpus: "0.5"
environment:
MYSQL_ROOT_PASSWORD: your password
MYSQL_DATABASE: your wordpress database name
MYSQL_USER: your customized database user
MYSQL_PASSWORD: your customized user password
image: mysql:8.0.33
ports:
- 127.0.0.1:3306:3306
restart: always
volumes:
- ./data/:/var/lib/mysql
#- ./conf/my.cnf:/etc/my.cnf
- ./log:/var/log/mysql
#- /etc/timezone:/etc/timezone:ro
#- /etc/localtime:/etc/localtime:ro
将上面 your password
换成自己的 mysql root 密码,将 your wordpress database name
换成你自己定义的数据库名称,比如 mywordpress。将 your customized database user
换成你自己的的名称,密码换成自己的密码即可。
这里将端口映射到 127.0.0.1:3306 可以避免将数据库直接暴露在公网,而 - --default-authentication-plugin=mysql_native_password
可以解决 WordPress 连接高版本 MySQL 的认证问题。
安装 WordPress
第一步,从创建文件夹开始,有了就不用创建了。
cd ~
mkdir /www/wwwroot/ -p
cd /www/wwwroot/
下载和 cp WordPress 文件
wget https://wordpress.org/latest.tar.gz
tar -zxvf latest.tar.gz
解压过后就可以看到 wordpress
文件夹了。
:/www/wwwroot# ls
latest.tar.gz wordpress
当然这时候还不能访问 WordPress,因为没有配置 Nginx。接下来就需要配置 Nginx 了。
配置 Nginx
在配置 Nginx 之前还需要申请 SSL 证书,不然无法实现 HTTPS,更别说 HTTP3 了。建议使用 acme.sh 开源程序,这里就不展开了。
Nginx 的配置文件真的及其复杂,相信有很多人都和我一样,被各种一键面板惯坏了,基本上对 Nginx 的配置就是 Ctrl + C, Ctrl + V 的程度。为了更好的复制粘贴,当然要祭出 DigitalOcean 的在线可视化配置工具了,该工具还支持中文 👏:https://www.digitalocean.com/community/tools/nginx
配置完成后根据官方指引,将下载好的压缩包直接解压到 Nginx 的配置文件路径就行了。
官方的指引是将文件直接解压到 /etc/nginx 目录,然而我是自己编译安装的,Nginx 的一切配置文件都在 /usr/local/nginx/conf/ 目录下。因此我需要 cd 到 /usr/local/nginx/conf/ 目录进行图上的操作,而不是 /etc/nginx 。如果执行 nginx -t
测试没有问题,就可以启动 Nginx 了。
当然生成的 Nginx 配置文件不一定完美适合自己的需求,可能需要小修小改。
我的需求就两个:
- 我要用 Caddy,因此需要使用 Nginx 转发 Caddy 的流量
- 我需要开启 HTTP3,配置工具的 HTTP3 配置好像有问题
Nginx 和 Caddy 共存
首先,将 Caddy 切换到别的端口,比如说 12345。比如下面的配置(这配置一看就知道是干嘛的 🤐
{
order forward_proxy before route
admin off
auto_https off
https_port 12345 #端口
}
:12345{ #端口
tls /cert directory/fullchain.cer /cert directory/example.com.key { #证书位置
ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
alpn h2 http/1.1
}
forward_proxy {
basic_auth user password #用户名 密码
hide_ip
hide_via
probe_resistance
}
@host {
host example.com #域名
}
route @host {
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
reverse_proxy https://example.com { #伪装网站,自己更换
header_up Host {upstream_hostport}
header_up X-Forwarded-Host {host}
}
}
}
然后编辑 Nginx 的主配置文件,加入 stream 块的配置。因为需要使用 Nginx的 SNI 识别,并通过 stream 将 Caddy 的流量在第四层进行转发。这里 stream 模块和 stream_ssl_preread_module 模块就有作用了。有关 stream 模块和 stream_ssl_preread_module 可以参考:
http://nginx.org/en/docs/stream/ngx_stream_core_module.html
http://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html
接下来开始配置
vim /usr/local/nginx/conf/nginx.conf
添加如下配置:
stream {
map $ssl_preread_server_name $backend_name {
example.com caddy;
your-web-domain.com web;
default web;
}
upstream web{
server 127.0.0.1:54321; #注意这个端口号不能用443了,443已经给stream用了
}
upstream caddy{
server 127.0.0.1:12345;
}
server {
listen 443 reuseport;
listen 443 udp;
proxy_pass $backend_name;
ssl_preread on;
# proxy_ssl_session_reuse off;
#proxy_protocol on;
}
}
注意: stream 块不能包含在 http 块里面;一定要添加 listen 443 udp
,因为 HTTP3 是基于 QUIC 协议,而 QUIC 是基于 UDP 的。
为网站添加 HTTP3 支持
vim /usr/local/nginx/conf/sites-enabled/your-web-domain.com.conf
为自己的站点添加如下配置:
server {
listen 80;
listen 54321 quic reuseport; #注意这个端口号不能用443了,443已经给stream用了
listen 54321 ssl http2; #注意这个端口号不能用443了,443已经给stream用了
...
...
add_header Alt-Svc 'h3=":443"; ma=86400';
ssl_early_data on;
...
...
}
为什么是listen 54321 quic 而不是 listen 54321 http3?
这个问题我也很疑惑…
齐活!
去 https://http3check.net 测试一下吧~