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 usually take a few minutes. The very first build on this server takes longer (about 5 to 10 minutes) while the runner downloads its build images. 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. Start your own node, which carries your pushes:rad node start. - Connect to this server's node so your pushes reach it:
rad node connect <node-id>@<this server>:8776 - Publish the repository. It has to be a Git repository with at least one commit:
git init -b main git add -A git commit -m "First commit" rad initrad initprints the 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:
It ends withdocker exec radicle-node rad seed rad:z… --scope all✗ Target not met: could not fetch from […]. That is about the public Radicle seeds, not this server, and can be ignored. The repository is in place once it shows in the Radicle explorer. - 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. Commit it (git add .gitea && git commit -m "Build the image").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.