4 Commits

Author SHA1 Message Date
ciiiii
527d2edc28 Fix production configuration 2024-06-14 02:32:51 +08:00
ciiiii
5eaf7124a3 Fix staging configuration 2024-06-14 02:31:02 +08:00
ciiiii
b7de5d1414 Fix ci 2024-06-14 02:16:59 +08:00
ciiiii
ae982cd6c7 Deploy staging env 2024-06-14 02:14:48 +08:00
8 changed files with 566 additions and 3618 deletions

View File

@@ -16,12 +16,8 @@ jobs:
- uses: actions/checkout@v4
- name: Publish
uses: cloudflare/wrangler-action@v3
env:
CUSTOM_DOMAIN: ${{ secrets.CUSTOM_DOMAIN || 'libcuda.so' }}
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{secrets.CF_ACCOUNT_ID}}
vars:
CUSTOM_DOMAIN
command: deploy --env production --minify src/index.js
environment: production

23
.github/workflows/stage.yaml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Deploy to Cloudflare Workers(Staging)
on:
pull_request:
branches:
- master
paths-ignore:
- '**.md'
repository_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
name: Build & Deploy
steps:
- uses: actions/checkout@v4
- name: Publish
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{secrets.CF_ACCOUNT_ID}}
command: deploy --env staging --minify src/index.js
environment: staging

View File

