基于Docker容器化快速搭建Halo个人博客

一款现代化的开源博客/CMS系统,值得一试。

Halo是一款基于java的开源博客系统,也有很多开发者开源了一些好看的主题,个人感觉使用起来还是非常方便的,我基于Halo搭建的个人博客网站Demo大家可以看一下效果:李波个人博客

下边介绍一下容器化快速搭建过程

先决条件

一台服务器

一个已备案的域名

推荐【腾讯云轻量应用服务器,首年45元】

ps:如果是国外服务器那么域名可以不备案。这里推荐【腾讯云香港服务器,首年98元,域名免备案】

搭建Halo的准备工作

安装docker

如果你购买的是腾讯云轻量应用服务器,那么你在选择系统镜像时直接选择docker20+centos7.9的镜像接口。

否则你需要对你的centos系统安装docker,安装步骤如下(详细安装步骤点击链接直达):

# 获取
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# 安装
yum install docker-ce -y
# 启动
systemctl start docker
systemctl enable docker


# 卸载docker,备用
yum remove docker-ce.x86_64 ddocker-ce-cli.x86_64 -y
rm -rf /var/lib/docker

构建docker网桥

docker容器间相互通信可以通过:

  1. 容器的分配的ip(不建议,因为容器重新启动后IP可能会发生改变。)
  2. 容器名称(推荐)

docker容器间若使用容器名称通信,则必须创建一个网桥,然后把需要通信的容器都使用此网桥即可。

# 创建网桥
docker network create --driver bridge blog
# 后边创建容器时指定网络名即可
--net blog

创建mysql容器

Halo默认存储使用的H2数据库,这里我们使用mysql

若使用mysql,Halo要求版本必须在5.7及以上。

容器互通 --net blog

# 拉一个mysql镜像
docker pull mysql:5.7.37
# 创建mysql容器数据挂载目录
mkdir -p /mydata/mysql_data/data
# 后台运行容器,挂载数据卷(持久化存储数据),端口暴露,admin密码,网桥
# 端口暴露给外部时方便连接管理,不暴露也可
# 数据库的数据全部存在这里  /mydata/mysql_data/data
# 因为我们全部容器化,所以不需要对外暴露访问端口
# 密码记得改成你自己的
docker run -dti --name mysql -v /mydata/mysql_data/data:/www/server/data -e MYSQL_ROOT_PASSWORD=123456 --net blog mysql:5.7.37

# 若需要暴露给外部访问,则加上-p参数即可
# 不建议暴露,会增加被攻击的危险性
docker run -dti --name mysql -v /mydata/mysql_data/data:/www/server/data -p8881:3306 -e MYSQL_ROOT_PASSWORD=123456 --net blog mysql:5.7.37

查看运行的容器:

[root@k8s-node02 mysql]# docker  ps
CONTAINER ID   IMAGE                COMMAND                    CREATED        STATUS        PORTS                                    NAMES    
23a9ab87cafb   mysql:5.7.37         "docker-entrypoint.s…"     4 hours ago    Up 4 hours    3306/tcp                                  mysql5.7.37

若果没有mysql,说明启动失败,

# 通过-a参数查看失败的容器
docker  ps -a
# 查看启动失败的日志,根据日志进行修改,按照我的做一定不会出错!
docker logs mysql

如果你暴露了外部访问端口,可以使用Navicat连接上试试功能,Navicat安装教程

不建议暴露,会增加被攻击的危险性

image-20220424161516822
创建一个名为halodb的数据库

# 进入mysql容器
docker exec -ti mysql /bin/bash
# 登录mysql
mysql -uroot -p
# 上边输入完按回车后输入你设定的mysql密码
# 然后执行下边的语句
create database halodb character set utf8mb4 collate utf8mb4_bin;
# 查看
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| bloglee            |
| halodb             |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.02 sec)
# 看到halodb已经创建成功
#退出容器
exit

如果安装了Navicat可以在其中操作即可。

创建redis容器

这里redis是用来给Halo做缓存使用的

容器互通 --net blog

