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.

79 lines · 3.7 KBRaw History
1# Diffinery runner image (Cloudflare Containers, linux/amd64).
2# Build context: containers/runner. Run `pnpm build` first so dist/agent.mjs exists.
3#
4# docker build --platform linux/amd64 -t diffinery-runner containers/runner
5ARG BASE_IMAGE=ubuntu:24.04
6FROM ${BASE_IMAGE}
7
8ARG NODE_VERSION=22.22.0
9
10ENV DEBIAN_FRONTEND=noninteractive \
11 LANG=C.UTF-8 \
12 LC_ALL=C.UTF-8 \
13 DIFFINERY_WORK_ROOT=/workspace \
14 RUNNER_TOOL_CACHE=/opt/hostedtoolcache \
15 AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache \
16 COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
17 # What hosted ubuntu-24.04 runners report; setup-* actions key their caches on it.
18 ImageOS=ubuntu24 \
19 ImageVersion=20250101.1 \
20 # Ubuntu 24.04 marks the system Python as externally managed (PEP 668);
21 # CI scripts commonly `pip install` directly, so allow it like hosted runners do.
22 PIP_BREAK_SYSTEM_PACKAGES=1
23
24RUN apt-get update \
25 && apt-get install -y --no-install-recommends \
26 ca-certificates curl git git-lfs jq zip unzip xz-utils tar gzip zstd \
27 build-essential pkg-config openssh-client gnupg \
28 python3 python3-pip python3-venv python-is-python3 \
29 && git config --system --add safe.directory '*' \
30 && git lfs install --system --skip-repo \
31 && apt-get clean \
32 && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
33
34# Node.js LTS from the official tarball (checksum-verified), with corepack shims for pnpm/yarn.
35RUN set -eux; \
36 cd /tmp; \
37 file="node-v${NODE_VERSION}-linux-x64.tar.xz"; \
38 curl -fsSLO "https://nodejs.org/dist/v${NODE_VERSION}/${file}"; \
39 curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/SHASUMS256.txt" | grep " ${file}\$" | sha256sum -c -; \
40 tar -xJf "${file}" -C /usr/local --strip-components=1 --no-same-owner \
41 --exclude='*/CHANGELOG.md' --exclude='*/README.md' --exclude='*/LICENSE' --exclude='*/include/*' --exclude='*/share/doc/*'; \
42 rm -f "${file}"; \
43 corepack enable; \
44 corepack prepare pnpm@10.28.0 --activate; \
45 corepack prepare yarn@1.22.22 --activate; \
46 node --version; npm --version; pnpm --version; yarn --version; \
47 npm cache clean --force; \
48 rm -rf /root/.npm /tmp/*
49
50# GitHub CLI (preinstalled on hosted runners; workflows call `gh` with GH_TOKEN).
51RUN set -eux; \
52 install -m 0755 -d /etc/apt/keyrings; \
53 curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg -o /etc/apt/keyrings/githubcli-archive-keyring.gpg; \
54 echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list; \
55 apt-get update; \
56 apt-get install -y --no-install-recommends gh; \
57 apt-get clean; \
58 rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
59
60# Docker Engine, started on first use by the /usr/local/bin/docker wrapper. Cloudflare
61# Containers run it rootful with iptables, so bridge networks, service DNS, port
62# publishing and builds all work like on GitHub's hosted runners.
63RUN set -eux; \
64 install -m 0755 -d /etc/apt/keyrings; \
65 curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc; \
66 echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list; \
67 apt-get update; \
68 apt-get install -y --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin iptables; \
69 apt-get clean; \
70 rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
71COPY image/daemon.json /etc/docker/daemon.json
72COPY image/docker /usr/local/bin/docker
73
74RUN mkdir -p /workspace /opt/hostedtoolcache /opt/diffinery
75COPY dist/agent.mjs /opt/diffinery/agent.mjs
76
77WORKDIR /workspace
78EXPOSE 8080
79ENTRYPOINT ["node", "/opt/diffinery/agent.mjs"]