搭建halo教程
最近通过Halo搭建了个人的博客站,在这里做一下记录。Halo官网其实已经提供了非常全的部署方案,这里我采用的docker 的安装方式(不使用宝塔面板),使用Nginx容器去代理Halo容器,cloudflare去托管解析域名,acme自动更新证书。
为什么要用这些:
- 不使用宝塔面板,主要是宝塔本身就是一个比较大的软件,在一些小型的服务器上比较吃力。
- cloudflare可以有效的隐藏我们的真实IP,一定程度防止被攻击
- acme可以自动更新证书,不用手动更新,这样一次搭建后无需再关注服务器端
- 使用Nginx容器去代理Halo容器,这里的Nginx容器其实不止可以代理Halo的容器,后续所有容器都可以代理,实现https的访问(需要注意的是,cloudflare免费提供了https证书,但是,这是用户到cloudflare的连接是才用https方式,如果服务端没有使用https,那cloudflare到源服务器就不是https的方式连接了。相当于cloudflare去代理了用户的请求,然后再转发给源服务器的)
服务器的连接与配置
在开始之前,我们需要准备一下环境:
- 一台初始化的
centos7.8系统服务器(避免软件安装冲突) - 一个已经备案的域名(国内服务器域名需要备案)
修改默认端口:
连接服务器:
1 | ssh root@you ip |
修改端口,编辑sshd_config文件:
1 | vi /etc/ssh/sshd_config |
输入 i 编辑,把#去掉,把22改为想要的端口,最后:wq保存:
1 | Port 10024 |
然后需要执行这一句命令:(端口是刚才修改的端口)
1 | semanage port -a -t ssh_port_t -p tcp 10024 |
可能会得到一个错误,可以执行一下下面这句:
1 | yum whatprovides semanage |
1 | yum install -y policycoreutils-python |
最后再重新执行:
1 | semanage port -a -t ssh_port_t -p tcp 10024 |
查看SSH运行的端口:(不是必须执行)
1 | semanage port -l | grep ssh |
删除SSH端口:(不是必须执行)
1 | semanage port -d -t ssh_port_t -p tcp 22 |
重启SSH:
1 | service sshd restart |
重新连接服务器:(端口是刚才的端口)
1 | ssh -p 10024 root@your ip |
密钥方式连接服务器:
在本地电脑生成SSH Key,一直回车就可以:
1 | ssh-keygen |
在本地路径C:\Users\你的用户\.ssh下创建config文件:
1 | Host Test |
服务器cd ~/.ssh/目录,(一定要CD到这个目录,切勿直接在根目录直接使用下面命令,会导致这个文件不生效)编辑文件,到本地C:\Users\你的用户名\.ssh 找到公钥文件,把本地电脑的公钥文件id_rsa.pub复制进去,:wq保存:
1 | vi authorized_keys |
如果之前连接过服务器,格式化后再连接可能报错,可以先删除本地电脑这两个文件,这两个文件是历史连接的记录

最后我们就可以使用别名的方式登录服务器了:
1 | ssh Test |
至此,完成服务器的端口修改和使用密钥登录的操作
Docker和dockercompose的安装
Docker在今年(2024年)6月初的时候,大批量无法拉取镜像,docker的安装也有些无法正常安装,这里提供两种方法:一种是国内服务器安装,另外一种是国外服务器的安装,两者区别在于安装的速度上。
国内服务器安装方式
运行以下命令,下载
docker-ce的yum源。1
sudo wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
运行以下命令,安装Docker。
1
sudo yum -y install docker-ce
执行以下命令,检查Docker是否安装成功。
1
docker -v
如下图回显信息所示,表示Docker已安装成功。

