内容简介:由于几年前一直在做 .Net 相关的开发,于是在阿里云上买了一台 Windows Server 的主机,在上面用 IIS 搭建 Web 环境还是比较方便的。后来写 PHP,也是用的 Windows 环境,那个时候比较流行 SAE 搭建本地开发环境,非常简单,还写过一篇文章介绍了最近这台服务器要到期了,一直想着换台 Linux 的服务器,终于可以如愿了。不过迁移服务器好麻烦,好多东西要备份,花了大半天时间把服务器上的东西备份好,又花了大半天的时间把博客迁移到新的服务器,这里对迁移过程做个记录,便于来日查阅。备
由于几年前一直在做 .Net 相关的开发,于是在阿里云上买了一台 Windows Server 的主机,在上面用 IIS 搭建 Web 环境还是比较方便的。后来写 PHP,也是用的 Windows 环境,那个时候比较流行 SAE 搭建本地开发环境,非常简单,还写过一篇文章介绍了 在 Windows 上搭建 PHP 本地开发环境 的其他方法,基本上都是部署在这台服务器上。这台服务器一用就是好多年,所以后来开始写博客,无论是一开始用的 WordPress 还是现在用的 Typecho,也是一直放在这台服务器上的。但随着自己开始学 Java,学 Docker,学 DevOps,这台 Windows Server 越来越没用了,一年将近 1000 块的大洋,性价比超低。
最近这台服务器要到期了,一直想着换台 Linux 的服务器,终于可以如愿了。不过迁移服务器好麻烦,好多东西要备份,花了大半天时间把服务器上的东西备份好,又花了大半天的时间把博客迁移到新的服务器,这里对迁移过程做个记录,便于来日查阅。
一、备份博客
备份分两步,备份 MySQL 和备份 Typecho:
1.1 备份 MySQL
我这里直接使用 MySQL 的图形化客户端工具 SQLyog Ultimate, Backup/Export
-> Backup Database As SQL Dump
,选择 Structure and data,导出即可。
当然也可以用 mysqldump
,譬如下面这样:
> mysqldump -u root -p --databases typecho_db > typecho_db.sql
1.2 备份 Typecho
这个没啥说的,直接将网站目录打包备份即可。值得注意的是 Typecho 的目录结构,它的根目录有几个文件: index.php
是入口文件, install.php
是安装文件,建议在安装完成后删除, config.inc.php
这个是 Typecho 的配置文件,在安装时自动生成的。除此之外,还有三个目录: admin
是管理后台的代码, var
是 Typecho 核心代码, usr
用于存放用户内容,譬如用户的主题位于 usr/themes
,插件位于 usr/plugins
,用户上传的文件位于 usr/uploads
。
二、安装 MySQL
自从有了 Docker,Linux 下的很多软件安装起来都变得非常轻松。比如安装 MySQL,可以用下面的一行命令就可以搞定:
sudo docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql:5.7
安装完成后,我们需要把刚刚备份的数据库导入到这个新数据库:
$ mysql -h 127.0.0.1 -uroot -p < typecho.sql
实际上还有更简单的一种方法,使用 Docker 运行 MySQL 时,可以在 /docker-entrypoint-initdb.d
目录下放一些初始化的脚本,可以是 shell,也可以是 sql,我们把刚刚备份的 typecho.sql 挂载到这个目录:
$ sudo docker run -d --name typecho-db -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=password \ -v ~/blog/mysql/init:/docker-entrypoint-initdb.d \ mysql:5.7
三、搭建 Nginx + PHP-FPM
接下来我们搭建 Web 服务器,这包括两个部分:Nginx 和 PHP。
3.1 安装 PHP-FPM
首先我们安装 PHP,官方提供了几种不同类型的镜像,根据 tag 的名称来进行区分,比如: php-<version>-cli
、 php-<version>-apache
、 php-<version>-fpm
等,如果你使用的 Web 服务器是 Apache,可以直接使用 php-apache
,这里由于我使用的是 Nginx,所以选择安装 php-fpm
:
sudo docker run -d --name typecho-php -p 9000:9000 \ -v ~/blog/websites:/var/www/html \ php:7.2-fpm
FPM 是 PHP 的 FastCGI 进程管理器,一般来说,以 CGI 的方式来运行 PHP 有几种比较常见的方式,比如:CGI、FastCGI、PHP-FPM,关于这几个的区别,可以参考 这里 。PHP-FPM 默认监听 9000 端口,接受 Nginx 转发过来的 CGI 请求,下面我们就来配置 Nginx。
这里挂载了 /var/www/html
目录,是为了 PHP 程序找到要执行的脚本文件,下面的 Nginx 镜像也会挂载这个目录,但是目的是完全不一样的。
3.2 安装 Nginx
Nginx 使用下面的 Docker 命令安装:
sudo docker run -d --name typecho-nginx -p 80:80 -p 443:443 \ -v ~/blog/nginx/conf:/etc/nginx/conf.d \ -v ~/blog/websites:/var/www/html \ nginx
Nginx 默认的配置文件里有几行被注释掉的代码,是配置 PHP FastCGI 的一个简单例子,如下:
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #}
但是拿这个例子直接跑 Typecho 会报 File Not Found
错误,根据 Typecho 的 官方文档 服务器环境设置 ,我们还需要加上 SCRIPT_NAME
和 PATH_INFO
这两个 FastCGI 参数。另外,如果你的博客开启了伪静态,还要加一条 rewrite 规则对所有的请求进行转发。下面是完整的配置:
server { listen 80; server_name www.aneasystone.com; root /var/www/html; location / { index index.php index.html index.htm; } if (!-e $request_filename) { rewrite ^(.*)$ /index.php$1 last; } location ~ \.php(\/.*)*$ { fastcgi_pass 172.17.0.1:9000; set $path_info ""; set $real_script_name $fastcgi_script_name; if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { set $real_script_name $1; set $path_info $2; } fastcgi_param SCRIPT_FILENAME $document_root$real_script_name; fastcgi_param SCRIPT_NAME $real_script_name; fastcgi_param PATH_INFO $path_info; fastcgi_index index.php; include fastcgi_params; } }
正如上文所述,Nginx 镜像和 PHP 镜像在运行时,都挂载了 /var/www/html
目录。这其实是为了支持 Typecho 的伪静态配置,我们通过 !-e $request_filename
来判断要访问的文件是否存在,如果不存在则 rewrite 到 index.php
,如果我们不挂载 /var/www/html
这个目录,则所有访问的路径都会不存在,直接触发重写规则,这样会导致 Typecho 的管理后台打不开。
3.3 遭遇 Database Server Error
Web 服务器搭建好了后,访问博客首页,发现报 500 错误,页面上直接显示大大的 “Database Server Error” 提示信息。我们打开 Typecho 的调试模式,在 config.inc.php 文件顶部加上一行代码:
define('__TYPECHO_DEBUG__', TRUE);
重新刷新页面,可以看到下面的错误详情:
Adapter Typecho_Db_Adapter_Mysql is not available
Typecho_Db_Exception: Adapter Typecho_Db_Adapter_Mysql is not available in /var/www/html/var/Typecho/Db.php:123
Stack trace:
#0 /var/www/html/config.inc.php(57): Typecho_Db->__construct('Typecho_Db_Adap...', 'typecho_')
#1 /var/www/html/index.php(11): include_once('/var/www/html/c...')
#2 {main}
发现是找不到数据库适配器 Mysql,Google 之后发现 PHP 7 以后的版本已经去除了 Mysql 扩展,推荐使用 PDO,我们修改 config.inc.php 文件中定义 Typecho_Db 的地方,将 Mysql
改为 Pdo_Mysql
:
$db = new Typecho_Db('Pdo_Mysql', 'typecho_');
重新刷新页面,发现错误还是没变:
Adapter Typecho_Db_Adapter_Pdo_Mysql is not available
使用 phpinfo()
查看 PHP 信息,发现只有 sqlite 这个 PDO driver:
才知道这是因为官方的 PHP 镜像里默认情况下并没有安装 pdo_mysql
这个扩展,可以使用 docker-php-ext-install
来安装,安装好后,要重启 PHP 重新加载扩展:
aneasystone@little-stone:~/blog/websites$ sudo docker exec -it typecho-php bash root@42633b997f8b:/var/www/html# docker-php-ext-install pdo pdo_mysql aneasystone@little-stone:~/blog/websites$ sudo docker restart typecho-php
四、升级 Typecho
至此,博客已经基本上完成了迁移,接着又把 Typecho 的版本升级了下。Typecho 1.1 正式版发布有 1 年多了,但我的版本还是 1.0,一直怕麻烦懒得升级,看着控制台的有新版本的提醒,都已经习惯性的无视了。这次趁着博客迁移,顺便升级下,才发现升级简单的很。
首先从 Typecho 的下载页面 下载 Typecho 1.1 正式版 ,然后按照 官方的升级步骤 先备份 /admin/、/var/、/index.php、/install.php 这几个文件,要注意 /usr/ 目录不用动,正如上面提到的,这个目录下保存着用户自己的一些文件,包括主题,插件和上传的文件。然后解压下载的最新版本,将相应的几个文件和目录拷贝到 websites 目录。
这时 Typecho 的前台页面还可以照常访问,没有任何变化。不过访问管理后台时,可以看到检测到新版本的提醒:
我们点击 “完成升级” 按钮就升级成功了。可以看出 Typecho 的升级和插件、主题的安装一样,都还是手工操作的方式,如果能做一个管理的功能,那多好啊。
五、支持 HTTPS
HTTPS 早就已经是主流,譬如百度早在 2014 年就已经主持全站 HTTPS,而且谷歌的 Chrome 浏览器从 Version 68 开始,将对所有 HTTP 网站显示 “不安全” 的警告,所以用最新版的浏览器访问我的博客,左上角都能看到 “不安全” 的字样,这让人很不舒服,于是决定也投入到 HTTPS 的怀抱中来。
关于 HTTPS 相关的概念,我之前有一篇博客《HTTPS 和 证书》做了详细的介绍,感兴趣的同学可以参考。要想让你的网站支持 HTTPS,你必须得有 SSL 安全证书,理论上我们自己也可以给自己签发证书,但是自己签发的证书,一般的浏览器都不会信任,所以我们要找证书授权中心,也就是所谓的 CA 来签发证书。在以前,签发 SSL 安全证书都是由一些比较大型的 CA 机构,比如 GeoTrust、GlobalSign 等来提供服务,而通常证书签发服务价格都比较昂贵,不过从 2015 年开始,情况有所改观,在这一年,EEF 电子前哨基金会、 Mozilla 基金会和美国密歇根大学成立了一个公益组织叫 ISRG (Internet Security Research Group) ,他们推出了 Let’s Encrypt 免费证书。
根据你是否有访问 Web 服务器上 Shell 的权限,有两种方式来获取 Let’s Encrypt 证书,一种是使用官方推出的 ACME 客户端 Certbot ,它可以通过 ACME 协议 自动从 Let’s Encrypt CA 获取证书,另一种是使用主机供应商提供的服务,或者使用 Certbot 的手工模式生成证书,再上传到服务器上。很显然,第一种方式是最简单的。
访问 Certbot 的首页,选择你使用的软件(Apache、Nginx、Haproxy 等)以及你使用的操作系统,Certbot 暂时只支持 UNIX-like 类的操作系统,不支持 Windows,所以如果你的 Web 服务器是 Windows Server,可能要使用 其他的 ACME 客户端 ,比如 acme.sh 脚本 就支持 Windows(cygwin)。我这里选择 Nginx + Ubuntu 14.04 (trusty):
下面会显示相应的操作步骤:
$ sudo certbot --nginx
这个命令使用了 Certbot 的 nginx 插件 ,它会自动获取证书,并且会自动修改你的 Nginx 配置文件,将证书自动设置好。当然,如果你不想让 Certbot 修改你的 Nginx 配置文件,可以加上 certonly
参数(官方将其称为 子命令 ):
$ sudo certbot --nginx certonly
其实,这个命令也会修改你的 Nginx 配置文件,它的执行流程如下:
- 临时修改 Nginx 配置,添加一个新的 server 块,用于处理 ACME Challenge( 详见 ACME 协议 )
- 重新启动 Nginx
- 回滚相应的配置改动
- 再次重新启动 Nginx
如果你对这个流程还是不放心,不想让 Certbot 动你的 Nginx,或者像我这里遇到的场景一样,Nginx 运行在 Docker 容器里,而 Certbot 运行在宿主机里,Certbot 没法自动重启 Nginx,那么可以选择使用 webroot 插件 :
$ sudo certbot certonly --webroot -w /var/www/html -d www.aneasystone.com
这个命令会在 Web 根目录创建一个 /.well-known/acme-challenge
文件,Let’s Encrypt 通过域名来请求这个文件,以此来验证你对该域名所对应的主机是否拥有权限。如果一切顺利,根据屏幕上的提示操作即可,最终看到下面这样的提示就说明证书获取成功了。
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/www.aneasystone.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/www.aneasystone.com/privkey.pem Your cert will expire on 2019-04-04. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
最终生成的 SSL 证书位于 /etc/letsencrypt/live/www.aneasystone.com/
目录,我们修改 Nginx 的启动命令,将该目录挂载到 Docker 容器里:
sudo docker run -d --name typecho-nginx -p 80:80 -p 443:443 \ -v ~/blog/nginx/conf:/etc/nginx/conf.d \ -v /etc/letsencrypt:/etc/letsencrypt \ -v ~/blog/websites:/var/www/html \ nginx
然后修改 Nginx 的配置文件,将之前的 listen 80
改为 listen 443 ssl
,再手动加上证书的配置:
listen 443 ssl; ssl_certificate /etc/letsencrypt/live/www.aneasystone.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.aneasystone.com/privkey.pem;
最后,将 listen 80
放在一个新的 server 块,直接将 http 的请求重定向到 https 地址:
server { listen 80; server_name www.aneasystone.com; return 301 https://$server_name$request_uri; }
至此,访问博客首页,发现自动跳转到 https://www.aneasystone.com 了。正在兴奋之余,还以为大功告成,却突然发现,博客上的菜单按钮点不动,F12 查看了下,才发现很多 js 和 css 报错,这是由于这些静态资源引用的是 HTTP 地址,在 HTTPS 站点引用 HTTP 资源,浏览器会直接 BLOCK 掉,所以还需要去插件和主题目录去修改所有用到的 HTTP 链接,改成 HTTPS 即可。
折腾到这里,是时候收工了。
不过对于 Certbot,还有很多东西可以学习,譬如它还支持其他的一些插件:apache、nginx、standalone、manual、webroot 等,如果你要申请泛域名证书(a wildcard certificate),还要使用 DNS 插件 。下面是 Certbot 支持的插件列表:
另外,如果对 Certbot 的原理感兴趣,还可以了解下 ACME 协议 。
参考
- Typecho Official Site
- mysql - Docker Hub
- php - Docker Hub
- nginx - Docker Hub
- Docker Hub MySQL官方镜像实现首次启动后初始化库表 | Ember
- 服务器环境设置 - Typecho Docs
- Typecho博客升级导致Database Server Error - 平凡之路 -- Lester You's Blog
- HTTPS 简介及使用官方工具 Certbot 配置 Let’s Encrypt SSL 安全证书详细教程
- User Guide — Certbot 0.29.0.dev0 documentation
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。