視頻教程#
前言和項目特點#
-
本文介紹用 GitLab 作為圖庫並用 GitHub 作為備份。
-
前面介紹了如何用 GitHub 作為圖庫並用 GitLab 作為備份,【GitHub 私庫作圖床,PicGO 上傳,Cloudflare Workers 加速,Gitlab 實時備份】 ,此為反向操作。
-
針對新建博客中大量使用圖片,故需搭建一個私人圖床。既要避免使用收費的商業雲 oss 儲存;又要在白嫖的前提下找個長期穩定的存放平台;還要兼顧訪問速度;最好有異地災備。為了實現這些目標,便有了以下綜合解決方案。
方案特點和優勢:
- 存儲在 GitLab 私庫:圖片存放在 GitLab 私有倉庫中,路徑經過脫敏處理,確保安全性;平台比 GitHub 還要穩。
- 自動壓縮圖片:通過自動壓縮圖片,提升加載速度,優化用戶體驗。
- Cloudflare CDN 加速:利用 Cloudflare CDN 提供的全球加速服務,確保圖片快速加載。
- 自定義域名:支持使用自定義域名,提升品牌形象和專業性。
- 多種鏈接形式輸出:生成多種形式的圖片鏈接,方便在博客或其他平台使用。
- 實時備份到 GitHub 私庫(可選): 將 GitLab 實時備份到 GitHub 私有庫提供了數據冗餘和跨平台備份,增強了數據安全性和保障了業務連續性。
條件#
- GitLab 帳號,https://gitlab.com
- GitHub 帳號,可選項,如不需要備份可忽略,https://github.com
- Cloudflare 帳號,https://www.cloudflare.com
- Tinypng 帳號,https://tinypng.com/developers
- 安裝 Snipaste,https://zh.snipaste.com
- 安裝 PicGo,https://molunerfinn.com/PicGo
流程和工具介紹#
截圖:使用 Snipaste 進行截圖,這一款簡單但強大的貼圖工具,支持截屏、標註等功能,適用於 Windows 和 Mac。
PicGo 上傳圖片到 GitHub:使用 PicGo ,並安裝 picgo-plugin-compress-next 插件,自動壓縮圖片後上傳到 GitHub。
獲取經過 Worker 處理的圖片鏈接:自動生成經過 Worker 隱藏 GitLab 私庫的 API,增加 CDN 和雙棧,輸出自定義域名 url。
自動從 GitHub 推送最新圖片到 GitLab:使用 GitLab CI/CD,一旦數據有更新,自動化備份到 GitHub,避免圖片全部丟失的風險。
詳細關鍵步驟#
前置條件,新建 GitLab 私庫,獲取 GitLab API 和項目 ID#
- 登錄 GitHub,訪問 https://gitlab.com/projects/new#blank_project 新建項目,並建一個私庫用於存放圖片,現在 GitLab 每個項目為 4G 大小,超過就再建新的可以了
- 獲取項目讀寫權限的 API
- 獲取項目 ID
獲取 Tinypng API Key#
- 註冊 Tinypng.com 帳號,訪問 https://tinypng.com/developers 註冊
PicGo 設置#
- 安裝好 PicGo 後,繼續在軟件裡安裝 picgo-plugin-compress-next 插件(此步可能需要開啟科學)
- 安裝好 gitlab-file 插件(此步可能需要開啟科學)
- 繼續設置 PicGO 主程序
名稱 | 介紹及配置示例 |
---|---|
圖床配置名 | 起個自己便記的即可,默認 Default |
gitlab 伺服器地址 | https://gitlab.com |
項目 id | 填寫前面獲取的 GitLab 項目 ID |
默認分支 | 填 main ,如填其他,後面的 worker 反代要作相應的改動 |
gitlab 的 token | 填寫前面獲取的 GitLab 項目 API (PicGo 會明文保存) |
檔名及其路徑 | <圖片存放的自定義路徑>/{fileName} |
上傳檔案的 Message | Upload {fileName} By PicGo gitlab files uploader at {year}-{month}-{day} |
自定義鏈接格式 | !(https://<worker 自定義域名>/<GitLab 圖庫項目名>/<圖片存放的自定義目錄,可以多層>/$fileName$extName) |
Cloudflare 創建 worker#
- 登錄 Cloudflare,訪問 https://dash.cloudflare.com/ ,新建 worker
- 部署後,編輯代碼,複製並按圖修改相應兩處位置
// 定義 GitLab 倉庫名稱、倉庫 ID 和 API 令牌
const REPO_CONFIG = [
{ name: 'repoName1', id: 'repoID1', token: 'repoAPI1' },
{ name: 'repoName2', id: 'repoID2', token: 'repoAPI2' },
{ name: 'repoName3', id: 'repoID3', token: 'repoAPI3' },
];
async function handleRequest(request) {
const url = new URL(request.url);
const pathParts = url.pathname.split('/').filter(Boolean);
console.log('URL:', url.toString());
console.log('Path parts:', pathParts);
if (pathParts.length < 1) {
return new Response('Invalid URL format', { status: 400 });
}
const gitlabRepo = pathParts[0];
console.log('Requested repo:', gitlabRepo);
const repoConfig = REPO_CONFIG.find(repo => repo.name === gitlabRepo);
if (!repoConfig) {
console.log('Repository not found in config. Available repos:', REPO_CONFIG.map(r => r.name));
return new Response('Repository not found', { status: 404 });
}
const { id: gitlabRepoId, token: gitlabApiToken } = repoConfig;
// 獲取剩余路徑並進行編碼
const remainingPath = pathParts.slice(1).join('/');
const encodedPath = encodeURIComponent(remainingPath);
console.log('Remaining path:', remainingPath);
console.log('Encoded path:', encodedPath);
// 構建 GitLab API URL
const apiUrl = `https://gitlab.com/api/v4/projects/${gitlabRepoId}/repository/files/${encodedPath}/raw?ref=main`;
console.log('GitLab API URL:', apiUrl);
try {
// 發起請求到 GitLab API
const response = await fetch(apiUrl, {
method: 'GET',
headers: {
'PRIVATE-TOKEN': gitlabApiToken
}
});
console.log('GitLab API response status:', response.status);
if (!response.ok) {
return new Response(`Error fetching from GitLab: ${response.statusText}`, { status: response.status });
}
// 返回 GitLab 的響應
const contentType = response.headers.get('Content-Type');
const body = await response.arrayBuffer();
console.log('Content-Type:', contentType);
return new Response(body, {
status: response.status,
headers: {
'Content-Type': contentType,
'Cache-Control': 'public, max-age=3600' // 緩存一小時
}
});
} catch (error) {
console.error('Error:', error);
return new Response(`An error occurred: ${error.message}`, { status: 500 });
}
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
- 添加自定義域名,可以用 worker 給的域名
https://<workerName>.<cloudflareUser>.workers.dev
先試試
正式使用流程#
截圖#
- 使用 Snipaste 進行截圖到粘貼板,可以使用快捷鍵 (默認 Ctrl + F1)
上傳圖片#
- 通過 PicGo 上傳圖片到 GitHub,可以使用快捷鍵(默認 Ctrl + Shift + P)或拖拽圖片到 PicGo 界面
- 上傳成功進度條是藍色的,如果是紅色,請檢查設置是否有誤。上傳成功後自定義域名鏈接會自動在粘貼板
- 在相應的場景 Blog 或者論壇等地址粘貼出來
實時備份到 GitHub (可選)#
Github 設置#
- 登錄 GitHub,創建備份項目庫,訪問 https://github.com/new
Gitlab 設置#
有兩個方法,選其中一種即可:1. 使用 GitLab 平台的鏡像功能(推薦); 2. 使用 CI/CD 工作流
方式 1:GitLab 平台的鏡像功能#
方式 2:通過 CI/CD pipeline#
- 在 CI/CD 處創建三個環境變量
變量 | 說明 |
---|---|
GITHUB_USERNAME | GitHub 的用戶名 |
GITHUB_REPO | 填寫前面創建的 GitHub 備份庫名字 |
GITHUB_PAT | 填寫前面獲取的 GitHub PAT Token |
- 創建備份到 GitHub 的 CI/CD Pipeline,代碼如下:
image: alpine:latest
variables:
GIT_STRATEGY: clone
before_script:
- apk add --no-cache curl git
sync_to_github:
script:
- |
# 獲取本地和GitHub遠程倉庫最新commit hash,並顯示
LOCAL_COMMIT=$(git rev-parse HEAD)
REMOTE_COMMIT=$(curl -s -H "Authorization: token ${GITHUB_PAT}" "https://api.github.com/repos/${GITHUB_USERNAME}/${GITHUB_REPO}/commits/main" | awk -F '"' '/"sha":/{print $4; exit}')
echo "Local commit: $LOCAL_COMMIT"
echo "Remote commit: $REMOTE_COMMIT"
# 比較本地和遠程commit,如有更新,則推送到GitHub
if [ "$LOCAL_COMMIT" != "$REMOTE_COMMIT" ]; then
echo "Pushing updates to GitHub..."
git config --global user.email "${GITHUB_USERNAME}@gitlab.com"
git config --global user.name "${GITHUB_USERNAME}"
git remote add github https://${GITHUB_PAT}@github.com/${GITHUB_USERNAME}/${GITHUB_REPO}.git
git push github HEAD:main --force
else
echo "No updates needed."
fi
rules:
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "web"
圖片案例#
https://pic.forvps.gq/pic2/images/202410081627933.png