@@ -1,14 +1,5 @@
# cloudflare-docker-proxy
> ### ⚠️ **Important Notice**
> <span style="color:#d73a49;font-weight:bold">Docker Hub is rate-limiting Cloudflare Worker IPs, causing frequent <code>429</code> errors.</span>
> <span style="color:#d73a49;font-weight:bold">This project is currently NOT recommended for production use.</span>
Due to the current instability, this project is not recommended for production use.
We will provide updates as soon as more information becomes available.
![deploy](https://github.com/ciiiii/cloudflare-docker-proxy/actions/workflows/deploy.yaml/badge.svg)
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/ciiiii/cloudflare-docker-proxy)
@@ -17,13 +8,13 @@ We will provide updates as soon as more information becomes available.
## Deploy
1. click the "Deploy With Workers" button
2. follow the instructions to fork and deploy
3. update routes as you requirement
1. fork this project
2. modify the link of the above button to your fork url
3. click the button, you will be redirected to the deploy page
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/ciiiii/cloudflare-docker-proxy)
## Routes configuration tutorial
## Config tutorial
1. use cloudflare worker host: only support proxy one registry
```javascript

3023
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@
"scripts": {
"format": "prettier --write '**/*.{js,css,json,md}'",
"build": "webpack",
"dev": "npx wrangler dev src/index.js --env dev"
"dev": "wrangler dev src/index.js --env dev"
},
"license": "MIT",
"main": "src/index.js"

View File

@@ -7,17 +7,16 @@ const dockerHub = "https://registry-1.docker.io";
const routes = {
// production
["docker." + CUSTOM_DOMAIN]: dockerHub,
["quay." + CUSTOM_DOMAIN]: "https://quay.io",
["gcr." + CUSTOM_DOMAIN]: "https://gcr.io",
["k8s-gcr." + CUSTOM_DOMAIN]: "https://k8s.gcr.io",
["k8s." + CUSTOM_DOMAIN]: "https://registry.k8s.io",
["ghcr." + CUSTOM_DOMAIN]: "https://ghcr.io",
["cloudsmith." + CUSTOM_DOMAIN]: "https://docker.cloudsmith.io",
["ecr." + CUSTOM_DOMAIN]: "https://public.ecr.aws",
"docker.libcuda.so": dockerHub,
"quay.libcuda.so": "https://quay.io",
"gcr.libcuda.so": "https://gcr.io",
"k8s-gcr.libcuda.so": "https://k8s.gcr.io",
"k8s.libcuda.so": "https://registry.k8s.io",
"ghcr.libcuda.so": "https://ghcr.io",
"cloudsmith.libcuda.so": "https://docker.cloudsmith.io",
// staging
["docker-staging." + CUSTOM_DOMAIN]: dockerHub,
"docker-staging.libcuda.so": dockerHub,
};
function routeByHosts(host) {
@@ -32,9 +31,6 @@ function routeByHosts(host) {
async function handleRequest(request) {
const url = new URL(request.url);
if (url.pathname == "/") {
return Response.redirect(url.protocol + "//" + url.host + "/v2/", 301);
}
const upstream = routeByHosts(url.hostname);
if (upstream === "") {
return new Response(
@@ -61,9 +57,24 @@ async function handleRequest(request) {
redirect: "follow",
});
if (resp.status === 401) {
return responseUnauthorized(url);
if (MODE == "debug") {
headers.set(
"Www-Authenticate",
`Bearer realm="http://${url.host}/v2/auth",service="cloudflare-docker-proxy"`
);
} else {
headers.set(
"Www-Authenticate",
`Bearer realm="https://${url.hostname}/v2/auth",service="cloudflare-docker-proxy"`
);
}
return new Response(JSON.stringify({ message: "UNAUTHORIZED" }), {
status: 401,
headers: headers,
});
} else {
return resp;
}
return resp;
}
// get token
if (url.pathname == "/v2/auth") {
@@ -108,23 +119,9 @@ async function handleRequest(request) {
const newReq = new Request(newUrl, {
method: request.method,
headers: request.headers,
// don't follow redirect to dockerhub blob upstream
redirect: isDockerHub ? "manual" : "follow",
redirect: "follow",
});
const resp = await fetch(newReq);
if (resp.status == 401) {
return responseUnauthorized(url);
}
// handle dockerhub blob redirect manually
if (isDockerHub && resp.status == 307) {
const location = new URL(resp.headers.get("Location"));
const redirectResp = await fetch(location.toString(), {
method: "GET",
redirect: "follow",
});
return redirectResp;
}
return resp;
return await fetch(newReq);
}
function parseAuthenticate(authenticateStr) {
@@ -149,28 +146,9 @@ async function fetchToken(wwwAuthenticate, scope, authorization) {
if (scope) {
url.searchParams.set("scope", scope);
}
const headers = new Headers();
headers = new Headers();
if (authorization) {
headers.set("Authorization", authorization);
}
return await fetch(url, { method: "GET", headers: headers });
}
function responseUnauthorized(url) {
const headers = new Headers();
if (MODE == "debug") {
headers.set(
"Www-Authenticate",
`Bearer realm="http://${url.host}/v2/auth",service="cloudflare-docker-proxy"`
);
} else {
headers.set(
"Www-Authenticate",
`Bearer realm="https://${url.hostname}/v2/auth",service="cloudflare-docker-proxy"`
);
}
return new Response(JSON.stringify({ message: "UNAUTHORIZED" }), {
status: 401,
headers: headers,
});
}

View File

@@ -6,25 +6,21 @@ ip = "0.0.0.0"
port = 8787
local_protocol = "http"
[env.vars]
CUSTOM_DOMAIN = "libcuda.so"
[env.dev.vars]
MODE = "debug"
TARGET_UPSTREAM = "https://registry-1.docker.io"
CUSTOM_DOMAIN = "exmaple.com"
[env.production]
name = "cloudflare-docker-proxy"
# routes = [
# { pattern = "docker.libcuda.so", custom_domain = true },
# { pattern = "quay.libcuda.so", custom_domain = true },
# { pattern = "gcr.libcuda.so", custom_domain = true },
# { pattern = "k8s-gcr.libcuda.so", custom_domain = true },
# { pattern = "k8s.libcuda.so", custom_domain = true },
# { pattern = "ghcr.libcuda.so", custom_domain = true },
# { pattern = "cloudsmith.libcuda.so", custom_domain = true },
# ]
routes = [
{ pattern = "docker.libcuda.so", custom_domain = true },
{ pattern = "quey.libcuda.so", custom_domain = true },
{ pattern = "gcr.libcuda.so", custom_domain = true },
{ pattern = "k8s-gcr.libcuda.so", custom_domain = true },
{ pattern = "k8s.libcuda.so", custom_domain = true },
{ pattern = "ghcr.libcuda.so", custom_domain = true },
{ pattern = "cloudsmith.libcuda.so", custom_domain = true },
]
[env.production.vars]
MODE = "production"
@@ -32,7 +28,7 @@ TARGET_UPSTREAM = ""
[env.staging]
name = "cloudflare-docker-proxy-staging"
# route = { pattern = "docker-staging.libcuda.so", custom_domain = true }
route = { pattern = "docker-staging.libcuda.so", custom_domain = true }
[env.staging.vars]
MODE = "staging"

1013
yarn.lock

File diff suppressed because it is too large Load Diff