当前位置: 首页 > news >正文

自建 Docker 镜像

本文地址:blog.lucien.ink/archives/547
本文主要参考自:自建Docker 镜像/源加速的方法

1. 简介

最近 Docker Hub 被禁一事引起了不小的波动,在这里简单讲下在这之后应该如何访问公开的 Docker Hub。

2. Cloudflare

2.1 搭建

搭建的前提是有一个在 Cloudflare 中被管理的域名,此处不展开介绍,在这里假设这个域名是 your-domain.com

2.1.1 创建 Worker

点击页面左侧的 Workers & Pages,创建一个 Worker,填入以下内容。请注意将 your-domain.com 替换为你自己的域名。

'use strict'const hub_host = 'registry-1.docker.io'
const auth_url = 'https://auth.docker.io'
const workers_url = 'https://your-domain.com'
/*** static files (404.html, sw.js, conf.js)*//** @type {RequestInit} */
const PREFLIGHT_INIT = {status: 204,headers: new Headers({'access-control-allow-origin': '*','access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS','access-control-max-age': '1728000',}),
}/*** @param {any} body* @param {number} status* @param {Object<string, string>} headers*/
function makeRes(body, status = 200, headers = {}) {headers['access-control-allow-origin'] = '*'return new Response(body, {status, headers})
}/*** @param {string} urlStr*/
function newUrl(urlStr) {try {return new URL(urlStr)} catch (err) {return null}
}addEventListener('fetch', e => {const ret = fetchHandler(e).catch(err => makeRes('cfworker error:\n' + err.stack, 502))e.respondWith(ret)
})/*** @param {FetchEvent} e*/
async function fetchHandler(e) {const getReqHeader = (key) => e.request.headers.get(key);let url = new URL(e.request.url);if (url.pathname === '/token') {let token_parameter = {headers: {'Host': 'auth.docker.io','User-Agent': getReqHeader("User-Agent"),'Accept': getReqHeader("Accept"),'Accept-Language': getReqHeader("Accept-Language"),'Accept-Encoding': getReqHeader("Accept-Encoding"),'Connection': 'keep-alive','Cache-Control': 'max-age=0'}};let token_url = auth_url + url.pathname + url.searchreturn fetch(new Request(token_url, e.request), token_parameter)}url.hostname = hub_host;let parameter = {headers: {'Host': hub_host,'User-Agent': getReqHeader("User-Agent"),'Accept': getReqHeader("Accept"),'Accept-Language': getReqHeader("Accept-Language"),'Accept-Encoding': getReqHeader("Accept-Encoding"),'Connection': 'keep-alive','Cache-Control': 'max-age=0'},cacheTtl: 3600};if (e.request.headers.has("Authorization")) {parameter.headers.Authorization = getReqHeader("Authorization");}let original_response = await fetch(new Request(url, e.request), parameter)let original_response_clone = original_response.clone();let original_text = original_response_clone.body;let response_headers = original_response.headers;let new_response_headers = new Headers(response_headers);let status = original_response.status;if (new_response_headers.get("Www-Authenticate")) {let auth = new_response_headers.get("Www-Authenticate");let re = new RegExp(auth_url, 'g');new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url));}if (new_response_headers.get("Location")) {return httpHandler(e.request, new_response_headers.get("Location"))}return new Response(original_text, {status,headers: new_response_headers})
}/*** @param {Request} req* @param {string} pathname*/
function httpHandler(req, pathname) {const reqHdrRaw = req.headers// preflightif (req.method === 'OPTIONS' &&reqHdrRaw.has('access-control-request-headers')) {return new Response(null, PREFLIGHT_INIT)}let rawLen = ''const reqHdrNew = new Headers(reqHdrRaw)const refer = reqHdrNew.get('referer')let urlStr = pathnameconst urlObj = newUrl(urlStr)/** @type {RequestInit} */const reqInit = {method: req.method,headers: reqHdrNew,redirect: 'follow',body: req.body}return proxy(urlObj, reqInit, rawLen, 0)
}/**** @param {URL} urlObj* @param {RequestInit} reqInit*/
async function proxy(urlObj, reqInit, rawLen) {const res = await fetch(urlObj.href, reqInit)const resHdrOld = res.headersconst resHdrNew = new Headers(resHdrOld)// verifyif (rawLen) {const newLen = resHdrOld.get('content-length') || ''const badLen = (rawLen !== newLen)if (badLen) {return makeRes(res.body, 400, {'--error': `bad len: ${newLen}, except: ${rawLen}`,'access-control-expose-headers': '--error',})}}const status = res.statusresHdrNew.set('access-control-expose-headers', '*')resHdrNew.set('access-control-allow-origin', '*')resHdrNew.set('Cache-Control', 'max-age=1500')resHdrNew.delete('content-security-policy')resHdrNew.delete('content-security-policy-report-only')resHdrNew.delete('clear-site-data')return new Response(res.body, {status,headers: resHdrNew})
}
2.1.2 添加域名

