Skip to content
Snippets Groups Projects
Select Git revision
  • main
1 result

ipfs-container-registry

  • Clone with SSH
  • Clone with HTTPS
  • Name Last commit Last update
    .gitignore
    LICENSE
    README.md
    generate.sh

    IPFS Container Registry - Like Docker Hub but everywhere

    This repository aims to provide a statically hostable container registry, served over IPFS.

    Required tools

    • GNU bash
    • GNU findutils
    • GNU coreutils
    • skopeo
    • ipfs

    Usage

    Start your ipfs daemon and run the generate script:

    $ ./generate.sh <image reference>

    Example:

    $ ./generate.sh docker.io/nginx:alpine
    Getting image source signatures
    Copying blob a0d0a0d46f8b done  
    Copying blob 4dd4efe90939 done  
    Copying blob c1368e94e1ec done  
    Copying blob 3e72c40d0ff4 done  
    Copying blob 969825a5ca61 done  
    Copying blob 61074acc7dd2 done  
    Writing manifest to image destination
    Storing signatures
    rm: cannot remove './registry/v2/nginx/manifests/sha256:6b0577bfa961af964eba99c023e9f4b79c0546b1e6db0988d12cdf98e801b01e': No such file or directory
    rm: cannot remove './registry/v2/nginx/manifests/alpine': No such file or directory
    added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH registry/v2/index.html
    added QmXuNZUQ5aMAt3W7UNFPipvWN5GtYBo7fCMd3xtLfhG2Eu registry/v2/nginx/blobs/sha256:3e72c40d0ff43c52c5cc37713b75053e8cb5baea8e137a784d480123814982a2
    added QmPgpSkvbkuDQkSTWjr39tSPWJhC8kpsCJnQKWQDGZXeQu registry/v2/nginx/blobs/sha256:4dd4efe90939ab5711aaf5fcd9fd8feb34307bab48ba93030e8b845f8312ed8e
    added QmRvtx1Um6d354NPPHScYy2mrqRGesyqYRRuurvLh4Sm6o registry/v2/nginx/blobs/sha256:61074acc7dd227cfbeaf719f9b5cdfb64711bc6b60b3865c7b886b7099c15d15
    added QmW1QnmNFRZbqQyDLgNXo7egY9v3QdVHMhWKGM6RUovxcC registry/v2/nginx/blobs/sha256:969825a5ca61c8320c63ff9ce0e8b24b83442503d79c5940ba4e2f0bd9e34df8
    added QmUzxSBZZnapnj9y2iTtpXBMSr9vwMMix2rLCEpSonRJLg registry/v2/nginx/blobs/sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e
    added QmRCsXVnbyvbQewGnQXc7berXzZfRwi7J1qQd3dBUW4Xad registry/v2/nginx/blobs/sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    added QmY2NobBa1pQk5N1kNu2r27W2mX8qJ6srPmuHs8rhQAnPh registry/v2/nginx/blobs/sha256:c1368e94e1ec563b31c3fb1fea02c9fbdc4c79a95e9ad0cac6df29c228ee2df3
    added QmfH6vDuicd752ADNwEH3K78E8omaGW4M1XMHuNs1b1hKS registry/v2/nginx/manifests/alpine
    added QmfH6vDuicd752ADNwEH3K78E8omaGW4M1XMHuNs1b1hKS registry/v2/nginx/manifests/sha256:6b0577bfa961af964eba99c023e9f4b79c0546b1e6db0988d12cdf98e801b01e
    added QmQsbLEXGMG5jfsCeQ3PvcdPi3pkcMruC91mXwNrrY3rTb registry/v2/nginx/tags/list
    added QmSC7b3SddgVerVbgsn5Dsvg78uDHC94iEsag8d3CK95vR registry/v2/nginx/blobs
    added QmeWtL4twN3bCpDX5vx26k4EpkgaqrAWdmaBtn5e5WcJdz registry/v2/nginx/manifests
    added QmfHHcf688FLnNZV85z5Bk9kg9CEGXQrTEQ76wDtLBrgJZ registry/v2/nginx/tags
    added QmfNp4bJcbbJW1F39VmSaUjtRuCnwWt72uPf1uEBF3UjmC registry/v2/nginx
    added QmTQSDfoMgH6tYc7ew4aZaJm6PJuRiDfWyWfJU4xuVLk8S registry/v2
    added QmQRbSGCsbo1Pu3Ce1u7jA1aFA7Ta3GAbwkFoVHoeEkMJy registry
     9.53 MiB / 9.53 MiB [================================================================================================================================] 100.00%
    

    Then copy the last reference for the registry directory (QmQRbSGCsbo1Pu3Ce1u7jA1aFA7Ta3GAbwkFoVHoeEkMJy in the example) and either publish it through a dnslink (e.g. _dnslink.registry.example.com).

    Point the DNS entry for this dnslinked address (registry.example.com) to a IPFS gateway (for example 127.0.0.1 with default gateway port 8080) and you can run your image using podman run --tls-verify=false -p 80:80 registry.example.com:8080/nginx:latest. Check what curl localhost:80 returns and enjoy!

    Why?!?

    Currently docker registries always require some active software on the server-side often being directly exposed to the internet including writing operations. This projects aims to make container images statically hostable and therefore make it just another directory on your webserver.

    Once this static hosting is achieved, one can put the content on IPFS, making it trivial to cache, share and keeping available. As long as one node on the IPFS network has pinned a specific version of a container image it's available to the world. And since IPFS is content-addressable, there is no way, it's manipulated if you pull it by it's /ipfs/<CID>-address.

    With all this, the goal is to make Kubernetes bootstrapping registry independent and reduce the requirement to keep third-party registries active in a cluster.

    Oh, and by the way, since docker images are already immutable, they reproduce perfectly on the IPFS network making sharing and deduplication across registries working like a dream.

    TODOs

    This is a PoC, it obviously requires some proper tooling.

    Lessons learned

    When there are no headers, podman expects Image manifest version 2 schema 1. skopeo downloads whatever format is available by the registry, therefore in order to be compatible it's required to explicitly set the format to v2s1.

    Registries are "pinged" before images are pulled, therefore it's important to return 200 from the /v2/ endpoint. One can force an IPFS gateway to serve a 200 by creating and empty index.html.

    find and xargs are fun on their own but even more fun together. Even though the resulting command might be challenging to read.

    Resources

    Implemented Endpoints / Compatibility

    Method API Endpoint Status
    GET /v2/ Implemented
    GET /v2/<name>/blobs/<digest> Completely implemented
    GET /v2/<name>/manifests/<reference> Completely implemented
    GET /v2/<name>/tags/list Basic functionality, currently the generation of the required JSON was too hairy to do it just in bash. Something that can properly serialise JSON should do this easily.
    GET /v2/<name>/tags/list?n=<integer>&last=<integer> Not possible, parameters are ignored by IPFS Gateways

    Obviously, since this is a static registry, there is no writeable endpoint. Error codes are also not implemented due to incompatiblity with IPFS serving.