执行以下命令,启动Docker服务,并设置开机自启动。
1
2sudo systemctl start docker
sudo systemctl enable docker执行以下命令,查看Docker是否启动。
1
sudo systemctl status docker
安装docker-compose:
1 | # 下载docker-compose |
这一步如果出错,可以把dockercompose文件下载到本地,然后上传到服务器解压,再给予执行权限就可以了。
关于docker在其他系统的安装可以参考阿里云这篇文章:https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance
国外服务器安装方式
先删除旧的版本(如果没有可以跳过):
1
2
3
4
5
6
7
8sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine安装必须的依赖:
1
2
3sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2添加
stable的Docker-ce的源:1
2
3sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo安装
docker-ce:1
sudo yum install docker-ce docker-ce-cli containerd.io
启动服务:
1
2
3
4
5#启动docker
sudo systemctl start docker
# 开机自动启动
sudo systemctl enable docker
docker-compose安装:
Docker-Compose工具是一个批量工具,用于运行与管理多个docker容器。官方文档:Install Docker Compose
1 | # 下载docker-compose |
解决docker镜像拉取问题
使用国内服务器拉取镜像会出现失败的情况,在这里提供一种解决的方式:
原理:使用cloudflare代理Docker镜像站点。
cloudflare官网:https://dash.cloudflare.com/
开源仓库:https://github.com/cmliu/CF-Workers-docker.io
步骤:
注册登录
cloudflare,选择Workers 和 Pages选项,点击创建;Pages方式:连接
github仓库,选择github仓库(Fork过来的开源仓库),直接开始默认设置就可以Workers :复制 _worker.js 代码,
保存并部署即可修改文件
/etc/docker/daemon.json(如果不存在则创建)使用
vi /etc/docker/daemon.json1
2
3{
"registry-mirrors": ["https://docker.fxxk.dedyn.io"] # 请替换为您自己的Worker自定义域名
}重启更新一下docker
1
2sudo systemctl daemon-reload
sudo systemctl restart docker
注意点:
部署后会一定时间的延迟,需要等一会才可以进行访问;
部署测试第一点是看域名能不能正常访问,第二是镜像名称前面加域名能不能正常pull,比如格式:
域名/镜像名
1
docker pull cf-workers-docker-io-XXX.XXX.dev/mongo
注意格式引号,一定要英文状态下的引号;否则重启docker 的时候会报错;
最好不要公开自己的域名,因为
cloudflare是有免费的请求次数限制;如果用一段时间后无法访问,这是因为
cloudflare容易被墙,最好的办法是自定义域名
Nginx反代和HTTPS证书
上面是服务器连接配置和docker 的安装,接下来是搭建的重要环节,也是这个搭建的灵魂所在。
域名托管到cloudflare
把域名服务商的DNS服务器改为cloudflare就可以被cloudflare托管;
cloudflare有两个配置需要设置一下,否则在部署后会出现问题:
SSL连接:选择完全模式,这是要源服务器配置了证书的情况下设置,这是因为cloudflare代理所有用户请求,cloudflare提供了证书,但是这是用户与cloudflare之间的连接,cloudflare与源服务器之间应该也要走https协议,具体看下面这图就可以知道了。

这里的缓存需要设置一下成标准,halo是带有参数的缓存请求,所以这里不能没有或者忽略。

安装acme
acme安装如果是国内服务器可能会出现安装非常缓慢的情况或者失败,这里一样提供两种安装方式:一种是国内服务器安装,另外一种是国外服务器的安装,两者区别在于安装的速度上。
国内服务器:
直接浏览器访问:https://get.acme.sh,会出现这样的字眼:

访问这个链接就可以得到我们想要的安装方式:
1 | git clone https://gitee.com/neilpang/acme.sh.git |
这里两个问题:
安装git命令:
sudo yum install -y git./acme.sh不是我们想要的,需要直接使用acme命令就可以使用:
1
2
3cd /root/.acme.sh/
alias acme.sh=~/.acme.sh/acme.sh
acme.sh -h
国外服务器:
使用一句安装命令:(这里一定要带上自己的邮箱,否则后面会报错)
1 | curl https://get.acme.sh | sh -s email="[email protected]" |
这个命令安装acme并且创建了一个 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.
注意:安装好之后建议重新连接服务期,如果这个时候直接使用
acme.sh可能有问题
acme生成证书
这里使用的acme的DNSApi的方式生成证书(这里演示的是cloudflare,不同的DNS服务商是不同命令的,具体参考:https://github.com/acmesh-official/acme.sh/wiki/dnsapi)
Cloudflare api:
1 | export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" |
这样,我们就完成了域名和子域名下的证书签发。
安装Nginx容器
安装Nginx之前,还需要做一下准备工作:
创建文件夹:
mkdir /home/keys,存放Https证书文件创建随机的
https证书密钥:1
openssl dhparam -out /home/keys/dhparam.pem 2048
创建容器的局域网段:
1 | docker network create https |
创建文件夹:
1
2mkdir /home/nginx
mkdir /home/nginx/conf.dhome/nginx 是用来存放nginx容器的文件
home/nginx/conf.d是用来存放带来其他容器的nginx conf.d文件
配置
nginx.conf文件,并上传到服务器home/nginx文件夹下,这是一个通用的文件配置,正常无需修改1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53user nginx;
worker_processes auto;
pid /run/nginx.pid;
worker_rlimit_nofile 65535;
events {
# 设置事件驱动模型,是内核2.6以上支持
use epoll;
worker_connections 65535;
accept_mutex off;
multi_accept off;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
send_timeout 120;
keepalive_timeout 300;
client_body_timeout 300;
client_header_timeout 120;
proxy_read_timeout 300;
proxy_send_timeout 300;
#tcp_nopush on;
types_hash_max_size 4096;
client_header_buffer_size 16m;
client_max_body_size 4096m;
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
# include /usr/share/nginx/modules/*.conf;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
}接下来是
Nginx容器安装,编写docker-compose文件:
1 | version: "3" |
解释:创建了一个some-nginx的容器,把容器文件nginx.conf、conf.d和keys文件夹挂载出来。暴露端口是80和443;把容器加入到https的网段里面,让这个网段里面的容器可以被nginx容器代理到。
编写好后就可以直接使用一下命令安装:
1 | docker-compose up -d |
最后我们就可以运行之前acem的安装命令:
1 | acme.sh --install-cert -d example.top \ |
正常的话,这里运行着一个nginx容器了,这里的步骤稍微复杂但是细心一点还是没有难度的,特别需要注意的是域名、文件夹和文件名这些内容不要写错。
TIP:这里在使用
docker-compos安装前,需要把Nginx的文件夹先创建好,给目录777权限,nginx.conf是文件,conf.d是文件夹
安装Halo
由于小型的服务器可能承受不住Halo和mysql的压力,这里演示的是H2数据库:
这是官方提供的docker-compose文件:
1 | version: "3" |
但是我们安装这个文件安装,可能就会报错,这里我们需要优化调整一下:
1 | version: "3" |
增加了container_name(自定义域名,方便接下来的Nginx容器访问),剔除了start_period(主要报错原因),增加了networks(加入https网段,和Nginx容器同个网段,可以之间通讯访问)
Nginx代理Halo容器
安装好Halo容器,最后就需要使用Nginx来代理这个容器,我们可以编写一个conf文件,存放到home/nginx/conf.d目录下,这样就可以使Nginx容器代理Halo容器了
Halo.conf
1 | upstream halo-server { |
需要修改地方:
- proxy_pass http://halo-server 是 和 halo-server对应的
- return 302 https://test.test.top 填写自己的域名
- server_name test.test.top; 填写自己的域名
- server test:8090 fail_timeout=0; 填写自己容器名称
总结
这样搭建的halo博客,不用关心https证书更新问题,也不用担心暴漏IP风险,少了宝塔,也减轻了服务器的负担,nginx容器可以带来其他容器,为以后其他项目做了一个兼容扩展性。
