用了一年多的各种笔记软件(notion、obsidian等),终于不像几年前个人建站的时候那样脑袋空空不知道在网站上发布些什么(也没多少能发出来的)。但随着了解的深入,越发觉得当时知道的仅仅只是皮毛,甚至可以说跟原始人差不多,各种照猫画虎稀里糊涂地就把网站搭好了,以至于今天都忘了当初是用哪种方法搭建的。
所以旧的东西先全部抛掉,积累了一定的linux基础和编程基础之后,相比于以前的毛坯房,真正的个人网站建好了。

前言

需求

将子域名”blog.xxx.xxx“绑定到服务器ip的端口,使wordpress博客可以使用“blog.xxx.xxx”地址直接访问
同时将使用ssl证书是网站加密,即在子域名前面自动添加“https:// ”,并且浏览器显示连接安全
image.png

前置

能够自行去其他地方学习搞定的,什么《三分钟极速部署wordpress》,当然,那些对纯小白来说还是很有门槛的。说是这么说,本教程写出来其实也是面向有一定计算机基础的人。

  1. 一台服务器:或者也可以自己在虚拟机上尝试部署网站到局域网
  2. 租域名:国内网站最好进行备案
  3. linux运行环境:腾讯云服务器或阿里云服务器都可,我使用的是腾讯的轻量级应用服务器,尽管它已经能用宝塔面板等镜像方便地部署项目,但为了拓展性,我选择用linux的centos镜像自己一步步搭建
  4. 域名解析:把个人域名www. xxx.xxx 和blog.xxx.xxx绑定到服务器的公网ip上
  5. ssl证书:腾讯云和阿里云都有ssl证书的免费申请额度,证书签发之后下载nginx格式的证书压缩包
  6. docker及进阶的docker-compose的安装与使用:如果已经有了一定的使用经验就更好了

步骤

一、使用docker-compose快速部署wordpress

1.在linux系统内装好docker和docker-compose之后,找一个地方开始我们的部署

mkdir /apps/wordpress
cd /apps/wordpress

2.使用vim命令修改yml文件

(没有vim命令可以使用vi,或者安装vim,操作linux不会用vim来修改文件简直寸步难行)
在这个目录下编写供docker-compose启动的文件:docker-compose.yml

vim docker-compose.yml

