在Debian 9环境下配置基于LNMP的WordPress博客

这其实是10月份写的文章。原来的blog在DigitalOcean上,因为ping实在是太高了,SSH和传文件很不爽,所以换了一家VPS服务商。新的VPS用的Linux发行版是openSUSE也不是Debian了。但是配置过程还是大同小异的。

因为URI改了,所以原来的文章没法迁移到这(你这懒癌晚期患者真的写过什么blog文章吗?),改备份的SQL真是改到吐血。好在原来的markdown还在,所以重新导入一下就可以。然后在文章里面补充了一些新问题的解决办法。

==========原文==========

鸽了一个月,总算把博客用wordpress搭起来了。把折腾部署网站的过程记下来,做个备忘。

网站用的是nginx服务器,OS是debian9,虽然说有懒人版的lnmp脚本,但是我把手动部署的过程走了一遍。
搭建的过程主要参考了以下文章:
https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-nginx-on-ubuntu-14-04

新建一个带 sudo 权限的用户

以root身份登录服务器,新建一个带sudo权限的用户,然后切换到该用户。

adduser demo
usermod -a -G sudo demo
su demo

安装PHP nginx MySQL

安装之前先更新下服务器预装的软件包。然后安装环境。

sudo apt-get update && apt-get dist-upgrade

首先安装以下软件包:
nginx mariadb-server php php-gd php-mysql php-fpm php-ssh2

  • php-fpm: php-fastcgi的一个实现。
  • php-gd: 为php语言添加处理图像数据的支持。
  • php-ssh2: 使得wordpress能通过ssh方式访问本地服务器。

运行命令 sudo apt-get -t stretch-backports install nginx php php-gd php-mysql php-fpm php-ssh2 mariadb-server 来安装。

如果提示找不到stretch-backports仓库,在/etc/apt/sources.list文件中添加以下两行:

deb http://http.us.debian.org/debian/ stretch-backports main contrib non-free
deb-src http://http.us.debian.org/debian stretch-backports main contrib non-free

然后 sudo apt-get update 刷新一下就可以安装了。

apt-get 会顺带把Apache(软件包名字叫apache2)也安装上,这里我们不用Apache做服务器。由于先安装了nginx并启动了服务,Apache安装成功之后它的服务也会启动失败。因此先输入命令sudo systemctl disable apache2.service把Apache服务关掉。

配置全站https

安装完nginx,在浏览器中输入http://<你的VPS的IP>/ 应该能看到nginx的欢迎画面。

为了让网站的内容不会被运营商和功夫网视奸,进而水表不保。我们先把网站弄上https,并且让网站的SSL安全等级达到SSLlabs网站的A+评价。

获取给域名颁发的SSL证书

这里选择LetsEncrypt作为网站SSL证书的颁发者。首先在DNS控制台里把拥有的域名指向我们的服务器:

安装Certbot帮助我们自动签发LetsEncrypt证书,输入命令:

sudo apt-get install python-certbot-nginx -t stretch-backports

输入配置Certbot自动签发的命令:

sudo certbot certonly --authenticator standalone --pre-hook "systemctl stop nginx.service" --post-hook "systemctl start nginx.service"

配置期间会让你输入以下信息:
– 用于签发证书的邮箱
– 要签发证书的域名

输入后一路按回车,SSL证书应该就签发好了。

检验Certbot是否能自动续签证书

https://certbot.eff.org/docs/using.html#automated-renewals

具体方法是输入命令systemctl list-timers 可以看到有个计时器名叫certbot.timer,证明自动续签定时器是有效的。
要检验证书续签是否有效,输入命令:

sudo certbot renew --dry-run

配置nginx服务器应用https

打开文件 /etc/nginx/sites-enabled/default,添加或把现有配置修改为以下内容:

