环境介绍

资源 说明
centos v7.9
docker 快速部署项目环境(18.06.3-ce)
nginx 反向代理,同时配置https证书(1.19.8)
halo v1.4.2,开源博客项目
Let’s Encrypt 免费证书 配置https

|

演示:

前置环境安装

Docker安装

参考:

https://www.yuque.com/docs/share/aec0f2f6-cb67-40dc-bf51-709dcf875314?# 《docker -安装》

halo安装

准备halo配置文件

  1. # 下载配置文件到 /home/halo/.halo 目录
  2. curl -o /home/halo/.halo/application1.yaml --create-dirs https://dl.halo.run/config/application-template.yaml

修改配置文件,数据库默认是h2,可以将数据库调整为mysql

如果选择了MySQL
则需要提前在mysql建立数据库 halodb:

MySQL安装

参考:https://www.yuque.com/docs/share/82c888b8-404f-44cf-aee0-651bffc76318?# 《docker -mysql 安装》

启动:
  1. docker run -d -p 3306:3306 --name mysql \
  2. -e MYSQL_ROOT_PASSWORD=123456 \
  3. -v /home/mysql/data:/var/lib/mysql \
  4. mysql:5.7

在启动halo之前需要手动创建数据库
创建语句:

  1. create database halodb character set utf8mb4 collate utf8mb4_bin;

相关的数据库表halo会自动生成,如果mysql 和 halo都是容器创建的,这里配置的mysql-ip应该是mysql容器内部的ip。

  1. # 查看mysql容器的ip,mysql-prod替换成mysql容器名称或者容器id
  2. docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql

最终配置:

  1. server:
  2. port: 8090
  3. compression:
  4. enabled: false
  5. spring:
  6. datasource:
  7. # MySQL database configuration.
  8. driver-class-name: com.mysql.cj.jdbc.Driver
  9. url: jdbc:mysql://172.17.0.2:3306/halodb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  10. username: root
  11. password: 123456
  12. halo:
  13. # Your admin client path is https://your-domain/{admin-path}
  14. admin-path: admin
  15. # memory or level
  16. cache: memory

image.gif

下载并安装halo

  1. # 拉取halo镜像
  2. docker pull halohub/halo

启动halo

  1. # 运行halo
  2. # --rm 停止即删除,不能和restart命令合用
  3. # -it 开启输入功能并连接伪终端
  4. # -d 后台运行容器
  5. # -p 8090:8090 指定宿主机端口与容器端口映射
  6. # -v /home/halo/.halo:/root/.halo 挂载halo配置文件,目录地址为我们在上一步下载了配置文件在宿主机的路径/home/halo/.halo
  7. # --restart 建议设置为 always,在 Docker 启动的时候自动启动 Halo 容器。
  8. #启动命令
  9. docker run -it -d --name halo -p 8090:8090 -v /home/.halo:/root/.halo halohub/halo

配置halo

## 查看容器状态,确认halo是否启动成功,如果启动失败需要检查下数据库连接(数据库一定要先启动)
docker ps -a

# 配置防火墙
# 开放8090端口
firewall-cmd --permanent --add-port=8090/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload

注意,阿里云需要同时配置安全组端口

image.gif# 阿里云配置安全组
image.png

image.png

image.png

容器启动完毕,我们现在配置一个nginx进行代理

nginx反向代理

安装

# 下载nginx镜像
docker pull nginx

# 启动nginx
docker run -p 80:80 --name nginx -d nginx

自定义配置启动

拷贝配置文件

docker container cp nginx:/etc/nginx /home/

配置

# 移除我们刚创建的nginx容器,重新以宿主机配置目录启动
docker stop nginx && docker rm nginx

# 编辑default.conf 文件,默认转发到halo端口,ip地址为服务器私网ip
 location / {
     proxy_pass http://ip:8090;
 }
# 启动nginx
docker run -p 80:80 --name nginx \
-v /home/nginx/conf.d:/etc/nginx/conf.d \
-v /home/nginx/logs:/var/log/nginx \
-d nginx

# 配置防火墙,注意,阿里云需要同时配置安全组80端口
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
# 到这里,我们可以通过ip访问halo了

使用ip:端口进行访问
image.png

到这一步如果不能使用ip直接访问,
首先确定halo启动成功没,
然后查看nginx配置是否正确,
最后再检查防火墙和安全组。

防火墙参考:
https://www.yuque.com/docs/share/e5f86bc7-6da3-4fef-9f17-5211c08cbddc?# 《开放端口&防火墙》

