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.