# 监听80端口,把所有的http请求通过返回301值重定向到https上
server {
    listen 80 default_server;              # IPv4
    listen [::]:80 default_server;         # IPv6
    server_name http_redirect;             # 服务器配置名
    return 301 https://$host$request_uri;  # http请求全都通过301重定向到同名的https URL上
}
# 监听443端口,提供https服务
server {
    listen 443 ssl;                        # 监听443端口,且开启ssl
    listen [::]:443 ssl;                   # v6

    # 使用的SSL 证书,这里用之前letsEncrypt签发证书存放的位置
    ssl_certificate /etc/letsencrypt/live/<your domain here>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<your domain here>/privkey.pem;

    # 复用SSL连接
    ssl_session_cache          shared:SSL:1m;
    ssl_session_timeout        5m;

    # SSL加密方式这里用的是nginx的默认设置
    ssl_ciphers                HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    ssl_protocols TLSv1.2;                 # 只支持TLS v1.2协议

    # 访问日志
    access_log  /var/log/nginx/host.access.log;
    error_log   /var/log/nginx/host.error.log;

    # 开启 HSTS 支持
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    server_name https_web;

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

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

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
}

要达到A+级评分,还需要一个强度较高的用于DH密钥交换的key。否则评价会限制在B级上。

首先输入命令 openssl dhparam -out /etc/nginx/dhparam.pem 2048 生成一个新密钥。
然后打开/etc/nginx/nginx.conf,在http栏添加配置:

ssl_dhparam dhparam.pem;

以上步骤都完成之后,输入systemctl restart nginx.service 重启nginx服务。
这时在浏览器里面输入域名,应该能正确跳转到https连接,并且证书是有效的,在SSLlabs网站上检测也能拿到A+的评价。

配置MySQL(MariaDB)服务器

输入命令mysql -u root -p以root用户身份登录MariaDB服务器,提示输入密码时输入root账户的密码,登录到MariaDB数据库。

我们现在要为WordPress新建一个数据库,然后建立一个新用户供WordPress程序使用。该用户只能读写WordPress数据库中的内容。

为了保证数据库的安全,先移除掉MariaDB安装后的一些默认设置。
运行脚本:

mysql_secure_installation

脚本会提示你重新设置root密码,移除掉匿名用户,禁止root用户远程登录MariaDB服务器,移除MariaDB安装时附带的测试数据库。

之后配置数据库。
输入以下命令:

create database wordpress;
create user wp@localhost identified by 'dontusethispassword'; -- 只允许本地登录(不要用这个密码!)
grant all privileges on wordpress.* to wp@localhost; -- 给用户 wp 对数据库 wordpress 所有的操作权限 
flush privileges; -- 刷新权限配置

配置完成,输入\q退出MySQL控制台。

配置WordPress网站并初始化博客网站

下载WordPress最新版本

从WordPress 官方网站下载最新版本的Wordpress压缩包,放置在本地目录并解压:

cd ~
curl -O https://wordpress.org/latest.tar.gz
tar xzvf latest.tar.gz

设置WordPress的wp-config.php

进入解压出来的WordPress目录,将示例配置文件wp-config-sample.php复制一份,命名为wp-config.php

cd wordpress
cp wp-config-sample.php wp-config.php

打开wp-config.php,将以下内容

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'database_name_here');

/** MySQL database username */
define('DB_USER', 'username_here');

/** MySQL database password */
define('DB_PASSWORD', 'password_here');

修改为:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');      // WordPress要使用的数据库名

/** MySQL database username */
define('DB_USER', 'wp');                      // MySQL数据库用户名

/** MySQL database password */
define('DB_PASSWORD', 'dontusethispassword'); // 之前建立的用户 wp 的密码。

https://api.wordpress.org/secret-key/1.1/salt/ 获取存储用户验证信息时要加的盐(不要原样复制这里的数据!):

