Docker 搭建自用随机图片 API(含手机/电脑端自动分流)
前言
我们在美化博客(如 Halo)时,经常需要用到随机图片 API 作为文章封面或背景。市面上的免费 API 虽然多,但经常遇到不稳、挂掉或者 HTTPS 混合内容报错的问题。
与其依赖别人,不如利用手里的服务器(VPS)自己搭建一个。本文将分享一个 零依赖、纯 Docker、支持手机 / 电脑自动分流 的部署方案。
主要优势:
速度快:直接部署在自己的服务器上。
不报错:直接输出图片流(非重定向),完美解决 HTTPS 混合内容和防盗链问题。
智能分流:自动识别手机和电脑,返回不同尺寸的壁纸。
1. 准备工作
一台安装好 Docker 的服务器(如 Debian/Ubuntu)。
一个域名(用于配置 HTTPS)。
若干张喜欢的横屏和竖屏壁纸。
2. 部署步骤
2.1 创建项目目录
登录服务器,创建存放代码和图片的目录结构:
Bash
# 创建主目录
mkdir -p /opt/random-img
# 创建图片子目录(分别存放电脑和手机图)
mkdir -p /opt/random-img/images/pc
mkdir -p /opt/random-img/images/mobile
# 进入目录
cd /opt/random-img
2.2 编写核心代码 (index.php)
创建并编辑 index.php 文件:
Bash
vim index.php
粘贴以下代码。这段代码的核心逻辑是获取 User-Agent,判断设备类型后从对应文件夹读取图片,并直接输出二进制流。
PHP
<?php
/**
* 自建随机图片 API
* 特性:支持移动端/PC端分流,支持直接输出图片流(解决防盗链)
*/
// 1. 获取用户设备标识
$ua = $_SERVER['HTTP_USER_AGENT'];
// 2. 判断设备类型
// 如果包含 iPhone, Android, Mobile 等关键词,判定为手机
if (preg_match('/(iPhone|Android|Mobile)/i', $ua)) {
$path = './images/mobile/';
} else {
// 否则默认为电脑
$path = './images/pc/';
}
// 3. 读取目录下的图片
$files = array();
if (is_dir($path) && $handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
// 仅读取常见图片格式
if (preg_match("/\.(jpg|jpeg|png|gif|webp)$/i", $file)) {
$files[] = $file;
}
}
}
closedir($handle);
}
// 4. 错误处理
if (empty($files)) {
http_response_code(404);
die("Error: No images found in " . $path);
}
// 5. 随机抽取一张
$random_img = $files[array_rand($files)];
$file_path = $path . $random_img;
// 6. 输出图片头信息
$mime_type = mime_content_type($file_path);
header('Content-Type: ' . $mime_type);
header('Content-Length: ' . filesize($file_path));
// 禁止浏览器缓存 (确保每次刷新都是新图,且切换设备时不串图)
header("Cache-Control: no-cache, no-store, must-revalidate");
header("Pragma: no-cache");
header("Expires: 0");
// 7. 直接输出图片数据
readfile($file_path);
?>
2.3 编写 Docker 配置文件
创建 docker-compose.yml:
Bash
vim docker-compose.yml
粘贴以下内容:
YAML
version: '3'
services:
random-api:
image: php:8.2-apache
container_name: random-api
restart: always
ports:
- "8089:80" # 宿主机端口 8089,可自行修改
volumes:
- ./index.php:/var/www/html/index.php
- ./images:/var/www/html/images
logging:
driver: "json-file"
options:
max-size: "10m"
2.4 上传图片(重要)
将你的壁纸分别上传到对应目录:
横屏 / 电脑图 ->
/opt/random-img/images/pc/竖屏 / 手机图 ->
/opt/random-img/images/mobile/
2.5 修复权限问题(避坑关键点)
Docker 容器内的 Apache 默认使用 www-data 用户,如果你用 root 上传图片,容器可能会因为权限不足报错 Permission denied。
执行以下命令修复权限:
Bash
chmod -R 755 /opt/random-img/images
2.6 启动服务
Bash
docker compose up -d
3. 域名与 HTTPS 配置
为了让博客正常加载,建议配置反向代理并开启 HTTPS。
以 Nginx Proxy Manager 或 1Panel 为例:
添加反向代理。
域名:填写你的二级域名(如
img.example.com)。目标地址:
http://127.0.0.1:8089。申请并开启 SSL 证书(强制 HTTPS)。
4. 在 Halo 博客中调用
这是最后一步,也是最容易出错的一步。
在 Halo 后台 -> 设置 / 文章封面 中填写链接时,必须在链接末尾加上伪装后缀,欺骗 Halo 系统这是一张静态图片,否则无法保存或显示。
错误写法:
https://img.example.com/正确写法:
https://img.example.com/?.jpg
效果展示
PC 访问:自动加载横版大图。
手机访问:自动加载竖版壁纸。
速度:秒开,且无混合内容报错。




