历时三天,我终于把这个属于自己的博客网站搭建好了(可能还没有),也可以说说我在这些时间内踩的坑。。

从头开始搭建博客的话,我一开始计划是下面这样的:

  1. 服务器购买并配置

  2. 博客的搭建

  3. CDN加速

计划是简单的,理想是丰满的,现实是骨感的,先说说如何搭建博客,再说说踩的坑吧。

一、服务器和docker的配置

1.1 购买服务器和连接服务器

服务器因为我懒得备案,所以一开始的选择就是海外服务器,又正好看到现在用的这台,16.5刀一年,2C1G 1Gbps带宽还蛮便宜的(什么?你拿流量肉机搭博客?),就选了这台,服务商是cloudcone,服务器位于洛杉矶(所以访问延迟有点高)。

配置直接用XShell连接SSH,很顺利,然后就是进入无尽的配置

我居然才发现XShell免费了,我还用了三年的XShell6的破解版,诶。。

还有就是cloudcone这家服务器的SSH密码很神奇,只会显示一次,而且密码是随机的好像不能自定义,忘记了就只能再从后台随机一个,所以记得保存好密码!

如果你选择了阿里云等国内的服务器,我可以先跟你说一下几个问题:

  1. 如果需要通过域名访问,则域名需要备案,网站也需要备案,但你有耐心走完备案的话,可以享受国内不定期免费的CDN加速服务器;

  2. 如果选择不备案只使用IP访问,那么你的网页速度只能受限于服务器的带宽(国内服务器的带宽真的是小的可怜);

1.2 安装并使用宝塔面板作为控制后台

宝塔官方安装页面:点击这里

这里选择的系统是Ubuntu,所以理所当然的使用了下面的命令(可能会失效,请直接去上面的链接获取最新的脚本):

wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh ed8484bec

在等待一段时间后会出现以下的信息,记得保存好,没保存好也可使用bt default再次显示

通过提供的面板地址进入宝塔的后台,输入提供的初始的username和password就能进入后台面板了。

当然如果你实在不想记这一大串乱码,也可以自己修改,在使用bt可以查看可供修改的选项,在这里我们先选择5再选择6,然后根据提示重新定义用户名和密码就可以了。

进入宝塔后台后,宝塔会让你安装初始套件,因为我们直接用的Docker搭建,所以暂时不需要这些(后面配置HTTPS的时候会需要Nginx),所以我们直接关掉,然后在左侧点击docker,根据提示安装docker服务,这里就不做图展示了。

Tip1:宝塔提示使用HTTPS访问和域名绑定,我们暂时先不绑定

Tip2:如果已经绑定了也可以在ssh使用bt指令来取消绑定

1.3 安装Docker 导入Docker镜像

然后就是配置Docker,这里选择了Halo博客的Docker,

Halo博客官方文档:点击这里

使用的Docker镜像:点击这里

我们回到SSH然后根据官方文档提供的 Docker配置 方法创建容器,对指令进行一个复制的粘贴。

docker run -it -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.10

等待拉取完成后,刷新宝塔的 docker->容器 界面就能看到一个全新拉取的容器,容器名为 "halo"。

图片请忽略其他容器,都是其他其他网站的,也可能后面会讲

到这里其实已经可以访问博客了,在前面的指令中,我们把docker的端口映射到了公网的8090端口,直接使用 XXX.XXX.XXX.XXX:8090XXX替换为你的IP地址,就可以访问了。后面根据提示配置博客后台的初始账号,最基础的博客配置就已经完成啦!

如果只是自己搭着玩玩或者自己用,此时此刻已经完全够用了,但是如果你打算分享给别人,那肯定是需要更好的访问方法,那就是通过域名访问!

二、绑定域名

2.1 域名购买/申请 添加解析

域名博主是很早就在阿里云购买的,国内购买域名需要实名并且备案,当然也有免费的域名网站可以用,不过海外的免费域名DNS无法更改,所以有时候会出现DNS污染无法访问域名的问题;

阿里云域名申请与购买:点击这里

Freenom域名申请(免费):点击这里

这里以阿里云为参考,只需要去解析里添加一个子域名并且解析到服务器IP就行了

当你添加好解析后就可以通过 域名:8090 来访问博客了!

2.2 使用域名默认访问网页