define('AUTH_KEY',         '/ (+4E5i---qv ^ql_!6SYfy1 <DO_NOT_COPY_VALUES_HERE> S w!GFli/}0mGA-5X!H5MgophTWq8*$#-s|Nt<O');
define('SECURE_AUTH_KEY',  'zyJ0+.lntK(pmoLz}{&2r4hIZ <DO_NOT_COPY_VALUES_HERE> PSU+$;OwVmZ-M-~FMOCOsCcqui9Q^mhUG*V]F=M');
define('LOGGED_IN_KEY',    'FqO}:DqL&_(YEh(G;90u_?]9h <DO_NOT_COPY_VALUES_HERE> .$)>:G`i.%(Imechhw@]lHuaF3Mvqt<q%NhM>Kj');
define('NONCE_KEY',        'ENG`i~-XP}o|-qe]tks~FVB@5 <DO_NOT_COPY_VALUES_HERE> ~;p;SVy6A)kNEqZ9Mw(Rgm`w={N&>*KXK)eh_|;');
define('AUTH_SALT',        'xgMO]-tb^*YZhRG(sU0N{u2Wi <DO_NOT_COPY_VALUES_HERE> 9$0B0/SpB}|C6(,+deb];=RYb=-R!d$_& 9qHDr');
define('SECURE_AUTH_SALT', ')-/GgH`>p6SU2bx*)nV?=}+3c <DO_NOT_COPY_VALUES_HERE> 2L6#8Pqn0@-bRm&D}T+2L.+nA638|y+|:`zF,4T');
define('LOGGED_IN_SALT',   '+Y|Pm`ExaNg|KoU<h`D,Kaw0u <DO_NOT_COPY_VALUES_HERE> b.QEa-=[g*<E/$EIBcOa^O|eNQFmnsB+D-w?:uW');
define('NONCE_SALT',       '_/4.-?-QB[)p0<U#M{MCqCum* <DO_NOT_COPY_VALUES_HERE> d!$bs4v%J:imVE^WRaLyZ 51m|&-ckqaV=dzvM_');

替换掉wp-config.php中原有的内容:

define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

保存并退出编辑器。

复制WordPress文件至网站根目录,配置目录权限

复制WordPress至网站根目录,然后进入该目录。

sudo rsync -avP ~/wordpress/ /var/www/wordpress
cd /var/www/wordpress

运行nginx进程的用户所在的组有www-data,让nginx能读写WordPress所在的目录:

