Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

71 lines · 3.2 KBRaw History
1name: Docker in Cloudflare Containers
2
3# Checks whether a Cloudflare Container can run a Docker daemon (rootful or
4# rootless), so hosted Diffinery runners can offer Docker. Deploys a throwaway
5# probe Worker with a container, prints what worked, and removes it.
6# Uses the repository secrets CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.
7on:
8 workflow_dispatch:
9
10permissions:
11 contents: read
12
13jobs:
14 probe:
15 name: Probe Docker inside a container
16 runs-on: ubuntu-latest
17 # The Cloudflare secrets are the production environment's.
18 environment: production
19 timeout-minutes: 40
20 env:
21 CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
22 CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
23 NAME: diffinery-dind-probe-${{ github.run_id }}
24 steps:
25 - uses: actions/checkout@v4
26 - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
27 - uses: actions/setup-node@v4
28 with:
29 node-version: 22
30 cache: pnpm
31 - run: pnpm install --frozen-lockfile
32 - name: Deploy the probe
33 working-directory: apps/diffinery/scripts/dind-probe
34 run: |
35 set -euo pipefail
36 # Test the runner image's real Docker wrapper and daemon config.
37 cp ../../../../containers/runner/image/docker ../../../../containers/runner/image/daemon.json .
38 cat > wrangler.json <<JSON
39 {"name":"$NAME","main":"worker.js","compatibility_date":"2026-10-01","workers_dev":true,
40 "containers":[{"class_name":"Probe","image":"./Dockerfile","instance_type":"standard-2","max_instances":1}],
41 "durable_objects":{"bindings":[{"name":"PROBE","class_name":"Probe"}]},
42 "migrations":[{"tag":"v1","new_sqlite_classes":["Probe"]}]}
43 JSON
44 pnpm --dir "$GITHUB_WORKSPACE/apps/diffinery" exec wrangler deploy -c "$PWD/wrangler.json"
45 sub=$(curl -sS "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/subdomain" -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq -r '.result.subdomain // empty')
46 echo "PROBE_URL=https://$NAME.$sub.workers.dev" >> "$GITHUB_ENV"
47 - name: Run the probe
48 run: |
49 set -uo pipefail
50 for i in $(seq 1 60); do
51 curl -fsS -m 30 -o /dev/null "$PROBE_URL/run" && break
52 sleep 10
53 done
54 for i in $(seq 1 120); do
55 out=$(curl -sS -m 30 "$PROBE_URL/log")
56 grep -q "PROBE DONE" <<<"$out" && break
57 sleep 10
58 done
59 echo "$out"
60 echo "::group::Summary"
61 grep '^RESULT' <<<"$out" | tee -a "$GITHUB_STEP_SUMMARY"
62 echo "::endgroup::"
63 - name: Remove the probe
64 if: always()
65 working-directory: apps/diffinery/scripts/dind-probe
66 run: |
67 W=(pnpm --dir "$GITHUB_WORKSPACE/apps/diffinery" exec wrangler)
68 [ -f wrangler.json ] && "${W[@]}" delete -c "$PWD/wrangler.json" --force || true
69 for id in $("${W[@]}" containers list --json 2>/dev/null | jq -r --arg n "$NAME" '.[] | select(.name | startswith($n)) | .id'); do
70 "${W[@]}" containers delete "$id" -c "$PWD/wrangler.json" || true
71 done