github.com/containerd/nerdctl@v1.7.7/docs/ipfs.md (about) 1 # Distribute Container Images on IPFS (Experimental) 2 3 | :zap: Requirement | nerdctl >= 0.14 | 4 |-------------------|-----------------| 5 6 You can distribute container images without registries, using IPFS. 7 8 IPFS support is completely optional. Your host is NOT connected to any P2P network, unless you opt in to [install and run IPFS daemon](https://docs.ipfs.io/install/). 9 10 ## Prerequisites 11 12 ### ipfs daemon 13 14 Make sure an IPFS daemon such as [Kubo](https://github.com/ipfs/kubo) (former go-ipfs) is running on your host. 15 For example, you can run Kubo using the following command. 16 17 ``` 18 ipfs daemon 19 ``` 20 21 In rootless mode, you need to install ipfs daemon using `containerd-rootless-setuptool.sh`. 22 23 ``` 24 containerd-rootless-setuptool.sh -- install-ipfs --init 25 ``` 26 27 > NOTE: correctly set IPFS_PATH as described in the output of the above command. 28 29 :information_source: If you want to expose some ports of ipfs daemon (e.g. 4001), you can install rootless containerd using `containerd-rootless-setuptool.sh install` with `CONTAINERD_ROOTLESS_ROOTLESSKIT_FLAGS="--publish=0.0.0.0:4001:4001/tcp"` environment variable. 30 31 :information_source: If you don't want IPFS to communicate with nodes on the internet, you can run IPFS daemon in offline mode using `--offline` flag or you can create a private IPFS network as described [here](https://github.com/containerd/stargz-snapshotter/blob/main/docs/ipfs.md#appendix-1-creating-ipfs-private-network). 32 33 :information_source: Instead of locally launching IPFS daemon, you can specify the address of the IPFS API using `--ipfs-address` flag. 34 35 ## IPFS-enabled image and OCI Compatibility 36 37 Image distribution on IPFS is achieved by OCI-compatible *IPFS-enabled image format*. 38 nerdctl automatically converts an image to IPFS-enabled when necessary. 39 For example, when nerdctl pushes an image to IPFS, if that image isn't an IPFS-enabled one, it converts that image to the IPFS-enabled one. 40 41 Please see [the doc in stargz-snapshotter project](https://github.com/containerd/stargz-snapshotter/blob/v0.10.0/docs/ipfs.md) for details about IPFS-enabled image format. 42 43 ## Using nerdctl with IPFS 44 45 nerdctl supports an image name prefix `ipfs://` to handle images on IPFS. 46 47 ### `nerdctl push ipfs://<image-name>` 48 49 For `nerdctl push`, you can specify `ipfs://` prefix for arbitrary image names stored in containerd. 50 When this prefix is specified, nerdctl pushes that image to IPFS. 51 52 ```console 53 > nerdctl push ipfs://ubuntu:20.04 54 INFO[0000] pushing image "ubuntu:20.04" to IPFS 55 INFO[0000] ensuring image contents 56 bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze 57 ``` 58 59 At last line of the output, the IPFS CID of the pushed image is printed. 60 You can use this CID to pull this image from IPFS. 61 62 You can also specify `--estargz` option to enable [eStargz-based lazy pulling](https://github.com/containerd/stargz-snapshotter/blob/v0.10.0/docs/ipfs.md) on IPFS. 63 Please see the later section for details. 64 65 ```console 66 > nerdctl push --estargz ipfs://fedora:36 67 INFO[0000] pushing image "fedora:36" to IPFS 68 INFO[0000] ensuring image contents 69 INFO[0011] converted "application/vnd.docker.image.rootfs.diff.tar.gzip" to sha256:cd4be969f12ef45dee7270f3643f796364045edf94cfa9ef6744d91d5cdf2208 70 bafkreibp2ncujcia663uum25ustwvmyoguxqyzjnxnlhebhsgk2zowscye 71 ``` 72 73 ### `nerdctl pull ipfs://<CID>` and `nerdctl run ipfs://<CID>` 74 75 You can pull an image from IPFS by specifying `ipfs://<CID>` where `CID` is the CID of the image. 76 77 ```console 78 > nerdctl pull ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze 79 bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze: resolved |++++++++++++++++++++++++++++++++++++++| 80 index-sha256:28bfa1fc6d491d3bee91bab451cab29c747e72917efacb0adc4e73faffe1f51c: done |++++++++++++++++++++++++++++++++++++++| 81 manifest-sha256:f6eed19a2880f1000be1d46fb5d114d094a59e350f9d025580f7297c8d9527d5: done |++++++++++++++++++++++++++++++++++++++| 82 config-sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1: done |++++++++++++++++++++++++++++++++++++++| 83 layer-sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54: done |++++++++++++++++++++++++++++++++++++++| 84 elapsed: 1.2 s total: 27.2 M (22.7 MiB/s) 85 ``` 86 87 `nerdctl run` also supports the same image name syntax. 88 When specified, this command pulls the image from IPFS. 89 90 ```console 91 > nerdctl run --rm -it ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze echo hello 92 hello 93 ``` 94 95 You can also push that image to the container registry. 96 97 ``` 98 nerdctl tag ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze ghcr.io/ktock/ubuntu:20.04-ipfs 99 nerdctl push ghcr.io/ktock/ubuntu:20.04-ipfs 100 ``` 101 102 The pushed image can run on other (IPFS-agnostic) runtimes. 103 104 ```console 105 > docker run --rm -it ghcr.io/ktock/ubuntu:20.04-ipfs echo hello 106 hello 107 ``` 108 109 :information_source: Note that though the IPFS-enabled image is OCI compatible, some runtimes including [containerd](https://github.com/containerd/containerd/pull/6221) and [podman](https://github.com/containers/image/pull/1403) had bugs and failed to pull that image. Containerd fixed this since v1.5.8, podman fixed this since commit [`b55fb86c28b7d743cf59701332cd78d4294c7c54`](https://github.com/containers/image/commit/b55fb86c28b7d743cf59701332cd78d4294c7c54). 110 111 ### `nerdctl build` and `localhost:5050/ipfs/<CID>` image reference 112 113 You can build images using base images on IPFS. 114 BuildKit >= v0.9.3 is needed. 115 116 In Dockerfile, instead of `ipfs://` prefix, you need to use the following image reference to point to an image on IPFS. 117 118 ``` 119 localhost:5050/ipfs/<CID> 120 ``` 121 122 Here, `CID` is the IPFS CID of the image. 123 124 :information_source: In the futural version of nerdctl and BuildKit, `ipfs://` prefix should be supported in Dockerfile. 125 126 Using this image reference, you can build an image on IPFS. 127 128 ```dockerfile 129 FROM localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze 130 RUN echo hello > /hello 131 ``` 132 133 Make sure that `nerdctl ipfs registry serve` is running. 134 This allows `nerdctl build` to pull images from IPFS. 135 136 ``` 137 $ nerdctl ipfs registry serve & 138 ``` 139 140 Then you can build this Dockerfile using `nerdctl build`. 141 142 ```console 143 > nerdctl build -t hello . 144 [+] Building 5.3s (6/6) FINISHED 145 => [internal] load build definition from Dockerfile 0.0s 146 => => transferring dockerfile: 146B 0.0s 147 => [internal] load .dockerignore 0.0s 148 => => transferring context: 2B 0.0s 149 => [internal] load metadata for localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze:latest 0.1s 150 => [1/2] FROM localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze@sha256:28bfa1fc6d491d3bee91bab451cab29c747e72917e 3.8s 151 => => resolve localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze@sha256:28bfa1fc6d491d3bee91bab451cab29c747e72917e 0.0s 152 => => sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54 28.57MB / 28.57MB 2.1s 153 => => extracting sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54 1.7s 154 => [2/2] RUN echo hello > /hello 0.6s 155 => exporting to oci image format 0.6s 156 => => exporting layers 0.1s 157 => => exporting manifest sha256:b96d490d134221ab121af91a42b13195dd8c5bf941012d7bfe07eabcf5259eda 0.0s 158 => => exporting config sha256:bd706574eab19009585b98826b06e63cf6eacf8d7193504dae75caa760332ca2 0.0s 159 => => sending tarball 0.5s 160 unpacking docker.io/library/hello:latest (sha256:b96d490d134221ab121af91a42b13195dd8c5bf941012d7bfe07eabcf5259eda)...done 161 > nerdctl run --rm -it hello cat /hello 162 hello 163 ``` 164 165 > NOTE: `--ipfs` flag has been removed since v1.2.0. You need to launch the localhost registry by yourself using `nerdctl ipfs registry serve`. 166 167 #### Details about `localhost:5050/ipfs/<CID>` and `nerdctl ipfs registry` 168 169 As of now, BuildKit doesn't support `ipfs://` prefix so nerdctl achieves builds on IPFS by having a read-only local registry backed by IPFS. 170 This registry converts registry API requests to IPFS operations. 171 So IPFS-agnostic tools can pull images from IPFS via this registry. 172 173 This registry is provided as a subcommand `nerdctl ipfs registry`. 174 This command starts the registry backed by the IPFS repo of the current `$IPFS_PATH` 175 By default, nerdctl exposes the registry at `localhost:5050` (configurable via flags). 176 177 <details> 178 <summary>Creating systemd unit file for `nerdctl ipfs registry`</summary> 179 180 Optionally you can create systemd unit file of `nerdctl ipfs registry serve`. 181 An example systemd unit file for `nerdctl ipfs registry serve` can be the following. 182 `nerdctl ipfs registry serve` is aware of environemnt variables for configuring the behaviour (e.g. listening port) so you can use `EnvironmentFile` for configuring it. 183 184 ``` 185 [Unit] 186 Description=nerdctl ipfs registry serve 187 188 [Service] 189 EnvironmentFile-=/run/nerdctl-ipfs-registry-serve/env 190 ExecStart=nerdctl ipfs registry serve 191 192 [Install] 193 WantedBy=default.target 194 ``` 195 196 </details> 197 198 The following example starts the registry on `localhost:5555` instead of `localhost:5050`. 199 200 ``` 201 nerdctl ipfs registry serve --listen-registry=localhost:5555 202 ``` 203 204 > NOTE: You'll also need to restart the registry when you change `$IPFS_PATH` to use. 205 206 > NOTE: `nerdctl ipfs registry [up|down]` has been removed since v1.2.0. You need to launch the localhost registry using `nerdctl ipfs registry serve` instead. 207 208 ### Compose on IPFS 209 210 `nerdctl compose` supports same image name syntax to pull images from IPFS. 211 212 ```yaml 213 version: "3.8" 214 services: 215 ubuntu: 216 image: ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze 217 command: echo hello 218 ``` 219 220 When you build images using base images on IPFS, you can use `localhost:5050/ipfs/<CID>` image reference in Dockerfile as mentioned above. 221 222 ``` 223 nerdctl compose up --build 224 ``` 225 226 ``` 227 nerdctl compose build 228 ``` 229 230 > NOTE: `--ipfs` flag has been removed since v1.2.0. You need to launch the localhost registry by yourself using `nerdctl ipfs registry serve`. 231 232 ### Encryption 233 234 You can distribute [encrypted images](./ocicrypt.md) on IPFS using OCIcrypt. 235 Please see [`/docs/ocicrypt.md`](./ocicrypt.md) for details about how to encrypt and decrypt an image. 236 237 Same as normal images, the encrypted image can be pushed to IPFS using `ipfs://` prefix. 238 239 ```console 240 > nerdctl image encrypt --recipient=jwe:mypubkey.pem ubuntu:20.04 ubuntu:20.04-encrypted 241 sha256:a5c57411f3d11bb058b584934def0710c6c5b5a4a2d7e9b78f5480ecfc450740 242 > nerdctl push ipfs://ubuntu:20.04-encrypted 243 INFO[0000] pushing image "ubuntu:20.04-encrypted" to IPFS 244 INFO[0000] ensuring image contents 245 bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4 246 ``` 247 248 You can pull the encrypted image from IPFS using `ipfs://` prefix and can decrypt it in the same way as described in [`/docs/ocicrypt.md`](./ocicrypt.md). 249 250 ```console 251 > nerdctl pull --unpack=false ipfs://bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4 252 bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4: resolved |++++++++++++++++++++++++++++++++++++++| 253 index-sha256:73334fee83139d1d8dbf488b28ad100767c38428b2a62504c758905c475c1d6c: done |++++++++++++++++++++++++++++++++++++++| 254 manifest-sha256:8855ae825902045ea2b27940634673ba410b61885f91b9f038f6b3303f48727c: done |++++++++++++++++++++++++++++++++++++++| 255 config-sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1: done |++++++++++++++++++++++++++++++++++++++| 256 layer-sha256:e74a9a7749e808e4ad1e90d5a81ce3146ce270de0fbdf22429cd465df8f10a13: done |++++++++++++++++++++++++++++++++++++++| 257 elapsed: 0.3 s total: 22.0 M (73.2 MiB/s) 258 > nerdctl image decrypt --key=mykey.pem ipfs://bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4 ubuntu:20.04-decrypted 259 sha256:b0ccaddb7e7e4e702420de126468eab263eb0f3c25abf0b957ce8adcd1e82105 260 > nerdctl run --rm -it ubuntu:20.04-decrypted echo hello 261 hello 262 ``` 263 264 ## Running containers on IPFS with eStargz-based lazy pulling 265 266 nerdctl supports running eStargz images on IPFS with lazy pulling using Stargz Snapshotter. 267 268 In this configuration, Stargz Snapshotter mounts the eStargz image from IPFS to the container's rootfs using FUSE with lazy pulling support. 269 Thus the container can startup without waiting for the entire image contents to be locally available. 270 You can see faster container cold-start. 271 272 To use this feature, you need to enable Stargz Snapshotter following [`/docs/stargz.md`](./stargz.md). 273 You also need to add the following configuration to `config.toml` of Stargz Snapshotter (typically located at `/etc/containerd-stargz-grpc/config.toml`). 274 275 ```toml 276 ipfs = true 277 ``` 278 279 You can push an arbitrary image to IPFS with converting it to eStargz using `--estargz` option. 280 281 ``` 282 nerdctl push --estargz ipfs://fedora:36 283 ``` 284 285 You can pull and run that eStargz image with lazy pulling. 286 287 ``` 288 nerdctl run --rm -it ipfs://bafkreibp2ncujcia663uum25ustwvmyoguxqyzjnxnlhebhsgk2zowscye echo hello 289 ``` 290 291 - See [the doc in stargz-snapshotter project](https://github.com/containerd/stargz-snapshotter/blob/v0.10.0/docs/ipfs.md) for details about lazy pulling on IPFS. 292 - See [`/docs/stargz.md`](./stargz.md) for details about the configuration of nerdctl for Stargz Snapshotter.