sudo chown -R demo:www-data /var/www/wordpress/*

新建wp-content/uploads目录,然后设置权限,使得我们在网页端能上传文件。

mkdir wp-content/uploads
sudo chown -R :www-data ./wp-content/uploads

配置nginx

打开/etc/nginx/sites-enabled/default文件,修改配置:

    root /var/www/wordpress;
    index index.php index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

最终修改完成的配置文件如下:

server {
    listen 80 default_server;              # IPv4
    listen [::]:80 default_server;         # IPv6
    server_name http_redirect;             # 服务器配置名
    return 301 https://$host$request_uri;  # http请求全都通过301重定向到同名的https URL上
}

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

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;
    # 使用的SSL 证书,这里用之前letsEncrypt签发证书存放的位置
    ssl_certificate /etc/letsencrypt/live/<your domain here>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<your domain here>/privkey.pem;
    # 复用SSL连接
    ssl_session_cache          shared:SSL:1m;
    ssl_session_timeout        5m;
    # SSL加密方式这里用的是nginx的默认设置
    ssl_ciphers                HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    ssl_protocols TLSv1.2;                 # 只支持TLS v1.2协议

    # 访问日志
    access_log  /var/log/nginx/host.access.log;
    error_log   /var/log/nginx/host.error.log;

    # 添加 HSTS 支持
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    server_name https_web;

    root /var/www/wordpress;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

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

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }

    # pass PHP scripts to FastCGI serve
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        # With php-fpm (or other unix sockets):
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        include fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    location ~ /\.ht {
        deny all;
    }
}

重启nginx和php-fpm服务:

sudo systemctl restart nginx.service
sudo systemctl restart php7.0-fpm.service

访问网站完成WordPress配置

这时在浏览器地址里面输入你的域名,应该能显示WordPress的安装页了。输入站点名、用户名、密码、邮箱,wordpress会自动帮你配置好其余的东西。

然后WordPress会提示你登录,登录后进入WordPress管理员页面。


这时WordPress的配置就完成了。

排错

遇到网页打不开的情况时,可以打开wp-config.php,然后打开调试开关:

define('WP_DEBUG', true);
define('WP_DEBUGLOG', true);

之后可以在wp-content/debug.log找到调试日志。

碰到css加载不出来之类的问题,去翻/var/log/nginx/host.access.log/var/log/nginx/host.access.log这两个文件。

后续配置

博客启动后的后续配置目前碰到了一些坑,这里记录已经遇到的问题和解决办法。

在WordPress管理员页面不能安装插件,需要FTP/SSH用户凭据

如图,安装插件时WordPress提示需要FTP或者SSH凭据。

解决方法是在wp-config.php中加上:

define('FS_METHOD','direct');

然后运行命令,给组赋予写的权限

sudo chmod g+w <your wordpress dir>/wp-content/* -R

即可解决该问题。

我想更改管理员邮箱,但是收不到确认信件

原因可能是主机商把mail()禁用了。检验方法是进入WordPress登录页面,点忘记密码,然后输入你的管理员邮箱,点获取新密码。如果出现以下提示,提示mail()函数被主机商禁用,那么就是这种情况。

解决的办法除了有联系主机商提供支持之外,还可以使用第三方的SMTP服务。这里以gmail为例:

  • 安装 WP Mail SMTP by WPForms 插件。

  • 在插件设定页中指定你要发邮件的gmail邮箱:

  • 登录 https://console.developers.google.com/flows/enableapi?apiid=gmail&pli=1
    • 先选择一个Project,没有则新建一个。
    • 在Add credentials to your project页面配置如下:
    • 选择新建一个OAuth client ID:

    • 把生成出来的凭据填进插件设置页对应的输入框中:
    • 点保存设置,然后点击Allow plugin to send emails using your Google account,授权插件使用该gmail邮箱发送邮件。
    • 最后可以进入Email Test页发送邮件,测试发送服务是否已经生效。生效可能需要一段时间。

我更改了WordPress的Permalink设置,然后博客上所有的链接都404了

解决方法是在/etc/nginx/sites-enabled/default中的https服务器配置中添加以下配置(仅适用于把WordPress作为网站根目录的情况):

    if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;
    }

WordPress上传不了大小超过2MB的东西

要更改PHP所允许的最大上传大小和nginx能接受的请求包的最大的大小。

  • 首先找到PHP加载的配置文件的位置,输入命令php -i | grep "Loaded Configuration File"
  • 这里得到php.ini的位置在 /etc/php/7.0/cli/php.ini
  • 修改 php.ini 中的配置项upload_max_filesizepost_max_size至想要的大小数值。这里设成64MB。
  post_max_size = 64M
  upload_max_filesize = 64M
  • 保存php.ini后,重启php7.0-fpm.service
  systemctl restart php7.0-fpm.serivice
  • 如果还是不行,那还需要修改nginx的配置。修改/etc/nginx/nginx.conf,在http栏加上配置:
  client_max_body_size 64M;
  • 之后重启服务nginx.service

参考资料

配置LNMP/wordpress: https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-nginx-on-ubuntu-14-04

签发Let’s Encrypt证书: https://certbot.eff.org/lets-encrypt/debianstretch-nginx

提升SSLlabs评价分数: https://michael.lustfield.net/nginx/getting-a-perfect-ssl-labs-score

安装插件: https://www.digitalocean.com/community/questions/wordpress-asking-for-ftp-credentials

Permalink设置:https://www.digitalocean.com/community/questions/404-when-using-pretty-permalinks-on-new-wordpress-site-on-lemp-nginx

3 thoughts on “在Debian 9环境下配置基于LNMP的WordPress博客”

Leave a Reply

Your email address will not be published. Required fields are marked *