Halo 搭建个人博客

写在前面

本文使用 docker-compose 方式,基于 Halo 2.12.0 搭建博客,使用 MySQL 8.0 做为 Halo 数据源,使用 Redis 6.2 做为缓存,使用 Nginx 做反向代理
本文仅记录搭建博客过程,关于 Halo 主题切换、详细使用等可以自行查阅其他资料,也可以留言联系

工具准备

docker 环境安装

安装docker

  • docker 安装

    sudo yum install -y docker-ce docker-ce-cli containerd.io
    
  • docker 安装后默认未运行 需要先运行

    sudo systemctl start docker
    
  • 检测 docker 是否安装成功

    // 拉取镜像
    sudo docker pull hello-world
    // 执行hello-world
    sudo docker run hello-world
    
  • 设置 docker 开机自启

    systemctl enable docker
    

docker-compose 安装

  • docker compose v2 安装

    sudo curl -L https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    
  • 授权二进制文件可执行权限

    sudo chmod +x /usr/local/bin/docker-compose
    
  • 检测是否安装成功

    docker-compose --version
    

容器之间通信

docker 容器网络
https://docs.docker.com/config/containers/container-networking/

Docker官方建议每个容器中只运行一个服务1,当用多个容器时,比如多个微服务或者使用到 MySQL、Redis等中间件时,就需要了解容器间的通信方法了2。默认的网桥bridge上的容器只能通过IP互连,无法通过DNS解析名称或别名

为了实现不同容器通过容器名或别名的通信,这里使用 自定义bridge 的方式

  • 主机执行 docker network ls 查看 docker 中存在的网络

  • 用户自定义bridge

    # 创建了一个名为"my-net"的网络
    docker network create my-net
    
    # 将redis服务加入my-net网络中
    docker network connect my-net my_redis
    # 将mysql服务加入my-net网络中
    docker network connect my-net mysqld8.0
    
    # 查看my-net的网络配置
    docker network inspect my-net
    
  • a虽然将容器加入了自定义bridge但是 默认bridge 网络仍然连接着,现在已经不需要,可以选择将容器与 默认bridgedocker0网桥断开连接。ps:不断开也不影响

    # 断开容器与docker0的连接
    docker network disconnect bridge my_redis
    docker network disconnect bridge mysqld8.0
    

nginx 安装

  • 安装 nginx 需要的编译工具及库文件

    yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel
    
  • 下载 nginx

    wget http://nginx.org/download//nginx-1.20.2.tar.gz
    
  • 解压 tar 包

    tar zxvf nginx-1.6.2.tar.gz
    
  • 进入安装目录 编译安装

    make && make install
    
  • 设置软链接

    设置环境变量同效, 可以全局使用 nginx 命令

    ln -s /usr/local/nginx/sbin/nginx  /usr/local/bin
    
  • 配置 nginx 反向代理 halo 服务

    编辑 nginx 配置文件:vi /usr/local/nginx/conf/nginx.conf

    server {
        listen       80;
        server_name  localhost;
    
        location / {
            proxy_pass http://127.0.0.1:8090/;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            index  index.html index.htm;
            client_max_body_size  100m;
        }
    }
    

nginx 配置开机自启

  • 在 / etc/systemd/system / 路径下创建 nginx.service 文件

    cd /etc/systemd/system/
    vi nginx.service
    
  • 写入如下内容,保存并退出

    [Unit]
    Description=nginx - high performance web server
    After=nginx.service
    [Service]
    Type=forking
    ExecStart=/usr/local/nginx/sbin/nginx
    ExecReload=/usr/local/nginx/sbin/nginx -s reload
    ExecStop=/usr/local/nginx/sbin/nginx -s stop
    Execenable=/usr/local/nginx/sbin/nginx
    [Install]
    WantedBy=multi-user.target
    
  • 设置开机自启动

    # 设置开机启动
    systemctl enable nginx
    # 取消开机自启动
    #systemctl disable nginx
    # 查看服务当前状态
    systemctl status nginx
    # 启动nginx服务
    systemctl start nginx
    # 停止nginx服务
    systemctl stop nginx
    # 重启nginx服务
    systemctl restart nginx
    

环境准备

JDK 安装

使用 docker 运行 Halo 可以忽略 JDK 安装

操作目录:/opt

创建 jdk 目录:mkdir jdk17

下载:wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz

解压:tar -vxf jdk-17_linux-x64_bin.tar.gz

使用 pwd 查看当前jdk目录,拷贝下来,设置环境变量需要

修改环境变量信息:vim /etc/profile

在文件末尾新增以下,jdk目录在opt/jdk17/jdk-17.x.x

JAVA_HOME=/opt/jdk-17.x.x
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME PATH

重新加载环境变量:source /etc/profile

验证 jdk 安装是否成功:java -version

MySQL 安装

使用docker-compose 安装 mysql8

  • 创建相关目录

    mkdir /mnt/mysql/conf /mnt/mysql/data
    
  • 编辑 docker-compose.yml 文件

    services:
      mysql8.0:
        # 镜像名
        image: mysql:8.0.28
        # 容器名(以后的控制都通过这个)
        container_name: my_mysql
        # 重启策略
        restart: always
        networks:
          - my-net
        environment:
          # 时区上海
          TZ: Asia/Shanghai
          # root 密码
          MYSQL_ROOT_PASSWORD: 123456
    
        # 映射端口
        ports:
          # <主机端口> : <容器端口>
          - 3306:3306
        volumes:
          # 数据挂载
          - /mnt/mysql/data/:/var/lib/mysql/
          # 配置挂载
          - /mnt/mysql/conf/:/etc/mysql/conf.d/
        command:
          # 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配)
          --default-authentication-plugin=mysql_native_password
          --character-set-server=utf8mb4
          --collation-server=utf8mb4_general_ci
          --explicit_defaults_for_timestamp=true
          --lower_case_table_names=1
          
    networks:
      my-net:
        external: true
    
  • 启动 mysql 镜像 (初次启动会拉取 mysql 镜像)

    docker-compose up -d mysql8.0
    