域名及网站备案

目前我们只能通过ip访问halo,我们可以通过配置域名进行访问。
首先我们得申请一个域名:

https://wanwang.aliyun.com/domain

申请完成后进行备案:

https://beian.aliyun.com/

备案注意事项:

  • 如果处于异地工作的情况,建议备案地点选择老家,而且手上要有老家的手机号,如果选择异地的话,需要你提供临时居住证之类比较麻烦。
  • 阿里云备案时间在一周左右,一般提交申请会有人找你确认信息,之后按备案流程走就行了。

    配置https

    一般情况证书是需要购买的,但是也有一些平台提供了免费证书,阿里云也有一年的免费证书,但是阿里云证书只能单个域名使用,
    如果要通配符证书是需要付费的。而Let’s Encrypt 证书即可以免费申请证书,又支持通配符,是个人开发者的上选。
    这里我们通过github项目配置免费证书(也可以手动安装,不过自动安装比较方便,下面两种方式都会提到):
    **letencrypt-certbot:**`` https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
    使用此项目前我们配置一下前置环境:certbot 和 git

    安装git

    yum install git
    

    安装certbot

    ```bash

    安装certbot

    yum install epel-release yum install certbot

查看版本,如果安装正常会显示版本号

certbot —version

<a name="62KB1"></a>
### 申请证书
特别注意的是,这里需要主机把80端口和443端口开放,上面我们已经开放了80端口,这里开放443端口就行了
```bash
# 配置防火墙,注意,阿里云需要同时配置安全组443端口
# 开放443端口
firewall-cmd --permanent --add-port=443/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload

重要提示:为避免遇到操作次数的限制,加入 dry-run 参数,可以避免操作限制,等执行无误后,再进行真实的 renew 操作

手动安装证书+手动续期

# 申请证书,需要填入你的邮箱和域名, --dry-run 测试使用不会生成证书,我们先用这个命令看是否成功
certbot certonly --email 你的邮箱@qq.com -d *.域名.cn -d 域名 --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory --dry-run
# 如果没有错误信息,去掉--dry-run真正生成证书
certbot certonly --email 你的邮箱@qq.com -d *.域名.cn -d 域名 --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
# 手动续期
certbot renew

安装过程中,需要确认选项,讲一下手动安装的重点:
image.png
image.png
安装成功后显示:
image.png

注意:证书90天后过期,我们手动续期的话比较麻烦,而且每次需要手动去DNS解析列表创建对应的记录,所以推荐下面的自动续期方式

通过apikey 和secret生成证书+自动续期

首先获取AccessKey ID及AccessKey Secret?

https://help.aliyun.com/knowledge_detail/38738.html

这种方式其实是利用你开放的api key调用阿里云提供的接口,所以保险起见我们创建一个权限很小的用户就行了。
流程:

  • 为了安全,我们需要先创建RAM用户,配置一个权限小的用户;
  • 给新创建的用户配置 AliyunDNSFullAccess(管理云解析(DNS)) 的权限;
  • 获取id和 secret。

    AccessKey ID LTAI5tC6xQdGveLi3zxjSzrz AccessKey Secret 8z3IWbwqgiD4Rux8v9x10ARw0D23q3

# 新建一个目标,拉取项目
mkdir /home/certbot
cd /home/certbot
git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
mv certbot-letencrypt-wildcardcertificates-alydns-au certbot-letencrypt
cd certbot-letencrypt
chmod 0777 au.sh

# 编辑au.sh,加入我们上面申请的key
vi au.sh
#填写阿里云的AccessKey ID及AccessKey Secret
ALY_KEY=""
ALY_TOKEN=""

# 运行命令,加上--dry-run 测试,如果没问题去掉 --dry-run 执行
#脚本目录就是我们上面创建的 /home/certbot-letencrypt
certbot certonly  -d *.zukxupu.xyz -d zukxupu.xyz --manual --preferred-challenges dns-01 --email zukxu520@163.com  --manual-auth-hook "/home/certbot-letencrypt/au.sh python aly add" --manual-cleanup-hook "/home/certbot-letencrypt/au.sh python aly clean" --dry-run

# 配置自动续期,使用crontab实现
vi /etc/crontab
# 加入以下命令,这个命令就是每周执行一次脚本,如果需要续期就会自动更新
0 0 * * 0 root certbot renew --manual --preferred-challenges dns --deploy-hook  "docker restart nginx" --manual-auth-hook "/home/certbot-letencrypt/au.sh python aly add" --manual-cleanup-hook "/home/certbot-letencrypt/au.sh python aly clean" --manual-public-ip-logging-ok;

