Docker Compose部署隨機圖API
平時我們部署部落格的時候,為了考慮美觀會考慮使用隨機圖來作為文章的封面,現在有很多大佬願意提供隨機圖API,透過API我們可以很方便地部署隨機圖,不必自己尋找圖片,考慮頻寬支出
不過很多時候一些公益API訪問速度很慢,其中很多圖片並不是我們所想要的,這時候我們就要考慮自建隨機圖API了,我參考了很多教程,他們中的很多都是基於寶塔來實現的,但其實我們不必要安裝寶塔皮膚,完全可以在Docker內實現
前置準備
首先我們先建立一個資料夾來方式我們的docker-compose
和其他的隨機圖檔案,並且進入該資料夾內:
mkdir random-pic && cd random-pic
之後上傳隨機圖的php
檔案,在這裡有三個版本,其中一個版本我嘗試過無法使用(可能是我沒有正確使用?
原理介紹
隨機圖的基本實現是透過新建一個站點,透過向站點傳送請求,站點檔案將請求重定向(301)到隨機圖所在圖鏈,從而實現隨機圖切換:
圖片準備
獲取到原始圖片之後,我建議你對圖片繼續壓縮處理,常見的諸如將圖片轉換成webp
,這能有效減小檔案體積,加快使用者端的載入速度,如果你使用的是物件儲存或者套了CDN的話,這能減小頻寬和費用壓力
在這裡推薦一下來自Google的Squoosh,是一個很全能的圖片壓縮程式,不用下載,直接在瀏覽器中就可以使用:網址
基本上支援了常見圖片型別的轉換和壓縮:
版本1(不支援桌面與移動端切換
<?php
//存放api隨機圖連結的檔名img.txt
$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)];
$pic = $pics[random_int(0, count($pics) - 1)]; # 真隨機
//返回指定格式
$type=$_GET['type'];
switch($type){
//JSON返回
case 'json':
header('Content-type:text/json');
die(json_encode(['pic'=>$pic]));
default:
die(header("Location: $pic"));
}
?>
此時你要在該資料夾內新建一個img.txt
檔案,用來儲存隨機圖的圖鏈,這裡的圖鏈就決定了你圖片載入的速度,請務必選擇一些速度比較快的圖床,這能夠有效提高使用體驗和載入速度:
此時你的檔案結構應該如下,有img.txt
和random.php
兩個檔案
.
├── img.txt
└── random.php
版本2(支援桌面與移動端切換
<?php
// 函式:訪客裝置
function is_mobile() {
if (empty($_SERVER['HTTP_USER_AGENT']) ||
strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') !== false) {
// 因為iPad有類似於PC的長寬比,所以我設定為電腦端
$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";
}
//存放api隨機圖連結的檔名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){
//JSON返回
case 'json':
header('Content-type:text/json');
die(json_encode(['pic'=>$pic]));
default:
die(header("Location: $pic"));
}
?>
使用這種方法,你需要額外新增一個img_mobile.txt
檔案來放置用於移動端的圖片,檔案內容同img.txt
此時你的檔案結構應該如下:
.
├── img_mobile.txt
├── img.txt
└── random.php
版本3(尚未成功
此版本需要引用Mobile_Detect.php
,用於檢測使用者的裝置型別(如手機、平板、桌面等),你需要自行去GitHub上下載原始碼,並且將它放置到此資料夾內:
- 訪問 GitHub 倉庫:
- 訪問 Mobile_Detect GitHub 倉庫。
- 下載 ZIP 檔案:
- 在倉庫頁面上,點選綠色的 “Code” 按鈕,然後選擇 “Download ZIP” 以下載整個倉庫的壓縮包。
- 解壓並找到
Mobile_Detect.php
:- 解壓下載的 ZIP 檔案,在解壓後的目錄中,找到
src/Mobile_Detect.php
檔案。
- 解壓下載的 ZIP 檔案,在解壓後的目錄中,找到
- 將檔案放到正確的位置:
- 將
Mobile_Detect.php
檔案放置到你的專案目錄中,例如/root/random-pic/
。
- 將
之後random.php
的內容為:
<?php
/*
* 函式:訪客裝置
* 部落格園:https://www.cnblogs.com/freephp/p/13979503.html
* Github: https://github.com/serbanghita/Mobile-Detect
*/
function is_mobile(){
require(__DIR__ . '/MobileDetect.php'); // 修正檔案路徑
$MobileDetect = new Mobile_Detect();
if ($MobileDetect->isTablet()) {
// 平板定義為PC類
return false;
} elseif ($MobileDetect->isMobile()) {
return true;
} else {
return false;
}
}
// 電腦與手機用不同的桌布
$filename = is_mobile() ? "img_mobile.txt" : "img.txt";
// 存放api隨機圖連結的檔名
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){
// JSON 返回
case 'json':
header('Content-type: application/json'); // 修正 Content-type
die(json_encode(['pic' => $pic]));
default:
die(header("Location: $pic"));
}
?>
此時還是需要新增img_mobile.txt
,同版本2
此時檔案結構如下:
.
├── img_mobile.txt
├── img.txt
├── MobileDetect.php
└── random.php
Docker Compose部署
為了部署這個站點,在這裡我們直接使用Docker Compose進行操作:
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
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;
}
}
寫入後儲存,你的檔案結構應該是這樣的:
.
├── default.conf
├── docker-compose.yaml
├── img_mobile.txt
├── img.txt
└── random.php
之後正式啟動容器
docker compose up -d
之後訪問域名+埠即可看到隨機圖效果
後語
個人感覺給隨機圖域名套上CDN還是有意義的,因為這個嚴格來說也算個靜態網站,如果有CDN快取的話隨機圖的切換速度會變快很多
如果你對類似專案感興趣的話,不妨訪問我的小站小樹 | Docker Compose部署隨機圖API
參考文獻:Docker系列 WordPress系列 自建隨機圖API之靜態桌布