搭建DockerHub代理,Docker设置代理以及加速镜像设置
DockerHub使用CF Workers代码加速
打开CF Workers创建应用程序,创建项目名docker,使用src/index.js代码
部署好了修改 docker.libcuda.so替换成自己域名
d.iii80.workers.dev 或者在 设置--触发器--自定义域--添加自定义域,也就是自己的域名,例如docker.wan8.eu.org
然后重新部署更新下,搞定,用这两个域名替换代理源。
也可以使用别人搭建的代理或者公共镜像代理,写入到系统配置中。
直接命令写入中国镜像源地址:
XML/HTML代码
- sudo mkdir -p /etc/docker
- sudo tee /etc/docker/daemon.json <<EOF
- {
- "registry-mirrors": ["https://do.nark.eu.org"]
- }
- EOF
- sudo systemctl daemon-reload
- sudo systemctl restart docker
也可以使用下面命令直接下载:
XML/HTML代码
- 原镜像
- docker pull whyour/qinglong:latest
- 加速镜像
- docker pull 你的域名/whyour/qinglong:latest
通过http/https代理加速
创建 dockerd 相关的 systemd 目录,这种 .d 目录下的配置将覆盖默认配置
sudo mkdir -p /etc/systemd/system/docker.service.d
新建配置文件 http-proxy.conf
sudo vim /etc/systemd/system/docker.service.d/proxy.conf
添加配置,修改 HTTP 代理的地址
XML/HTML代码
- [Service]
- Environment="HTTP_PROXY=http://127.0.0.1:10809/"
- Environment="HTTPS_PROXY=http://127.0.0.1:10809/"
- Environment="NO_PROXY=127.0.0.1,localhost,192.168.*,*.example.com"
# 如果 `NO_PROXY=*`,那么所有请求都将不通过代理服务器
重新加载配置文件,重启 Dockerd 才能生效
sudo systemctl daemon-reload
sudo systemctl restart docker
检查确认环境变量已经正确配置:
sudo systemctl show --property=Environment docker
可以拉取镜像试试了
以上均以Debian系统测试。
Docker的代理配置
dockerd代理
在执行docker pull时,是由守护进程dockerd来执行。 因此,代理需要配在dockerd的环境中。 而这个环境,则是受systemd所管控,因此实际是systemd的配置。
XML/HTML代码
- sudo mkdir -p /etc/systemd/system/docker.service.d
- sudo touch /etc/systemd/system/docker.service.d/proxy.conf
在这个proxy.conf文件(可以是任意*.conf的形式)中,添加以下内容:
XML/HTML代码
- [Service]
- Environment="HTTP_PROXY=http://proxy.example.com:8080/"
- Environment="HTTPS_PROXY=http://proxy.example.com:8080/"
- Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
其中,proxy.example.com:8080要换成可用的免密代理。 通常使用cntlm在本机自建免密代理,去对接公司的代理。 可参考《Linux下安装配置Cntlm代理》。
Container代理
在容器运行阶段,如果需要代理上网,则需要配置~/.docker/config.json。 以下配置,只在Docker 17.07及以上版本生效。
XML/HTML代码
- {
- "proxies":
- {
- "default":
- {
- "httpProxy": "http://proxy.example.com:8080",
- "httpsProxy": "http://proxy.example.com:8080",
- "noProxy": "localhost,127.0.0.1,.example.com"
- }
- }
- }
此外,容器的网络代理,也可以直接在其运行时通过-e注入http_proxy等环境变量。 这两种方法分别适合不同场景。 config.json非常方便,默认在所有配置修改后启动的容器生效,适合个人开发环境。 在CI/CD的自动构建环境、或者实际上线运行的环境中,这种方法就不太合适,用-e注入这种显式配置会更好,减轻对构建、部署环境的依赖。 当然,在这些环境中,最好用良好的设计避免配置代理上网。
docker build代理
虽然docker build的本质,也是启动一个容器,但是环境会略有不同,用户级配置无效。 在构建时,需要注入http_proxy等参数。
XML/HTML代码
- docker build . \
- --build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \
- --build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \
- --build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \
- -t your/image:tag
注意:无论是docker run还是docker build,默认是网络隔绝的。 如果代理使用的是localhost:3128这类,则会无效。 这类仅限本地的代理,必须加上--network host才能正常使用。 而一般则需要配置代理的外部IP,而且代理本身要开启gateway模式。
重启生效
代理配置完成后,reboot重启当然可以生效,但不重启也行。
docker build代理是在执行前设置的,所以修改后,下次执行立即生效。 Container代理的修改也是立即生效的,但是只针对以后启动的Container,对已经启动的Container无效。
dockerd代理的修改比较特殊,它实际上是改systemd的配置,因此需要重载systemd并重启dockerd才能生效。
sudo systemctl daemon-reload
sudo systemctl restart docker
小常识:
Openclash可以直接配置代理
1、系统ip设置成Openclash的IP可以直接旁路由科学
2、打开Openclash的UI管理,设置里面可以直接设置SOCKS5/HTTP(S)代理
默认:HTTP 代理端口 7890 Socks5 代理端口 7891 混合代理端口 7893 允许来自局域网的连接 勾选
3、设置 SOCKS5/HTTP(S) 认证信息(有账号密码认证的代理)
覆写设置--设置 SOCKS5/HTTP(S) 认证信息--添加账号密码
至于Passwwall和ShadowSocksR Plus+也都只默认支持代理转换成SOCKS5代理的。
附改进版 CF Works 代码:
XML/HTML代码
- 'use strict'
- const hub_host = 'registry-1.docker.io'
- const auth_url = 'https://auth.docker.io'
- const workers_url = 'https://do.nark.eu.org'
- const workers_host = 'do.nark.eu.org'
- const home_page_url = 'https://qninq.cn/file/html/dockerproxy.html'
- /** @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 === '/') {
- // Fetch and return the home page HTML content with replacement
- let response = await fetch(home_page_url);
- let text = await response.text();
- texttext = text.replace(/{workers_host}/g, workers_host);
- return new Response(text, {
- status: response.status,
- headers: response.headers
- });
- }
- 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.search
- return 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_responseoriginal_response_clone = original_response.clone();
- let original_text = original_response_clone.body;
- let response_headers = original_response.headers;
- let newnew_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"))
- }
- let response = new Response(original_text, {
- status,
- headers: new_response_headers
- })
- return response;
- }
- /**
- * @param {Request} req
- * @param {string} pathname
- */
- function httpHandler(req, pathname) {
- const reqreqHdrRaw = req.headers
- // preflight
- if (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 = pathname
- const 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 resresHdrOld = res.headers
- const resHdrNew = new Headers(resHdrOld)
- // verify
- if (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.status
- resHdrNew.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
- })
- }
此代码为最简单的 dockerhub 的代理,仅需要新建一个 Workers ,粘贴代码,部署即可,不需要复杂设置。
1Panel代理:https://docker.1panel.live
国内 Docker 服务状态 & 镜像加速监控:https://status.1panel.top