最简单的解决方法就是直接把docker容器的映射端口直接改成80,这样直接访问域名的时候就可以直接进入博客了。

如何修改docker的映射端口,博主是参考了这篇文章,这里也会讲一讲如何修改。

我们这里需要使用SSH和宝塔面板的文件管理界面来修改

首先我们在SSH输入 docker ps 我们需要记住halo这个容器前面的ID

打开宝塔的docker页面->设置->停止

然后打开宝塔面板内的文件管理,进入以下路径

/var/lib/docker/containers/

如果是跟着本篇博客的小伙伴,这里应该是只有一个文件夹的,如果有多个docker,可以根据上面获取的ID来判断是哪个文件夹,如博主这里所示的是0C98cc3841c1 ,我们直接进入这个文件夹。

然后找到 hostconfig.json 文件,双击编辑

我们找到 PortBindings这一行参数,把前面的8090改成80

然后回到之前停止docker的页面,启动docker服务,启动halo的docker容器

这个时候我们已经完成了最基础的HTTP访问,可以通过域名直接访问网页了。

到这里已经足够使用了,不过咱还要更进一步

如果要继续,我们需要把 PortBindings这一行参数替换成null

三、使用HTTPS加密访问

3.1 SSL证书的申请

一般在购买域名的服务网站都会有免费的SSL证书可以下载,证书与域名绑定,这里以阿里云为例:

我们在阿里云控制台搜索 数字证书管理服务 ->SSL证书->免费证书->创建证书

然后根据提示进行实名和域名信息的填写验证

申请通过后我们点击下载

下载Nginx格式的证书格式

至此我们已经完成了证书的申请和SSL证书的获取

然后我们通过宝塔的文件管理把SSL证书上传到服务器内,然后记录证书与秘钥的位置

例如我把证书放到了服务器根目录下的ssl文件夹,所以看起来就是这样的

3.2 Nginx的安装

为了能够验证SSL证书,我们需要Nginx的帮助。

回到宝塔面板 点击左侧的软件商店->搜索Nginx->安装

安装完成后可以打开 首页显示的选项,这样可以在首页更方便的进入

3.3 Nginx的重定向配置

为了映射,我们还需要知道docker容器的ip地址,点击docker页面

我们记下这个ip地址 如图上是 172.17.0.2

打开Nignx的设置页面,点击配置修改

我们在倒数第二行的 include上面,添加如下的代码:

server 
  {
    listen 443 ssl;
    server_name localhost;
    
    ssl_certificate /ssl/blog.iloli.shop.pem;
    ssl_certificate_key /ssl/blog.iloli.shop.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on; 

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://172.17.0.2:8090/;
    }
  }

在这里我们只需要注意三个需要修改的位置

ssl_certificate:SSL证书路径 如/ssl/blog.iloli.shop.pem

ssl_certificate_key :SSL证书秘钥路径 如/ssl/blog.iloli.shop.key

proxy_pass:docker的内网访问链接 如http://172.17.0.2:8090/

因为docker内网的访问是不包含HTTPS的,所以一定要是http,后面的ip替换为上面记录的docker容器的ip;8090为Halo博客的端口

保存后重启Nginx服务,使用https://访问域名就可以使用加密连接了!

不过细心的人会发现,如果直接输入域名会自动打开另一个空白的网页

所以我们还需要重定向 80 端口到443

也是打开Nginx配置文件

我们在前面找到 以下内容:

server 
  {
    listen 80;
	<...后面省略...>
}

我们把这一段内容替换为

server 
  {
    listen 80;
    server_name localhost;

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_pass https://127.0.0.1:443/;
    }
}

这样就可以把http重定向到https了。

四、多docker容器的端口重定向

当拥有了多个docker后,我们就要解决访问的问题了,直接映射到主机端口容易被直接IP访问,所以还是要通过https,而每次添加一个端口就需要到Nginx配置文件里面添加一个重定向。

4.1 获取docker容器的ip以及端口

ssh内使用指令

docker ps 

可以在PORTS看到每个docker中使用的端口,记下这里所需要的docker容器的端口

在宝塔的docker页面内可以看到容器的ip地址

然后将需要的docker容器ip与端口对应,并记录

如172.17.0.2:8090、172.17.0.3:8000

4.2 Nginx添加重定向配置