# 拉取redis镜像
docker pull redis:6.2.6
# 只是用来做缓存的,不需要其他复杂配置,也无需暴露端口给外部访问
# 密码记得改成你自己的
docker run -itd --name redis --net blog redis:6.2.6 --requirepass  "123456"
# 查看
[root@VM-12-11-centos ~]# docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED      STATUS       PORTS                                      NAMES
98a559583642   redis:6.2.6               "docker-entrypoint.s…"   4 days ago   Up 4 days    6379/tcp                                   redis

搭建Halo博客

  1. 创建工作目录

    mkdir ~/.halo && cd ~/.halo
    
  2. 下载示例配置文件到工作目录

    wget https://dl.halo.run/config/application-template.yaml -O ./application.yaml
    
  3. 编辑配置文件

    vim application.yaml
    # 内容修改为下边的
    # 可以看到我们的redis和mysql的host全写为容器的名字即可,非常方便
    server:
      port: 8090
    
      # Response data gzip.
      compression:
        enabled: true
    spring:
      datasource:
    
        # H2 database configuration.
        # driver-class-name: org.h2.Driver
        # url: jdbc:h2:file:~/.halo/db/halo
        # username: admin
        # password: 123456
    
        # MySQL database configuration.
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://mysql:3306/halodb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
        username: root
        password: 123456
    
      # H2 database console configuration.
      # h2:
      #   console:
      #     settings:
      #       web-allow-others: false
      #     path: /h2-console
      #     enabled: false
      redis:
        # Redis cache configuration.
        port: 6379
        database: 0
        host: redis
        password: 123456
    
    halo:
    
      # Your admin client path is https://your-domain/{admin-path}
      admin-path: admin
    
      # memory or level
      cache: redis
    
  4. 拉取最新的 Halo 镜像

    docker pull halohub/halo:1.5.2
    
  5. 创建容器

    # 一定要指定网桥为我们创建的blog
    # 因为我们容器互通,后边会让nginx容器转发,所以不必暴露端口
    docker run -it -d --name halo -v ~/.halo:/root/.halo --net blog --restart=unless-stopped halohub/halo:1.5.2
    
    # 如果你想暴露端口,加上-p参数即可,暴露的端口要在服务器安全组放行
    # 不建议暴露,会增加被攻击的危险性
    docker run -it -d --name halo -p 8090:8090 -v ~/.halo:/root/.halo --net blog --restart=unless-stopped halohub/halo:1.5.2
    