到这一步我们证书生成成功了,
同样存放在 /etc/letsencrypt/live/zukxupu.xyz/ 目录,注意这里的文件是软链接,
我们实际上的文件在 etc/letsencrypt/archive/zukxupu.xyz 目录

image.png

nginx配置SSL证书

证书签发之后,会存放到/etc/letsencrypt目录中,刚才我们映射了数据卷,因此可以直接从宿主机中看到这个目录中的内容,其中证书位于/etc/letsencrypt/live/your.domain1.com中。接下来需要让nginx容器也能够读取这些证书,方法放简单,把这个目录映射给nginx容器就可以了:

但是我们的nginx容器内部是没有这些文件的,而且每次重启nginx容器,映射的数据都会消失,所以我们可以将ssl证书存到nginx映射目录下面

#将ssl证书文件复制到nginx映射目录下
/etc/letsencrypt/live/your.domain1.com
cp 证书到 /home/nginx/conf.d/cert

/etc/letsencrypt/live/your.domain1.com
cp /etc/letsencrypt/archive/zukxupu.xyz/ /home/nginx/conf.d/cert/ -r

接下来我们在nginx 的配置文件里把证书配上去:

upstream halo_server {
  server 172.31.252.224:8090;
}

server {
  listen 80;
  server_name zukxupu.xyz www.zukxupu.xyz;
  client_max_body_size 1024m;
  #把http的域名请求转成https
  rewrite ^(.*)$ https://$host$1 permanent;
}
#配置ssl证书
server {
    listen 443 ssl;
    client_max_body_size 1024m;
    server_name zukxupu.xyz www.zukxupu.xyz;

    ssl_certificate conf.d/cert/fullchain1.pem;
    ssl_certificate_key conf.d/cert/privkey1.pem;
    ssl_session_timeout 5m;    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;    

    location / {

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

    proxy_pass http://halo_server;    
    }
}

最终nginx运行命令

注意:将上面zukxupu.xyz相关的路径换成你的域名路径。

# 为了让nginx能访问到我们刚生成的证书,需要重新挂载证书路径到nginx
docker stop nginx && docker rm nginx

# 运行nginx,此处加入了443端口和证书路径
docker run -p 80:80 -p 443:443 --name nginx -v /home/nginx/logs:/var/log/nginx -v /home/nginx/conf.d:/etc/nginx/conf.d -d nginx

此时我们就可以通过https域名访问项目了,而且这个时候也可以新建二级域名访问项目的(二级域名同样是https)。
注意:此时会发现博客的样式文件没有加载,这是因为站点是通过HTTPS进行访问,只需要将样式文件也设置成为HTTPS访问即可

输入https://www.域名即可访问网站

  • 进入后台-》系统-》博客设置-》博客地址
  • 修改为HTTPS访问即可

image.png

总结

实际部署过程中遇到很多问题,比如项目访问不了、https证书失败等。本篇文章是经过实践后得出的流程,如果中间有碰到问题可以在下方评论我们可以一起解决。

附录:

申请二级域名

这里申请域名仅针对在阿里云购买的域名。
从域名解析列表加入需要使用的二级域名:

我们在域名解析中添加了一个temp.zukxupu.xyz的二级域名,指向域名 zukxupu.xyz 的地址,这时候通过temp.zukxupu.xyz 访问是失败的,原因是需要等待网络服务商刷新DNS地址,一般需要等等1-2分钟。

配置二级域名

此时我们访问访问temp.zukxupu.xyz会默认跳转到 www.zukxupu.xyz 首页。为了方便测试,我们需要针对temp.zukxupu.xyz 配置访问nginx默认页面。

vi default.conf
# 在末尾追加以下脚本
server {
   listen 443 ssl;
   server_name temp.zukxupu.xyz;
   location / {
     # 改为你想代理的应用
     # 注意这里要使用机器的ip,不能用127.0.0.1,机器ip使用命令 ip addr 查看
      proxy_pass http://ip:端口;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {                #重定向错误页面到 /50x.html
        root   /usr/share/nginx/html;
    }

}

nginx域名解析配置【halo官方】

upstream halo {
  server 127.0.0.1:8090;
}
server {
  listen 80;
  listen [::]:80;
  server_name www.zukxupu.xyz;
  client_max_body_size 1024m;
  location / {
    proxy_pass http://halo;
    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;
  }
}