fscarmen

fscarmen

GitHub 私库作图床集群,PicGO 上传,Cloudflare Workers加速,Gitlab 实时备份

视频教学#

前言和项目特点#

针对新建博客中大量使用图片,故需搭建一个私人图床。既要避免使用收费的商业云 oss 储存;又要在白嫖的前提下找个长期稳定的存放平台;还要兼顾访问速度;最好有异地灾备。为了实现这些目标,便有了以下综合解决方案。

方案特点和优势:

  • 图床集群矩阵:由多个 GitHub 仓库组成的存储系统。突破每个库 4G 大小的限制。每个仓库作为一个节点,形成一个整体资源存储网络。不同仓库之间既独立管理,又共同构成了一个分布式的多仓库集群。
  • 图片存储在 GitHub 私库:图片存放在 GitHub 私有仓库中,路径经过脱敏处理,确保安全性。
  • 自动压缩图片:通过自动压缩图片,提升加载速度,优化用户体验。
  • Cloudflare CDN 加速:利用 Cloudflare CDN 提供的全球加速服务,确保图片快速加载。
  • 自定义域名:支持使用自定义域名,集群里 n 个图库统一一个域名,提升品牌形象和专业性。
  • 多种链接形式输出:生成多种形式的图片链接,方便在博客或其他平台使用。
  • 实时备份到 Gitlab 私库(可选): 将 GitHub 实时备份到 GitLab 私有库提供了数据冗余和跨平台备份,增强了数据安全性和保障了业务连续性。

条件#

流程和工具介绍#

截图:使用 Snipaste 进行截图,这一款简单但强大的贴图工具,支持截屏、标注等功能,适用于 Windows 和 Mac。

PicGo 上传图片到 GitHub:使用 PicGo ,并安装 picgo-plugin-compress-next 插件,自动压缩图片后上传到 GitHub。

获取经过 Worker 处理的图片链接:自动生成经过 Worker 隐藏 GitHub 私库的 PAT,增加 CDN 和双栈,输出自定义域名 url。

** 自动从 GitHub 推送最新图片到 GitLab:使用 GitHub action,一旦数据有更新,自动化备份到 GitLab,避免图片全部丢失的风险。

详细关键步骤#

前置条件,获取 GitHub PAT 和 Tinypng API Key#

  • 登陆 GitHub,访问 https://github.com/settings/tokens 获取 PAT,并建一个私库用于存放图片,现在 GitHub 每个项目为 4G 大小,超过就再建新的可以了

image
image
image

  • 在 GitHub 里建一个私库用于存放图片,访问 https://github.com/new ,现在 GitHub 每个项目为 4G 大小,超过就再建新的可以了

image

image
image
image

PicGo 设置#

  • 安装好 PicGo 后,继续在软件里安装 picgo-plugin-compress-next 插件(此步可能需要开启科学)
    image
    image

  • 继续设置 PicGO 主程序

image
image
image
image

Cloudflare 创建 worker#

  • 登陆 Cloudflare,访问 https://dash.cloudflare.com/ ,新建 worker
    image

  • 部署后,编辑代码,复制并按图修改相应两处位置

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const GITHUB_USERNAME = '' // 设置你的 GitHub 用户名
  const GITHUB_PAT = ''  // 设置你的 GitHub PAT 令牌(Personal Access Token)
  const GITHUB_REPO_PREFIX = 'pic'        // 仓库前缀,需要结合仓库数量 REPO_COUNT 使用
  const REPO_COUNT = 10                   // 仓库数量。比如填10,结合前缀即为 pic1, pic2, ..., pic10
  const DIR = 'images'  // 仓库中的目录路径

  // 从请求的 URL 中获取文件名
  const REPOS = Array.from({ length: REPO_COUNT }, (_, i) => `${GITHUB_REPO_PREFIX}${i + 1}`)
  const url = new URL(request.url)
  const FILE = url.pathname.split('/').pop()  // 获取 URL 中的最后一部分作为文件名

  // 构建 GitHub raw 文件的 URL 列表
  const urls = REPOS.map(repo => `https://raw.githubusercontent.com/${GITHUB_USERNAME}/${repo}/main/${DIR}/${FILE}`)

  // 创建并发请求任务,向所有 GitHub raw 文件 URL 请求数据
  const requests = urls.map(githubUrl => {
    const modifiedRequest = new Request(githubUrl, {
      method: request.method,
      headers: {
        'Authorization': `token ${GITHUB_PAT}`,  // 使用 GitHub PAT 进行授权
        'Accept': 'application/vnd.github.v3.raw'
      }
    })
    return fetch(modifiedRequest).then(response => {
      if (response.ok) return response; // 如果响应成功返回该响应
      throw new Error(`Not Found in ${githubUrl}`); // 如果响应不成功抛出错误
    })
  })

  try {
    // 等待第一个成功的请求返回结果
    const response = await Promise.any(requests)

    // 创建新的响应,移除 Authorization 头部,避免信息泄露
    const newResponse = new Response(response.body, response)
    newResponse.headers.delete('Authorization')

    return newResponse

  } catch (error) {
    // 如果所有请求都失败,返回 404 错误
    return new Response(`404: File Not Found (${FILE}) in any repository`, { status: 404 })
  }
}

image

  • 添加自定义域名,有时候不能马上生效,可以用 worker 给的域名 https://<workerName>.<cloudflareUser>.workers.dev 先试试
    image

正式使用流程#

截图#

  • 使用 Snipaste 进行截图到粘贴板,可以使用快捷键 (默认 Ctrl + F1)

上传图片#

  • 通过 PicGo 上传图片到 GitHub,可以使用快捷键(默认 Ctrl + Shift + P)或拖拽图片到 PicGo 界面
  • 上传成功进度条是蓝色的,如果是红色,请检查设置是否有误。上传成功后自定义域名链接会自动在粘贴板
  • 在相应的场景 Blog 或者论坛等地址粘贴出来
    image
    image

实时备份到 Gitlab (可选)#

Gitlab 设置#

Github 设置#

  • 设置 3 个 secrets
Namesecret
GITLAB_USERNAMEGitlab 用户名
GITLAB_REPOGitlab 上创建的项目名
GITLAB_PAT上面生成的 Gitlab 项目的 PAT

image

  • 创建备份到 Gitlab 的工作流,路径和文件为

.github/workflows/sync-to-gitlab.yml
代码如下:

name: Sync to GitLab

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest

    env:
      GITLAB_USERNAME: ${{ secrets.GITLAB_USERNAME }}
      GITLAB_REPO: ${{ secrets.GITLAB_REPO }}
      GITLAB_PAT: ${{ secrets.GITLAB_PAT }}

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4.1.1
      with:
        fetch-depth: 0

    - name: Set up Git
      run: |
        git config --global user.name 'github-actions'
        git config --global user.email 'github-actions@github.com'

    - name: Add GitLab remote
      run: git remote add gitlab https://${{ env.GITLAB_USERNAME }}:${{ env.GITLAB_PAT }}@gitlab.com/${{ env.GITLAB_USERNAME }}/${{ env.GITLAB_REPO }}.git

    - name: Force push to GitLab
      run: git push gitlab main --force

image
image
image
image

图片案例#

https://img.forvps.gq/pic1/main/example/202410021622722.png

image

加载中...