输入以上命令后跳转文件编辑界面
英文输入法下按i键左下角出现”--INSERT--“提示,代表进入输入状态(vim或者vi的具体使用可参考https://www.jianshu.com/p/f1fc65a245e2
复制以下内容粘贴到文件内,注意首尾是否完整如“version”变成“on”,以及缩进是否正确,yaml文件的缩进格式非常重要

version: '3.1'

services:
  wordpress:
    image: wordpress
    container_name: wordpress
    restart: always
    depends_on:
      - db
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wordpress:/var/www/html

  db:
    image: mysql:5.7
    container_name: wordpress_db
    ports:
      - 3306:3306
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_ROOT_PASSWORD: abc123
    volumes:
      - ./mysql:/var/lib/mysql

粘贴完成后,就按ESC键退出输入状态左下角“--INSERT--”消失
然后在英文输入法状态下输入":wq"(输入冒号的时候左下角有冒号出现)保存退出
image.png

3.运行docker-compose

在当前目录(docker-compose.yml所在的目录)下输入docker-compose up -d
经过下载镜像(国外网站)漫长的等待之后,部署镜像容器就很快了,这些完成后,就能通过服务器所在的ip访问wordpress网站
因为在上面的docker-compose.yml文件里,我们把wordpress容器的ports属性写为 - 8080:80
也就是说我们只要在浏览器输入 ip:8080就能跳转到自己的wordpress博客了(需要开启防火墙对应的端口)
凑合凑合这样其实也能用(在后面步骤无法完成的情况下)

二、域名重定向以及https加密

问题

  1. 只能使用“ip:端口号”或者“域名:端口号”来访问网页,和一般访问网站直接输入域名的习惯有区别
  2. 自动添加的是"http:// "而非“https:// ”,浏览器的地址栏前面显示连接不安全警告

思路

之前查过一些方法,要把端口映射到子域名,需要反向代理,就引入了nginx,也许有很多其他的软件同样也能够实现,但据我了解nginx的使用范围很广,说不定以后在折腾其他什么的时候就用到了。既然都是为了拓展性,那么就不用nginx的docker镜像,直接安装到服务器的系统里
如果单纯是把端口映射到子域名,现在回过头来看还挺简单,当然前提是把nginx的坑挨个踩一遍把路走熟
而在把端口映射到子域名之后,再添加ssl证书实现https加密,难度又成倍提升,牵扯到wordpress网站从https请求http的资源被拦截导致网站渲染不出来的问题image.png

实现步骤

1.安装nginx并初次运行

如果前面看了如何安装vim就知道linux有最为广泛使用的两个版本:centos和ubuntu,它们安装软件的命令(或者说工具)有所不同,centos用yum,ubuntu用apt或者apt-get,之后后面的参数就大差不差了。
输入命令yum -y install nginx来安装nginx,不加“-y”则会再询问是否安装,输入“y”表示确定安装,可能需要一些环境依赖,碰到坑的话可以看一下nginx安装及其配置详细教程
输入nginx -h如果有反应就表示nginx安装成功
image.png
图中圈出来的就是nginx默认的配置文件nginx.conf所在位置,后面我们要在这个文件路径上进行许多操作
输入nginx 开始运行,这时候访问这台服务器的ip就可以进入nginx设置的主页(下图为网图)

2.端口转发

可以发现这次在ip的后面没有加端口后却能访问,难道我们访问了这个ip所有的端口?其实不是,当访问ip不加端口号时,默认会访问这个ip的80端口,反过来,当访问ip的80端口时,地址栏会把端口号隐藏掉
nginx的默认配置文件暴露了服务器的80端口,并设置访问的位置是nginx默认的网页文件,这个文件经过浏览器渲染我们就看到了上面的这个网页
除了访问文件以外,nginx还能实现端口转发,即,当我们访问服务器的80端口时,自动跳转到我们的wordpress博客所在的8080端口,可以参考以下内容修改nginx的配置文件nginx.conf,同样使用vim或者vi

vim /etc/nginx/nginx.conf

nginx.conf内容如下,只需要修改http{}的花括号包裹下的server{},并将location / {}包裹下的proxy_pass修改为自己的wordpress博客所在的ip及端口号

# 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 4096;

    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.
    
   server {
         listen 80;
         location / {
	         proxy_pass xxx.xxx.xxx:8080;
         } 
    }
   include /etc/nginx/conf.d/*.conf;

}

修改完成后还是首先按ESC键退出输入状态,在输入":wq"保存退出
接着nginx -t检查nginx配置是否正确,出现ok和successfully字样就表示正确,
最后输入nginx -s reload向nginx发出重新加载配置的信号
成功之后,我们直接访问自己ip不需要端口号应该就能跳转到自己的wordpress博客

3.域名解析

这本来是前置里的第四条,但在这里再多作说明以作强调
域名解析是把我们的域名映射到我们的ip上,表现出来的作用就是完成域名解析之后,在浏览器输入的ip可以用域名代替,从ip:端口号域名:端口号
这时候观察我们的域名,发现其实只有xxx.xxx,而不是我们常见的“www.xxx.xxx” ,如 “www.baidu.com”
因为最前面www其实是域名的子域名,一个特殊的子域名
只不过www之于域名,正如上面说的80端口之于ip,“www.baidu.com” 指向的就是 “baidu.com”
image.png
所以在域名解析页面,可以看到在域名栏后面选择自己的域名之后,下面的主机名就需要在空格里填入需要的子域名,如这个个人博客的地址是“blog.yoake.top”,我在这里填的就是“blog”
当然按上面这张图里说法也可以填“@”,与填"www“的区别在于会少解析一个www.yoake.top ,因为填”www"其实会解析两个域名:www.yoake.top 和 yoake.top

4.指定域名访问

解析了域名之后,意味着域名和这台服务器的公网ip绑定了,但有一个问题,我们进行域名解析时通常会把多个域名解析到一个ip上,“一夫多妻”和“一妻多夫”甚至“群婚制”在“网络通信国家”这里是非常普遍的
怎么通过不同的域名访问这台服务器的不同服务(网页,信息之类的资源)?还是由nginx出场解决
在上面的nginx.conf配置文件中我们在server的花括号里写了listen(监听)和location(访问的位置),只要在它们二者之间再加上一个属性“server_name”(服务名),就能让服务器根据访问的域名匹配不同的sever{},匹配规则可以参考nginx配置:server_name的作用
把上面的server{}改成如下:

server {
         listen 80;
         server_name blog.yoake.top;
         location / {
	         proxy_pass xxx.xxx.xxx:8080;
         }
    }

保存退出后输入nginx -s reload重新载入配置,这时候在浏览器输入“blog.yoake.top”,就能匹配到这个服务
再访问一次一次wordpress的后台,把博客的地址从ip修改为域名
image.png
整个过程就像你拿着写有这个后宫中其中一个妻子的名字(子域名)的纸条找到这个丈夫(ip),然后丈夫知道你是这个妻子的朋友(至少你知道她的名字),就把这个妻子从家里找出来见你。
倘若我们在上面的server{}后面再加一个server{}并且在中间写上server_name www.yoake.top 并且指定了相应的要访问的资源,就可以在浏览器输入“www.yoake.top” 来访问

5. https加密

终于到了最后一个问题,在"blog.yoake.com"的前面,即我们填入的网址的前面,会有浏览器自动补充一个”http"或者“https”
“http"和”https“的区别是什么?那就是后者为前者的加密升级版。当网络请求是http时,意味着请求方和响应方传递的数据是明文的,第三方很轻易就能截持并看得到的。这在仅内网下进行数据传递其实无所谓,而个人博客属于在大外网中树了一个路标,如果不进行加密,所造成的安全问题不言而喻,所以当开头是http时,浏览器会红字提示“不安全“,这对一个网站来说当然不行,因此现在大多数的网站的都已完成接下来我们要做的这一步,虽然个人博客不会强求浏览量,但终究要把该做好的做好。
至于两者更多的区别,可以参考十分钟搞懂HTTP和HTTPS协议?
还是请出nginx来解决。
前面的我们已经用nginx把本台服务器的80端口直接转接到了wordpress所在的8080端口,现在要加密就需要在他们中间再加一个人:这个人通常是服务器ip的443端口,他负责把来自两端的数据加密。
所以我最后的nginx配置分为两server{}块:

  1. 监听80端口(listen),并根据的域名(server_name)进行匹配,最后重写请求(rewritre)变成https,这实际是将这个请求传递给了443端口
  2. 监听443端口并标示出是ssl(指前置里写的ssl证书),再匹配一次域名,然后开始加密过程,最后转接到8080端口,这就是我们安排好的访问的整个流程。

所以最后整个nginx.conf配置文件如下。加密这个过程除了在这之前讲得三个,还需要添加更多的配置属性,这里不一一介绍。
除了“server_name”外两个要改的地方是 “ssl_certificate”和“ssl_certificate_key”,后面分别填入ssl证书的四个文件中的.crt文件和.key文件在服务器中的路径
image.png
至于怎么把自己电脑上的文件传输到云服务器上?这里有怎么上传文件到腾讯云Linux服务器?,这里面前面的答案推荐了windows自带的scp命令,但操作会有点繁琐,而简化操作的则有xshell,finalshell(貌似看到有安全问题,虽然我斗胆尝试了一下,但不太敢多用)这些专门用来简化非图形界面计算机操作步骤的软件,如果实在完全不懂linux运维,可以选择它们来降低门槛

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 4096;

    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.
    server {
        listen   443 ssl;
        server_name  blog.yoake.top;
        ssl_certificate cert/blog.yoake.top_bundle.crt;
        ssl_certificate_key cert/blog.yoake.top.key;
        ssl_session_cache shared:SSL:1m;
        ssl_protocols  TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_session_timeout  10m;
        ssl_prefer_server_ciphers on;
        location / {
                proxy_pass  http://xxx.xxx.xxx.xxx:8080;
                proxy_redirect    off;
                proxy_set_header  Host $host;
                proxy_set_header  X-Real-IP $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header  X-Forwarded-Host $server_name;
                proxy_set_header  X-Forwarded-Proto https;
                add_header  Strict-Transport-Security "max-age=31536000";
                proxy_set_header  Upgrade $http_upgrade;
                proxy_set_header  Connection "upgrade";
                proxy_read_timeout 86400;
        }

   }
   server {
         listen 80;
         server_name  blog.yoake.top;
         rewrite ^(.*) https://$host$1 permanent;
    }
   include /etc/nginx/conf.d/*.conf;

}

查怎么配置https加密的时候看到了各种nginx的配置文件,在这个地方卡了许久,来来回回改了许多次终于解决,并让网站的安全评级达到最高的A+
但我还是要补充一句:折腾嘛,最后还是要自己学会一部分原先不知道的东西
image.png

后记

一些坑处理

  1. 清除浏览器的缓存

nginx.conf中创建另外的server{}时或者更换server{}里面的内容并且已经reload,但在本地的浏览器上访问,却一直跳转到原先的配置,这会让自己把正确的配置当成错误的配置从而把正确答案改错
这与浏览器本身存储了的跳转缓存有关,需要删除这些缓存,由于我也不确定那种方法有效,就把所知道的列出来:

方法1(推荐):按F12进入开发者模式,进入网络(Network)选项卡,找到在最上面的状态码为301或302的重定向请求,阻止请求URL(Block request url)或阻止请求域(Block request domain)
方法2:在浏览器地址栏的最前面,有个锁形的标志,点击之后再点击Cookie,跳出一个窗口然后在这个窗口把所有的Cookie删除
方法3:以上方法还是不行且自己也没有找到其他能解决的办法,要么在浏览器的设置里把数据全部清除,要么换一个浏览器
所以在整个过程中,用平时不常用的浏览器来测试是最好的,数据清除了不心疼
image.png
2. 待补充

总结

搭个人博客或者说个人网站,其实是可以用现实的比喻来理解的:
租ip,就是租地皮,ip的数字就是经纬度,也意味着别人可以根据ip定位你实际所处的方位——当然,在本文里,是云服务器所在的位置,云服务器相当于在这块地皮上建的一栋楼
设置端口,就是这栋楼里对应房间号的房间,每个房间具体的用途用楼的主人(也就是我们自己)来规定,但约定俗成了80号房间是大门(因为访问80端口可以省略),443类似于玄关起到一定防护作用等等,理论上楼里有65536-1个房间供户主来安排(房间号最大为65536,除去0)
租域名,就是广告位,它把记忆ip四段数字变成了记忆具有更明显规律的词语,从而有了更鲜明的记忆点(域名其他作用就不展开讲了)
域名备案,字面意思,不需要比喻
域名解析,就是向广告商登记,告知广告商广告位上广告的内容,当然,这个广告位放不了太多东西(毕竟就是一个域名),访问这个广告位之后,广告商把访问者带到背后所绑定的ip地址,果然还是个不太恰当的比喻......

因此访问一个网站的流程一般是这样的:访问者在网页上输入blog.yoake.top这个广告位,广告商把访问者带到我们的店铺,店铺的前台注意到访问者是访问blog.yoake.top来的,先经过玄关,然后把它带到博客所在的8080房间。

ok,就是这样,不知道有没有因为”知识的诅咒“而没有把一些复杂的东西讲明白。
至少怎么搭建是讲完了,后面怎么维护呢?目前没有想法写这方面的东西,一个原因是每个人有每个人的用法,自家的装修方案是给自己家的,并不适用其他人。