IPCR Forge
From git push to docker pull on any server, without a central
service. Code lives on Radicle, Gitea Actions builds it, and IPCR serves the image from IPFS.
gitea_admin.
Published imagesWhat this server serves from IPFS, with the line to put in a compose file.
How it works
git push rad a v* tag to the Radicle network.gitea/workflows/ are copied into Giteaipcr.localhost:4767/ipns/…Steps 2 to 4 are automatic and take two to three minutes. A repository needs no configuration beyond committing a workflow.
Published images
Loading…
Publish a project
- Install Radicle on your machine and create an identity: see
radicle.xyz, then
rad auth. - Connect to this server's node so your pushes reach it:
rad node connect <node-id>@<this server>:8776 - Publish the repository from its folder:
rad init. It prints a repository ID (rad:z…). - Let this node seed it. The node only keeps repositories it is told to (seeding policy
block). In this server's Terminal app or over SSH:
docker exec radicle-node rad seed rad:z… --scope all - Add a workflow at
.gitea/workflows/build.yml. This one builds theDockerfileat the root and publishes it for everyv*tag. TheREGISTRY_TOKENsecret is already set for every repository.on: push: tags: ['v*'] jobs: image: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Registry address id: registry run: echo "host=${GITHUB_SERVER_URL#https://}" >> "$GITHUB_OUTPUT" - uses: docker/metadata-action@v5 id: meta with: images: ${{ steps.registry.outputs.host }}/${{ github.repository }} tags: | type=semver,pattern={{version}} type=raw,value=latest - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ${{ steps.registry.outputs.host }} username: ${{ github.repository_owner }} password: ${{ secrets.REGISTRY_TOKEN }} - uses: docker/build-push-action@v6 with: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - Release:
Follow the build in Gitea undergit tag v1.0.0 git push rad main v1.0.0gitea_admin/<repo>→ Actions. A minute after it finishes, the tag appears under Published images.
Use an image
Copy the line from Published images into a compose file. It works on this server and on any server running IPCR:
services:
myapp:
image: ipcr.localhost:4767/ipns/k51qzi5uqu5d…:1.0.0 # a tag: follows new builds of 1.0.0
# image: ipcr.localhost:4767/ipfs/bafkrei… # a CID: this exact image, forever
/ipns/<name>:<tag> is a name the publisher can move to a new build.
/ipfs/<cid> is the image's content address and can never change.
For a readable name, add a DNS TXT record _dnslink.example.com =
dnslink=/ipns/k51… to a domain you own. The image is then
ipcr.localhost:4767/ipns/example.com:1.0.0.
Pull from another server
Any server with IPCR resolves the same lines and fetches the image from the IPFS network, from this server and from every other server that already pulled it.
On a Yundera server
Install IPCR from the App Store. There is nothing to configure.
On any Linux server with Docker 29+
mkdir -p /DATA/AppData/ipcr && cd /DATA/AppData/ipcr
curl -fsSLO https://raw.githubusercontent.com/Yundera/ipcr/main/apps/IPCR/docker-compose.yml
install -d -m 0700 -o 1000 -g 1000 kubo && install -d -o 1000 -g 1000 init.d
curl -fsSL -o init.d/01-ipcr-node.sh https://raw.githubusercontent.com/Yundera/ipcr/main/apps/IPCR/seed/init.d/01-ipcr-node.sh
chmod 0755 init.d/01-ipcr-node.sh
printf 'PUID=1000\nPGID=1000\nTZ=UTC\nAppID=ipcr\n' > .env
docker compose up -d
IPCR listens on 127.0.0.1:4767 only, and trusts itself through
/etc/docker/certs.d/ipcr.localhost:4767/ca.crt. It publishes port 4768 (TCP and UDP)
for IPFS peers. Details: github.com/Yundera/ipcr.