Docker Compose部署随机图API
平时我们部署博客的时候,为了考虑美观会考虑使用随机图来作为文章的封面,现在有很多大佬愿意提供随机图API,通过API我们可以很方便地部署随机图,不必自己寻找图片,考虑带宽支出
不过很多时候一些公益API访问速度很慢,其中很多图片并不是我们所想要的,这时候我们就要考虑自建随机图API了,我参考了很多教程,他们中的很多都是基于宝塔来实现的,但其实我们不必要安装宝塔面板,完全可以在Docker内实现
前置准备
首先我们先建立一个文件夹来方式我们的docker-compose
和其他的随机图文件,并且进入该文件夹内:
1
| mkdir random-pic && cd random-pic
|
之后上传随机图的php
文件,在这里有三个版本,其中一个版本我尝试过无法使用(可能是我没有正确使用?
原理介绍
随机图的基本实现是通过新建一个站点,通过向站点发送请求,站点文件将请求重定向(301)到随机图所在图链,从而实现随机图切换:
图片准备
获取到原始图片之后,我建议你对图片继续压缩处理,常见的诸如将图片转换成webp
,这能有效减小文件体积,加快用户端的加载速度,如果你使用的是对象存储或者套了CDN的话,这能减小带宽和费用压力
在这里推荐一下来自Google的Squoosh,是一个很全能的图片压缩程序,不用下载,直接在浏览器中就可以使用:网址
基本上支持了常见图片类型的转换和压缩:
版本1(不支持桌面与移动端切换
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
| <?php
$filename = "img.txt"; if(!file_exists($filename)){ die('文件不存在'); }
$pics = []; $fs = fopen($filename, "r"); while(!feof($fs)){ $line=trim(fgets($fs)); if($line!='' && substr($str , 0 , 1) != '#'){ array_push($pics, $line); } }
$pic = $pics[random_int(0, count($pics) - 1)];
$type=$_GET['type']; switch($type){
case 'json': header('Content-type:text/json'); die(json_encode(['pic'=>$pic])); default: die(header("Location: $pic")); } ?>
|
此时你要在该文件夹内新建一个img.txt
文件,用来保存随机图的图链,这里的图链就决定了你图片加载的速度,请务必选择一些速度比较快的图床,这能够有效提高使用体验和加载速度:
此时你的文件结构应该如下,有img.txt
和random.php
两个文件
1 2 3
| . ├── img.txt └── random.php
|
版本2(支持桌面与移动端切换
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 53 54 55 56 57 58 59 60 61 62
| <?php
function is_mobile() { if (empty($_SERVER['HTTP_USER_AGENT']) || strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') !== false) { $is_mobile = false; } elseif ( strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mobi') !== false ) { $is_mobile = true; } else { $is_mobile = false; } return $is_mobile; }
if(is_mobile()){ $filename = "img_mobile.txt"; }else{ $filename = "img.txt"; }
if(!file_exists($filename)){ die('文件不存在'); }
$pics = []; $fs = fopen($filename, "r"); while(!feof($fs)){ $line=trim(fgets($fs)); if($line!='' && substr($str , 0 , 1) != '#'){ array_push($pics, $line); } }
$pic = $pics[array_rand($pics)];
$type=$_GET['type']; switch($type){
case 'json': header('Content-type:text/json'); die(json_encode(['pic'=>$pic])); default: die(header("Location: $pic")); } ?>
|
使用这种方法,你需要额外添加一个img_mobile.txt
文件来放置用于移动端的图片,文件内容同img.txt
此时你的文件结构应该如下:
1 2 3 4
| . ├── img_mobile.txt ├── img.txt └── random.php
|
版本3(尚未成功
此版本需要引用Mobile_Detect.php
,用于检测用户的设备类型(如手机、平板、桌面等),你需要自行去GitHub上下载源码,并且将它放置到此文件夹内:
- 访问 GitHub 仓库:
- 下载 ZIP 文件:
- 在仓库页面上,点击绿色的 “Code” 按钮,然后选择 “Download ZIP” 以下载整个仓库的压缩包。
- **解压并找到
Mobile_Detect.php
**:
- 解压下载的 ZIP 文件,在解压后的目录中,找到
src/Mobile_Detect.php
文件。
- 将文件放到正确的位置:
- 将
Mobile_Detect.php
文件放置到你的项目目录中,例如 /root/random-pic/
。
之后random.php
的内容为:
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 53 54 55
| <?php
function is_mobile(){ require(__DIR__ . '/MobileDetect.php'); $MobileDetect = new Mobile_Detect(); if ($MobileDetect->isTablet()) { return false; } elseif ($MobileDetect->isMobile()) { return true; } else { return false; } }
$filename = is_mobile() ? "img_mobile.txt" : "img.txt";
if(!file_exists($filename)){ die('文件不存在'); }
$pics = []; $fs = fopen($filename, "r"); while(!feof($fs)){ $line = trim(fgets($fs)); if($line != '' && substr($line, 0, 1) != '#'){ array_push($pics, $line); } } fclose($fs);
$pic = $pics[random_int(0, count($pics) - 1)];
$type = $_GET['type'] ?? ''; switch($type){
case 'json': header('Content-type: application/json'); die(json_encode(['pic' => $pic])); default: die(header("Location: $pic")); } ?>
|
此时还是需要添加img_mobile.txt
,同版本2
此时文件结构如下:
1 2 3 4 5
| . ├── img_mobile.txt ├── img.txt ├── MobileDetect.php └── random.php
|
Docker Compose部署
为了部署这个站点,在这里我们直接使用Docker Compose进行操作:
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
| version: '3.8' services: web: image: nginx:latest ports: - "9000:80" volumes: - /root/random-pic:/usr/share/nginx/html - ./default.conf:/etc/nginx/conf.d/default.conf container_name: random-pic depends_on: - php-fpm networks: - mynetwork
php-fpm: image: php:7.4-fpm volumes: - /root/random-pic:/usr/share/nginx/html networks: - mynetwork
networks: mynetwork: driver: bridge
|
这里为了方便测试我们不占用80端口,而是使用9000端口,之后使用Nginx或者其他工具进行反代即可
此时不要急着启动容器,我们还需要定制一下Nginx
的配置文件:
此时新建一个default.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server { listen 80; server_name localhost;
root /usr/share/nginx/html; index random.php;
location ~ \.php$ { include fastcgi_params; fastcgi_pass php-fpm:9000; fastcgi_index random.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
|
写入后保存,你的文件结构应该是这样的:
1 2 3 4 5 6
| . ├── default.conf ├── docker-compose.yaml ├── img_mobile.txt ├── img.txt └── random.php
|
之后正式启动容器
之后访问域名+端口即可看到随机图效果
后语
个人感觉给随机图域名套上CDN还是有意义的,因为这个严格来说也算个静态网站,如果有CDN缓存的话随机图的切换速度会变快很多
参考文献:Docker系列 WordPress系列 自建随机图API之静态壁纸