IPDR is a Docker Registry tool that proxies Docker registry requests to IPFS for pushing and pulling images. IPDR allows you to store Docker images on IPFS instead of a central registry like Docker Hub or Google Container Registry. Docker images are referenced by their IPFS hash instead of the repo tag names.
IPDR is compatabile with the Docker Registry HTTP API V2 Spec for pulling images*
*not fully 1:1 implemented yet
High-level overview:
IPDR can be used in two main ways:
- Using the Local Registry Container: This method involves setting up IPDR registry. The IPDR registry contains the IPDR server and an IPFS node
- Using the IPDR Client with an IPFS Node: This standalone method requires only an IPFS Desktop Node and the IPDR client.
This setup allows you to use IPDR directly with an existing IPFS node, enabling Docker image management through IPFS without a full registry setup.
Install the IPDR client on your system to interact with IPFS directly:
# Download the latest release binaries
wget https://github.com/Metazla/ipdr/releases/download/x.x.x/ipdr_x.x.x_linux_amd64.tar.gz
tar -xvzf ipdr_x.x.x_linux_amd64.tar.gz
sudo mv ipdr /usr/local/bin/ipdr
# Check installation
ipdr --helpDownload the executable from IPDR Releases and add it to your system path.
If you have Go installed, you can install directly using:
go get -u github.com/Metazla/ipdr/cmd/ipdrWith IPDR installed, and the IPFS node running (must listen on the 5000 port API) you can push and pull Docker images to and from IPFS. Hereβs how you can use the IPDR client:
# Build a Docker image
docker build -t example/helloworld .
# Push the image to IPFS and get the IPFS hash
ipdr push example/helloworld
# On another machine, pull the image from IPFS using the hash
ipdr pull bafybeidb5pvdpggchtwj2pacw7zyxf7wtwotktrw6dn3iqtpbdktlb4diy
# Run the Docker image
docker run example/helloworldThe IPDR registry container integrates an IPFS node with the Docker registry capabilities provided by IPDR, facilitating a seamless Docker image management experience.
-
Download the latest Docker image:
- From GitHub: Navigate to IPDR Releases and download the appropriate image file.
- Directly from IPFS: Download using the IPFS hash provided in the releases page and rename the file to
file.tar.
-
Load and start the registry:
docker load --input file.tar
docker run -d -p 5000:5000 ipdr-server:latestOnce the registry is running, you can tag, push, and pull images:
# Tag your Docker image
docker tag example/helloworld localhost:5000/example/helloworld
# Push the image to IPFS via the IPDR registry
docker push localhost:5000/example/helloworld
# Pull the image to IPFS via the IPDR registry
docker pull localhost:5000/example/helloworld
# Pull and run the image from IPFS via your registry
docker run localhost:5000/example/helloworld$ ipdr --help
The command-line interface for the InterPlanetary Docker Registry.
More info: https://github.com/ipdr/ipdr
Usage:
ipdr [flags]
ipdr [command]
Available Commands:
convert Convert a hash to IPFS format or Docker registry format
help Help about any command
pull Pull image from the IPFS-backed Docker registry
push Push image to IPFS-backed Docker registry
server Start IPFS-backed Docker registry server
Flags:
-h, --help help for ipdr
Use "ipdr [command] --help" for more information about a command.-
Create
Dockerfile:FROM busybox:latest CMD echo 'hello world'
-
Build Docker image:
docker build -t example/helloworld .Test run:
$ docker run example/helloworld:latest hello world
-
Use IPDR CLI to push to IPFS:
$ ipdr push example/helloworld INFO[0000] [registry] temp: /var/folders/k1/m2rmftgd48q97pj0xf9csdb00000gn/T/205139235 INFO[0000] [registry] preparing image in: /var/folders/k1/m2rmftgd48q97pj0xf9csdb00000gn/T/657143846 INFO[0000] [registry] dist: /var/folders/k1/m2rmftgd48q97pj0xf9csdb00000gn/T/657143846/default/blobs/sha256:305510b2c684403553fd8f383e8d109b147df2cfde60e40a85564532c383c8b8 INFO[0000] [registry] compressing layer: /var/folders/k1/m2rmftgd48q97pj0xf9csdb00000gn/T/205139235/886f4bdfa483cc176e947c63d069579785c051793a9634f571fded7b9026cd3c/layer.tar INFO[0000] [registry] root dir: /var/folders/k1/m2rmftgd48q97pj0xf9csdb00000gn/T/657143846 INFO[0000] [registry] upload hash QmRxZ5Wffj6b1j8ckJLcr7yFrbHUhBYXsAMbj7Krwu1pp8 INFO[0000] [registry] uploaded to /ipfs/Qmc2ot2NQadXmbvPbsidyjYDvPfPwKZmovzNpfRPKxXUrL INFO[0000] [registry] docker image ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi Successfully pushed Docker image to IPFS: /ipfs/Qmc2ot2NQadXmbvPbsidyjYDvPfPwKZmovzNpfRPKxXUrL -
Use IPDR CLI to pull from IPFS:
$ ipdr pull /ipfs/QmagW4H1uE5rkm8A6iVS8WuiyjcWQzqXRHbM3KuUfzrCup INFO[0000] [registry/server] port 5000 INFO[0000] [registry] attempting to pull docker.local:5000/ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi INFO[0000] [registry/server] /v2/ INFO[0000] [registry/server] /v2/ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi/manifests/latest INFO[0000] [registry/server] location http://127.0.0.1:8080/ipfs/Qmc2ot2NQadXmbvPbsidyjYDvPfPwKZmovzNpfRPKxXUrL/manifests/latest-v2 {"status":"Pulling from ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi","id":"latest"} {"status":"Digest: sha256:1fb36e4704d6ebad5becdcfe996807de5f8db687da396330f112157c888c165b"} {"status":"Status: Downloaded newer image for docker.local:5000/ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi:latest"} Successfully pulled Docker image from IPFS: docker.local:5000/ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi -
Run image pulled from IPFS:
$ docker run docker.local:5000/ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi hello world
-
Retag Docker image:
$ docker tag docker.local:5000/ciqmw4mig2uwaygddjlutoywq43udutvdmuxkcxvetsjp2mjdde27wi example/helloworld:latest
-
We can also pull the image using
docker pull:-
First run the IPDR server in a seperate terminal:
$ ipdr server -p 5000 INFO[0000] [registry/server] listening on [::]:5000
-
Then convert the IPFS hash to a valid format docker allows:
$ ipdr convert QmYMg6WAuvF5i5yFmjT8KkqewZ5Ngh4U9Mp1bGfdjraFVk --format=docker ciqjjwaeoszdgcaasxmlhjuqnhbctgwijqz64w564lrzeyjezcvbj4y
-
Now we can
docker pullthe image from IPFS:$ docker pull docker.local:5000/ciqjjwaeoszdgcaasxmlhjuqnhbctgwijqz64w564lrzeyjezcvbj4y Using default tag: latest latest: Pulling from ciqjjwaeoszdgcaasxmlhjuqnhbctgwijqz64w564lrzeyjezcvbj4y Digest: sha256:6b787c9e04c2038d4b3cb0392417abdddfcfd88e10005d970fc751cdcfd6d895 Status: Downloaded newer image for docker.local:5000/ciqjjwaeoszdgcaasxmlhjuqnhbctgwijqz64w564lrzeyjezcvbj4y:latestTest run:
$ docker run docker.local:5000/ciqjjwaeoszdgcaasxmlhjuqnhbctgwijqz64w564lrzeyjezcvbj4y hello world
-
An example of using IPNS to resolve image tag names.
- First start local server:
ipdr server -p 5000- Tag the image:
docker pull hello-world
docker tag hello-world docker.local:5000/hello-world- Push to local registry:
docker push --quiet docker.local:5000/hello-worldCID mappings live under ~/.ipdr
$ tree ~/.ipdr/
/home/username/.ipdr/
βββ cids
βββ hello-world
βββ latest- Add cids directory to IPFS:
$ ipfs add -r ~/.ipdr/cids/ --quieter
QmVtjwa3kdFJHce2wnFuygaCHdSPXraBd4FRSEZKjqZWQp- Set
_dnslinkTXT record on the domain to point to the directory IPFS hash:
dnslink=/ipfs/QmVtjwa3kdFJHce2wnFuygaCHdSPXraBd4FRSEZKjqZWQp
- Verify DNS changes:
$ dig _dnslink.example.com -t TXT +short
"dnslink=/ipfs/QmVtjwa3kdFJHce2wnFuygaCHdSPXraBd4FRSEZKjqZWQp"- Re-run server, now with domain as resolver:
$ ipdr server --cid-resolver=example.com- Now we can run ipdr dig to get CID using repo tag name!
$ ipdr dig hello-world:latest
bafybeiakvswzlopeu573372p5xry47tkc2hhcg5q5rulmbfrnkecrbnt3yNote: if nothing is returned, then make sure the IPFS gateway is correct.
- Next pull and the docker image from IPFS using the resolved CID formatted for docker:
docker pull docker.local:5000/bafybeiakvswzlopeu573372p5xry47tkc2hhcg5q5rulmbfrnkecrbnt3y
docker run docker.local:5000/bafybeiakvswzlopeu573372p5xry47tkc2hhcg5q5rulmbfrnkecrbnt3y- Discuss on Discord
-
Q: How do I configure the local registry host or port that IPDR uses when pushing or pulling Docker images?
- A: Use the
--docker-registry-hostflag, eg.--docker-registry-host docker.for.mac.local:5000
- A: Use the
-
Q: How do I configure the IPFS host that IPDR uses for pushing Docker images?
- A: Use the
--ipfs-hostflag, eg.--ipfs-host 127.0.0.1:5001
- A: Use the
-
Q: How do I configure the IPFS gateway that IPDR uses for pulling Docker images?
- A: Use the
--ipfs-gatewayflag, eg.--ipfs-gateway https://ipfs.io
- A: Use the
-
Q: How can I configure the port for the IPDR registry server?
- A: Use the
--portflag, eg.--port 5000
- A: Use the
-
Q: How do I setup HTTPS/TLS on the IPDR registry server?
- A: Use the
--tlsKeyPathand--tlsCertPathflag, eg.--tlsKeyPath path/server.key --tlsCertPath path/server.crt
- A: Use the
-
Q: How do I get
docker.localto work?- A: Make sure to add
127.0.0.1 docker.localto/etc/hosts. Optionally, you may uselocal.ipdr.iowhich resolves to127.0.0.1
- A: Make sure to add
Pull requests are welcome!
For contributions please create a new branch and submit a pull request for review.
Many thanks to @qiangli and all the contributors that made this package better.
To improve the clarity and formatting of the build instructions for Windows, consider adding a structured, step-by-step format with explanations for each step. Here's a more organized version:
Follow these steps to dev on the solution the solution using Docker and IPFS on a Windows machine.
-
Start IPFS Desktop:
- Launch IPFS Desktop to ensure the IPFS daemon is running.
-
Start Docker Desktop:
- Open Docker Desktop to have Docker ready for building and pushing images.
-
Create a Release Snapshot with GoReleaser:
- Run the following command to create a release snapshot. This cleans up any previous builds to avoid conflicts.
goreleaser release --snapshot --clean docker build -t example/helloworld . dist\ipdr_windows_amd64_v1\ipdr.exe push example/helloworld
- Run the following command to create a release snapshot. This cleans up any previous builds to avoid conflicts.
Ensure that each tool required (IPFS Desktop, Docker Desktop, GoReleaser, IPDR) is installed on your system before starting the build process.
make testReleased under the MIT license.
Β© Miguel Mota

