Halo博客+兰空图床搭建保姆级指南
1. 简介
1.1 依赖的相关软件
Docker
、Docker-Compose
底层运行环境Minio
底层的存储支持Mysql
关系型数据库Redis
缓存中间件NginxProxyManager
(以下简称NPM
)管理 Nginx 反向代理的开源工具Portainer
Docker容器管理兰空图床
图片管理,如果使用第三方如阿里云S3、七牛S3,可以省略CloudFlare
DNS 服务提供商,解析域名Halo
博客系统
为什么要搭建自己的图床,不使用第三方阿里云、七牛等OSS?
- 完全控制:自己搭建图床,你可以完全控制数据的存储、访问权限、安全策略等,避免第三方服务商的政策变动或限制。
- 隐私和安全:对于高度敏感的图片或数据,自己搭建图床可以确保数据不会被第三方服务商访问或存储。
- 自定义功能:可以根据需要自定义图床的功能,如图片压缩、水印添加、格式转换等,满足特定业务需求。
- 成本管理:如果图片流量和存储需求在可控范围内,自己搭建图床可能比第三方服务商的按需计费模式更具成本效益。
- 无依赖性:不依赖于第三方服务商的服务质量和可用性,减少潜在的服务中断风险。
1.2 端口规划
假设域名为itweek.top,这里加上二级域名访问地址则为:https://blog.itweek.top
软件 | 端口 | 二级域名前缀 |
---|---|---|
Minio | 9090 - api端口 9091 - 控制台端口 |
m - 映射api端口 minio - 映射控制台端口 |
Mysql | 3306 | |
Redis | 6379 | |
NginxProxyManager | 80 - HTTP端口 443 - HTTPS端口 81 - NPM管理界面端口 |
npm |
兰空图床 | 8089 - HTTP端口 8088 - HTTPS端口 |
lsky |
Portainer | 9000 - 容器管理端口 | pt |
Halo | 8090 - 博客管理端口 | blog |
1.3 目录相关
根目录 /home/soft/docker
, 这里用来存放所有的软件部署文件
上面是使用
vscode
的Remote - SSH
插件远程连接到云服务器上,方便编辑配置文件和创建文件夹。
建议提前按照上述截图创建好对应目录及文件。
2. 服务器及域名
服务器:至少2核2G内存,放开
80
、81
、443
、3306
端口,这里假定ip地址为118.60.60.118
域名:通过
泛解析
和NPM
,可以方便地管理大量的子域名,而无需为每个子域名单独配置 DNS 记录和反向代理规则,通过NPM
,能够轻松配置和管理 SSL 证书,提升站点的安全性.这里假定域名为itweek.top
以下通过 Namesilo
申请域名及 CloudFlare
设置DNS解析作为示例,介绍如何设置泛解析及为后续 NPM
托管域名申请SSL证书做准备。
详细操作过程见 Namesilo+Cloudflare申请域名及DNS解析指南
按照上述操作后需要记录对应的 API令牌
。
3. 软件配置文件
3.1 Minio
- docker-compose.yml
version: '3'
services:
minio:
restart: unless-stopped
image: minio/minio
container_name: minio
volumes:
- ./config:/config
- ./data:/data
# 指定控制台的端口
command: server /data --console-address ":9001"
environment:
- 'MINIO_ROOT_USER=minio'
- 'MINIO_ROOT_PASSWORD=minio'
ports:
# api端口
- 9090:9000
# 控制台端口,如果上述command不配置,默认为9090
- 9091:9001
修改 MINIO_ROOT_PASSWORD
配置
3.2 Mysql
- docker-compose.yml
version: '3'
services:
mysql:
restart: always
image: mysql:5.7.35
container_name: mysql
volumes:
- ./datadir:/var/lib/mysql:rw
- ./my.cnf:/etc/mysql/my.cnf
environment:
- "MYSQL_ROOT_PASSWORD=root"
- "TZ=Asia/Shanghai"
ports:
# 使用宿主机的3306端口映射到容器的3306端口
- 3306:3306
修改 MYSQL_ROOT_PASSWORD
配置,这里如果是群晖部署,./datadir:/var/lib/mysql:rw
需要指定 rw
读写 权限,不然后期无法删除数据库。
- my.cnf
[mysqld]
user=mysql
default-storage-engine=INNODB
character-set-server=utf8
character-set-client-handshake=FALSE
init_connect='SET NAMES utf8'
max_connections=1000
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
3.3 Redis
- docker-compose.yml
version: '3.3'
services:
redis:
image: redis:latest
container_name: redis
restart: always
ports:
- '6379:6379'
volumes:
- ./data:/data
- ./redis.conf:/usr/local/etc/redis/redis.conf
- ./logs:/logs
#配置文件启动
command: redis-server /usr/local/etc/redis/redis.conf
- redis.conf
# 开启保护
protected-mode no
# 绑定监听IP地址
bind 0.0.0.0
# 自定义密码
requirepass root
# 启动端口
port 6379
# redis 默认就开启 rdb 全量备份,以下是默认的备份触发机制
# 900s内至少一次写操作则执行bgsave进行RDB持久化
save 900 1
save 300 10
save 60 10000
# 是否压缩 rdb 备份文件,默认是压缩
# 如果 redis 承载的数据量非常大的话,建议不要压缩
# 因为压缩过程中需要耗费大量 cpu 和内存资源,磁盘相对而言比较廉价
rdbcompression yes
# rdb 备份的文件名
dbfilename dump.rdb
# Redis 备份文件存储目录,注意:该路径是 docker 容器内的路径
dir /data
# 是否开启 aof 增量备份功能,默认是否
appendonly yes
# AOF文件的名称,这里使用默认值
appendfilename appendonly.aof
# aof 增量备份的策略,这里是每秒钟一次,将累积的写命令持久化到硬盘中
appendfsync everysec
修改 requirepass
配置
3.4 NPM
- docker-compose.yml
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
# Mysql/Maria connection parameters:
DB_MYSQL_HOST: "172.17.0.1"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "root"
DB_MYSQL_PASSWORD: "root"
DB_MYSQL_NAME: "npm"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
修改 DB_MYSQL_PASSWORD
、DB_MYSQL_NAME
,提前创建好npm数据库,后续数据库的表自动初始化。
create database npm default character set utf8mb4 collate utf8mb4_unicode_ci;
3.5 Portainer
可省略,这个主要是方便管理docker应用,以及查看应用日志。
- docker-compose.yml
version: "3"
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
- "9000:9000"
volumes:
- ./data:/data
- /var/run/docker.sock:/var/run/docker.sock
3.6 Lsky Pro
- docker-compose.yml
version: '3'
services:
lsky:
image: halcyonazure/lsky-pro-docker:latest
restart: unless-stopped
hostname: lsky
container_name: lsky
environment:
- WEB_PORT=8089
- HTTPS_PORT=8088
volumes:
- ./web:/var/www/html/
- /volume2/PUBLIC_PIC/uploads:/var/www/html/uploads
ports:
- "8089:8089"
- "8088:8088"
这里暂时不用指定mysql的配置,在初始化的时候引导界面可以指定mysql的连接信息及数据库,这里可以先创建好对应的数据库,后续数据库的表自动初始化。
create database lsky_pro default character set utf8mb4 collate utf8mb4_unicode_ci;
4. NPM设置
4.1 初始化
访问 http://118.60.60.118:81 界面,初始账号密码为
Email: admin@example.com
Password: changeme
进去之后按照提示修改账号密码。
4.2 配置SSL证书
注意这里需要在域名提供商提前增加泛解析到该机器ip,并获取到对应的API令牌。
点击 SSL-Certificates
, Add SSL Certificate
,选择 Lets Encrypt
按如下要求填写信息:
-
Domain Names
:*.itweek.top
-
Email Address for Lets Encrypt
: 这里可以随便填写,但是最好填写域名提供商绑定的邮箱地址 -
DNS Proider
选择Cloudflare -
Credentials File Content
按如下信息填写# Cloudflare API token dns_cloudflare_email = mulyzhou@gmail.com dns_cloudflare_api_key = 1ef26**************da3deeef3ec
dns_cloudflare_email
和Email Address for Lets Encrypt
保持一致dns_cloudflare_api_key
为提前申请好的API令牌
点击Save之后会去申请证书,成功之后会显示如下信息:
4.3 增加Proxy Host
点击 Dashboard
,Proxy Hosts
,Add Proxy Host
这里以NPM(二级域名为npm、端口地址为81)为例
详细信息 Details
如下:
这里填写的
172.17.0.1
是Docker默认的桥接网络(bridge network)的网关 IP 地址。这个 IP 地址通常用来与 Docker 容器进行网络通信。
SSL Certificate
必须填 *.itweek.top
,然后勾选上 Force SSL
和 HTTP/2 Support
。点击 save
之后即能使用 https://npm.itweek.top
访问 NPM
。
5. Minio设置
搭建的minio是新版的,界面和旧版的可能不一样。
5.1 配置域名
步骤和配置 NPM
的域名访问一致,这里配置两个域名,一个为控制台的域名 https://minio.itweeks.top
,一个为API存储桶 https://m.itweeks.top
的访问域名,这样以后就能直接通过 https://m.itweeks.top/存储桶/key
访问图片了。
5.2 创建地区和存储桶
登录https://minio.itweeks.top,用户名密码为 docker-compose.yml
里配置的用户名和密码。
这里创建的地区为:us-east-1
创建 image
的存储桶,创建成功之后点击该存储桶,然后设置存储桶的权限为 public
。
测试上传图片,这里上传的图片为 WX20240426-164920@2x.png
,按照上面配置就能通过 https://m.itweek.top/image/WX20240426-164920@2x.png
该链接访问预览该图片。
这个图片存储在服务器的位置如下,后续对该文件夹做好对应的备份即可。或者minio可以采用高可用集群部署,这里篇幅有限不再展开,感兴趣的同学可以自行研究。
5.3 申请密钥
这里记录下 Access Key
和 Secret Key
后面要用到。
6. 兰空图床设置
6.1 简介
兰空图床(Lsky Pro)是一款开源的图床程序,旨在为用户提供一个简单、方便、稳定的图像存储与分享平台。以下是兰空图床的一些主要特点和功能:
- 开源免费:兰空图床是开源软件,源代码托管在GitHub上,用户可以免费使用、修改和分发。
- 多存储支持:支持多种存储方式,包括本地存储、阿里云OSS、腾讯云COS、七牛云等第三方云存储,用户可以根据需求选择适合的存储方式。
- 多平台支持:兰空图床可以部署在多种平台上,包括Windows、Linux、macOS等,部署简单方便。
- 简洁的界面:提供简洁、美观的用户界面,操作简单,用户体验良好。
- API支持:提供丰富的API接口,方便开发者进行二次开发或与其他系统集成。
- 多用户支持:支持多用户管理,每个用户可以管理自己的图片,并可以设置不同的权限。
- 安全性:提供多种安全措施,包括访问控制、数据加密等,保障用户数据安全。
- 图片处理功能:内置图片处理功能,如缩放、裁剪、水印等,方便用户对图片进行各种操作。
兰空图床适合个人和团队使用,不仅可以用来存储和分享图片,还可以与博客、论坛等平台集成,提高图片管理效率。如果你对图床程序有需求,兰空图床是一个不错的选择。
6.2 配置域名
配置好 https://lsky.itweek.top
的域名访问。
这里需要在 Custom locations
下添加一个header,内容为:proxy_set_header X-Forwarded-Host $http_host;
勾选上 Force SSL
和 HTTP/2 Support
。点击 save
。
为什么需要在 Custom locations
下添加header,具体可见官方仓库issue讨论。这里面的讨论还涉及到源码的修改,这个等应用搭建初始化完毕之后再修改。
6.3 初始化
访问 https://lsky.itweek.top
,进入初始化页面。
配置数据库和管理员账号,这里要预先创建好对应的数据库 lsky_pro
,数据库连接地址可以填写 172.17.0.1
,用户名密码填写mysql的用户名密码,填写管理员账号邮箱及密码,点击立即安装。
6.4 修改源码
兰空图床的源码都映射在 lsky/web
文件夹下
- 修改
/config/app.php
'url' => env('APP_URL', 'https://xxxxx.com:50000'),
'asset_url' => env('ASSET_URL', 'https://xxxxx.com:50000'), - 修改
/app/Providers/ApServiceProvider.php
第 32 行下面追加一行:
\Illuminate\Support\Facades\URL::forceScheme('https'); - 修改
/app/Services/ImageService.php
,在356行'bucket_endpoint' => (bool)$configs->get(MinioOption::BucketEndpoint),
下面增加: 'use_path_style_endpoint' => true, - 配置cache
修改.env文件,使用 Redis
缓存驱动名称
- CACHE_DRIVER=redis
redis 连接地址(可选)
- REDIS_HOST=172.17.0.1
redis 连接密码(可选)
- REDIS_PASSWORD=null
redis 连接端口(可选)
- REDIS_PORT=6379
6.5 修改配置项
- 系统设置 - 控制 - 关闭注册
- 系统设置 - 控制 - 关闭画廊
- 系统设置 - 控制 - 关闭游客上传
- 用户管理 - 编辑用户 - 修改总用量
10485760
(1024*1024*10
= 10G)
6.6 增加Minio存储策略
存储策略 - 新增存储策略
名称
Minio
存储策略
选择Minio
AccessKey
minio的AccessKeySecretKey
miniode的SecretKey连接地址
http://172.17.0.1:9090 这里直接填内网Minio的API地址区域填写
us-east-1
存储桶名称
填写image
点击确认创建,点击这里之后,不知道是不是兰空的bug,默认的图床始终无法更改为Minio,这里直接操作数据库修改默认图床。
到lsky_pro数据库的表 strategies
找到 Minio
的id及 groups
里 系统默认组&游客组
的id,往 group_strategy
里插入一条数据。假设这里的默认组的id为1,Minio存储策略为2,执行如下sql:
INSERT INTO `lsky_pro`.`group_strategy` (`group_id`, `strategy_id`) VALUES (1, 2);
7. Halo设置
- 应用市场 - 下载图床插件
- 插件 - 启用图床插件
- 点击图床插件详情 - 点击基本设置
API地址为兰空图床的访问路径(https://lsky.itweek.top) + /api/vi 。这里的 API Token
如何获取?
进入兰空图床后台管理页面,点击接口。
执行如下方法:
curl --location --request POST 'https://lsky.itweek.top/api/v1/tokens' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'Host: image.itweek.top' \
--header 'Connection: keep-alive' \
--data-raw '{
"email":"mulyzhou@gmail.com",
"password":"*******"
}'
修改https://lsky.itweek.top及 email
、password
,这里的 email
和 password
就是登录兰空图床管理后台的邮箱和账号。
执行之后返回的token即是授权token。
{
"status": true,
"message": "success",
"data": {
"token": "2|cCSkzG**********cgWoxhHXJ"
}
}
上述设置完毕之后就能在halo的后台,工具 - 图床管理 看到兰空图床的图片列表了。
至此整套halo使用兰空图床的环境就搭建完毕了。
8. 总结
这篇文档是一个详细的博客搭建指南,涵盖了从依赖的软件到目录结构等多个方面的内容。文档列出了搭建博客系统所需的软件及其用途,还解释了为什么要自建图床而不是使用第三方服务的理由,包括完全控制、隐私和安全、自定义功能、成本管理和无依赖性。