进入创建好的 Worker 的配置页面,在 Settings Tab 中选择 Triggers,点击 Add Custom Domain,添加 your-domain.com

2.2 使用

2.2.1 配置为镜像

/etc/docker/daemon.json 加入以下内容:

{"registry-mirrors": ["https://your-domain.com"]
}

然后重启 docker:systemctl restart docker

随后就能像往常一样直接 pull 了:

docker pull busybox:latest
docker pull mysql/mysql-server:latest
2.2.2 直接使用
docker pull your-domain.com/library/busybox:latest
docker pull your-domain.com/mysql/mysql-server:latest

3. 使用 registry

首先你需要一个能正常访问 Docker Hub 的机器,并在那台机器上正常安装 Docker。

3.1 搭建

找一个文件夹,编辑 compose.yml 文件,填入以下内容:

services:registry:image: registry:2ports:- "5000:5000"environment:REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io  # 上游源REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR: inmemory # 内存缓存,去掉本行以直接使用硬盘volumes:- ./data:/var/lib/registry

然后执行 docker compose up -d 即可。

3.2 使用

使用方法同上。

http://www.lryc.cn/news/368072.html

相关文章:

  • php实现抖音小程序支付
  • 代码审计(1):CVE-2022-4957分析及复现
  • 问题:设备管理指标为完好率不低于( ),待修率不高于5%,事故率不高于1%。 #知识分享#经验分享#经验分享
  • 【Linux】(六)—— vim编辑器
  • 06016传感器原理与应用202207
  • java web:springboot mysql开发的一套家政预约上门服务系统源码:家政上门服务系统的运行流程
  • 二叉树的后序遍历-力扣
  • C++基础编程100题-008 OpenJudge-1.3-06 甲流疫情死亡率
  • 计算机网络 ——网络层(IPv4地址)
  • 重写mybatisPlus自定义ID生成策略
  • 华为坤灵路由器配置SSH
  • 盘点一个Python网络爬虫的实战问题
  • 100道面试必会算法-32-二叉树右视图用栈实现队列
  • ⽀付逻辑漏洞思路⼩集合
  • 嵌入式学习——Linux高级编程复习(线程)——day40
  • kvm管理工具-virsh
  • VisionPro的应用和入门教程
  • 整数规划问题算法例子
  • C#启动一个cmd.exe多次随时输入命令并获取输出
  • 持续总结中!2024年面试必问 20 道分布式、微服务面试题(五)
  • Android输入法IME(三)之 管理端(IMMS)启动流程
  • elasticsearch安装与使用(4)-搜索入门
  • 【UML用户指南】-12-对高级结构建模-接口、类型和角色
  • C++笔试强训day42
  • Docker 中运行的 MySQL 数据库与 Docker 外部的管理系统连接
  • 10 设备树
  • 【架构分析】GPU执行GEMM矩阵运算实例演示
  • 从《千脑智能》看大模型
  • k8s Pods漂移时间配置
  • Python - json 美化格式、保存文件