打开Nginx配置文件并添加以下代码

server 
  {
    listen XXXX ssl;
    server_name localhost;
    
    ssl_certificate /ssl/blog.iloli.shop.pem;
    ssl_certificate_key /ssl/blog.iloli.shop.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on; 

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://AAA.AAA.AAA.AAA:XXXX/;
    }
  }

其中XXXX替换成自己的docker容器端口号,AAA则是容器的内网ip地址,例如

server 
  {
    listen 8000 ssl;
    server_name localhost;
    
    ssl_certificate /ssl/blog.iloli.shop.pem;
    ssl_certificate_key /ssl/blog.iloli.shop.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on; 

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://172.17.0.3:8000/;
    }
  }

这样就把8000端口映射到了域名上,然后通过 https://域名:端口 就可以访问了!

五、CDN加速服务器

这一部分着实踩了坑,后面会好好捞一捞,咱们先正常过一遍

5.1 CDN服务器的选择

CDN服务器分国内外,如果有打算使用国内服务器备案网页的可以使用国内的CDN服务器,速度很快,而且各大厂商也有免费的流量。

国内CDN服务商推荐:

以上国内CDN服务器除了阿里云均有新用户免费1年的流量,可以考虑选择使用,并且流量付费也不贵,对于个人博客来说是完全够用的。

如果你像我一样不喜欢备案,并且把服务器架在境外,可以跟我一样选择境外的CDN服务器

国外CDN服务商推荐:

以上两种均有免费服务,其中Amazon CloudFront是支持自己上传SSL证书的,而Cloudflare如果需要上传自己的证书则需要购买200$的商业版(太贵啦)

如果没有申请SSL证书,Cloudflare支持将http单向加密为https,也就是数据从客户到CDN服务器这一段是采用https加密的,而Cloudflare到服务器这一段依旧是http

Cloudflare的使用需要将DNS解析一起改过去,容易遇到DNS污染,域名无法访问的情况,所以一般不推荐使用。所以本文使用Amazon CloudFront作为例子。

Amazon CloudFront在注册的时候需要visa信用卡进行验证!!!

5.2 申请多域名SSL证书

CloudFront的CDN代理方式与一般国内的CDN配置方式不太一样。

它是通过CloudFront提供的域名跳转到自己的域名,这个时候只能通过CloudFront提供的域名访问网站才有加速效果。流量的路径相当于:

xxx.cloudfront.net-->xxx2.iloli.shop

xxx2.iloli.shop-->(dns)-->ip-->服务器

若想要跟以前一样使用自己的域名访问,就需要再加一层解析两个域名同时使用:

xxx1.iloli.shop-->(dns)->xxx.cloudfront.net

xxx.cloudfront.net-->xxx2.iloli.shop

xxx2.iloli.shop-->(dns)-->ip-->服务器

同时SSL证书也需要同时包含以上的两个域名

这里使用阿里云作为示例会遇到以下的问题:

  1. 免费SSL证书只支持一次添加一个子域名

  2. 包含所有子域名的证书只有企业证书(贵)

但是SSL证书有一个除外,就是添加主域名,这个时候会自动包含www域名

这个时候申请的证书就包含了两个域名,iloli.shop和www.iloli.shop

这个时候就可以通过CloudFront继续我们的操作了

5.3 CloudFront托管SSL证书

CloudFront控制台搜索Certificate Manager 进入我们的证书页面,点击导入证书

根据本文3.1的流程下载证书文件,然后使用记事本打开pem文件和key文件.

把pem文件内的第一段复制到证书正文

其余的都复制到证书链

把key文件内所有文本复制到证书秘钥 ,最后大概如下图所示,点击下一步即可。

5.4 CloudFront配置

注册好账号后,我们来到CloudFront的控制台,点击创建分配

配置方法就按照下图选择,也会稍微解释一下作用

最后点击完成

然后返回详情就可以看到分配的域名

5.5 修改域名的DNS解析

在自己域名的DNS中添加以下两个解析:

  1. www 使用CNAME解析到CloudFront提供的加速域名xxx.cloudfront.net

  2. @ 使用A 解析到服务器IP地址

到这里我们已经完成了DNS服务器的架设,然后参考 第三章 的流程,我们把证书换成刚刚申请下来的新证书,若一开始证书就是包含子域名的,可以忽略。