配置Nginx容器转发Halo博客并设置https服务

  1. 拉镜像

    # 拉镜像
    docker pull nginx:1.18.0
    
  2. 创建域名证书挂载文件夹

    去阿里云控制台的SSL服务为你的域名免费生一个SSL证书,下载Nginx格式。

    会得到两个文件:.pem和.key的。

    把他们上传到此文件夹中。

    image-20220424162009726

    # 创建域名证书挂载文件夹
    mkdir -p /mydata/nginx/cert 
    # 上传证书文件.pem和.key
    [root@VM-12-11-centos cert]# ll
    total 16
    -rw-r--r-- 1 root root 1679 Apr 20 00:07 blog.liboer.top.key
    -rw-r--r-- 1 root root 3801 Apr 20 00:07 blog.liboer.top.pem
    
  3. 创建nginx配置文件:nginx.conf

    主要关注两个地方的配置:http和https

    http:配置后可通过http访问

    **********
    **********
           server
            {
              listen 80;
              server_name blog.liboer.top;
              rewrite ^(.*)$ https://$host$1;
              #server_name _;
              location / {
                    proxy_pass http://halo:8090; #与uwsgi中ip:端口相同
                    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;
                }
            }  
    **********
    **********
    

    https:不配置则只能通过上面的http访问,配置后可通过https访问

    **********
    **********
            server
            {
              listen 443 ssl;
              #配置HTTPS的默认访问端口为443。
              #如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
              #如果您使用Nginx 1.15.0及以上版本,请使用listen 443 ssl代替listen 443和ssl on。
              server_name blog.liboer.top; #需要将yourdomain.com替换成证书绑定的域名。
              root html;
              index index.html index.htm;
              ssl_certificate /etc/nginx/conf/cert/blog.liboer.top.pem;  #需要将cert-file-name.pem替换成已上传的证书文件的名称。
              ssl_certificate_key /etc/nginx/conf/cert/blog.liboer.top.key; #需要将cert-file-name.key替换成已上传的证书密钥文件的名称。
              ssl_session_timeout 5m;
              ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
              #表示使用的加密套件的类型。
              ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; #表示使用的TLS协议的类型。
              ssl_prefer_server_ciphers on;
              location / {
                    proxy_pass http://halo:8090; #与uwsgi中ip:端口相同
                    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;
                }
            }
    **********
    **********
    

    完整的配置文件

    只需在/mydata/nginx目录下输入

    vi ngxin.conf

    然后把下边的内容粘贴进入保存即可

    user  nginx;
    worker_processes  1;
    
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        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;
    
        server_names_hash_bucket_size 512;
            client_header_buffer_size 32k;
            large_client_header_buffers 4 32k;
            client_max_body_size 50m;
    
            sendfile   on;
            tcp_nopush on;
    
            keepalive_timeout 60;
    
            tcp_nodelay on;
    
            fastcgi_connect_timeout 300;
            fastcgi_send_timeout 300;
            fastcgi_read_timeout 300;
            fastcgi_buffer_size 64k;
            fastcgi_buffers 4 64k;
            fastcgi_busy_buffers_size 128k;
            fastcgi_temp_file_write_size 256k;
    		fastcgi_intercept_errors on;
    
            gzip on;
            gzip_min_length  1k;
            gzip_buffers     4 16k;
            gzip_http_version 1.1;
            gzip_comp_level 2;
            gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
            gzip_vary on;
            gzip_proxied   expired no-cache no-store private auth;
            gzip_disable   "MSIE [1-6]\.";
    
            limit_conn_zone $binary_remote_addr zone=perip:10m;
    		limit_conn_zone $server_name zone=perserver:10m;
    
            server_tokens off;
            include /etc/nginx/conf.d/*.conf;
    
            server
            {
              listen 80;
              server_name blog.liboer.top;
              rewrite ^(.*)$ https://$host$1;
              #server_name _;
              location / {
                    proxy_pass http://halo:8090; #与uwsgi中ip:端口相同
                    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;
                }
            }  
            #以下属性中,以ssl开头的属性表示与证书配置有关。	
            server
            {
              listen 443 ssl;
              #配置HTTPS的默认访问端口为443。
              #如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
              #如果您使用Nginx 1.15.0及以上版本,请使用listen 443 ssl代替listen 443和ssl on。
              server_name blog.liboer.top; #需要将yourdomain.com替换成证书绑定的域名。
              root html;
              index index.html index.htm;
              ssl_certificate /etc/nginx/conf/cert/blog.liboer.top.pem;  #需要将cert-file-name.pem替换成已上传的证书文件的名称。
              ssl_certificate_key /etc/nginx/conf/cert/blog.liboer.top.key; #需要将cert-file-name.key替换成已上传的证书密钥文件的名称。
              ssl_session_timeout 5m;
              ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
              #表示使用的加密套件的类型。
              ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; #表示使用的TLS协议的类型。
              ssl_prefer_server_ciphers on;
              location / {
                    proxy_pass http://halo:8090; #与uwsgi中ip:端口相同
                    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;
                }
            }
    }
    
  4. 启动容器

    加入网络 --net blog

    docker run -dti --name nginx -p80:80 -p443:443  --net blog -v /mydata/nginx/cert:/etc/nginx/conf/cert -v /mydata/nginx/nginx.conf:/etc/nginx/nginx.conf nginx:1.18.0
    
  5. 选择一个你喜欢的主题上传即可

    我使用的是joe2.0,挺好看的,你们可以选择自己的喜欢的主题上传。

访问你的博客

浏览器输入:

https://blog.liboer.top

哇塞!请在公屏上打出 牛B 二字!

在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