Redis 安装

  • 创建相关目录

    mkdir /mnt/redis/data /mnt/redis/logs
    
  • 编写 redis.conf 文件

    #开启远程可连接
    #bind 127.0.0.1
    #自定义密码
    requirepass 123456
    #指定 Redis 监听端口(默认:6379)
    port 6379
    #客户端闲置指定时长后关闭连接(单位:秒。0:关闭该功能)
    timeout 0
    # 900s内如果至少一次写操作则执行bgsave进行RDB持久化操作
    save 900 1
    # 在300s内,如果至少有10个key进行了修改,则进行持久化操作
    save 300 10
    #在60s内,如果至少有10000个key进行了修改,则进行持久化操作
    save 60 10000
    #是否压缩数据存储(默认:yes。Redis采用LZ 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大)
    rdbcompression yes
    #指定本地数据文件名(默认:dump.rdb)
    dbfilename dump.rdb
    #指定本地数据文件存放目录
    dir /data
    #指定日志文件位置(如果是相对路径,redis会将日志存放到指定的dir目录下)
    logfile "redis.log"
    
  • 编辑 docker-compose.yml 文件

    version: "3"
    services:
      redis:
        #镜像及版本
        image: redis:6.2.6
        #自定义容器名
        container_name: my_redis
        # docker 启动时,自动启动该容器
        restart: always
        networks:
          - my-net
        # 挂载映射,数据或配置持久化
        volumes:
          # <本地配置文件> : <docker中的配置文件> : <ro:docker容器对该文件只读,默认是rw可读可写>
          - /mnt/redis/redis.conf:/etc/redis/redis.conf:ro
          # <本地数据目录> : <docker中的数据目录>
          - /mnt/redis/data:/data
          - /mnt/redis/logs:/logs
        # docker执行的启动命令
        command: redis-server /etc/redis/redis.conf
        ports:
          # <本地端口> : <docker容器端口>
          - 6379:6379
          
    networks:
      my-net:
        external: true
    
    
  • 启动 redis 镜像 (初次启动会拉取 redis 镜像)

    docker-compose up -d mysql8.0
    

搭建 Halo 服务

halo官网搭建文档:
https://docs.halo.run/getting-started/prepare

创建 Halo 所需数据库

  • 如果使用 mysql 作为数据源,需要手动创建数据库,不需要创建表

halo 官方建议使用 建库语句

create database halodb character set utf8mb4 collate utf8mb4_bin;

Halo 相关配置

  • 创建相关目录

    mkdir /mnt/halo-app && cd /mnt/halo-app
    
  • 编写 docker-compose.yml

    https://hub.docker.com/r/halohub/halo 查看最新版本镜像,我们推荐使用具体版本号的镜像,但也提供了 latest 标签的镜像,它始终是最新的。

    version: "3"
    
    services:
      halo:
      	# 使用 halo 2.12.0 镜像, 可以去查看最新版本使用
        image: halohub/halo:2.12.0
        # 重命名容器
        container_name: halo
        restart: on-failure:3
        # 使用自定义网络 my-net
        networks:
          - my-net
        volumes:
          - ./:/root/.halo
          #- /etc/timezone:/etc/timezone:ro
          #- /etc/localtime:/etc/localtime:ro
        ports:
          - "8090:8090"
        environment:
          # 容器内服务端口
          - SERVER_PORT=8090
          # 数据库驱动
          - SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
          # 数据库连接 url
          - SPRING_DATASOURCE_URL=jdbc:mysql://mysql8.0:3306/my_halo?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
          # 数据库用户
          - SPRING_DATASOURCE_USERNAME=root
          # 数据库用户密码
          - SPRING_DATASOURCE_PASSWORD=123456
          # halo 系统后台路径
          - HALO_ADMIN_PATH=admin
          # 使用内存作为缓存
          #- HALO_CACHE=memory
          # 使用 redis 作为缓存
          - HALO_CACHE=redis
          - SPRING_REDIS_PORT=6379
          - SPRING_REDIS_DATABASE=0
          - SPRING_REDIS_HOST=my_redis
          - SPRING_REDIS_PASSWORD=123456
    
    # 指定网络
    networks:
      my-net:
      	# 外部
        external: true
    

启动&初始化 Halo

  • 启动 Halo

    # 启动容器
    docker-compose up -d halo
    
    # 查看日志
    docker-compose logs -f --tail=100 halo
    
  • 初始化 Halo

    查看日志,成功启动 halo 服务后,打开http://ip(如果 nginx 反向代理使用的不是 80 端口,需要 http://ip:端口号)看到 halo 的安装引导界面

    根据引导 输入用户名、邮箱... 后跳转进入 halo 后台管理页面

    初始化完成后再次打开 http://ip 就是个人博客的对外显示样式了

到这里,你的个人博客就搭建完成了,欢迎交换友链。

更新 Halo

官网文档
https://docs.halo.run/getting-started/upgrade

停止容器

docker stop halo

删除容器

docker rm -f halo

备份数据以及旧的运行包

cp -r ~/.halo ~/.halo.archive

需要注意的是,.halo.archive 文件名不一定要根据此文档命名,这里仅仅是个示例。

清空 leveldb 缓存(如果有使用 leveldb 作为缓存策略)
rm -rf ~/.halo/.leveldb

拉取最新的 Halo 镜像

docker pull halohub/halo:2.12.0


Footnotes

  1. https://docs.docker.com/config/containers/multi-service_container/

  2. https://docs.docker.com/network/