|
| 1 | ++++ |
| 2 | +title="Export to OCI layout format" |
| 3 | +weight=3 |
| 4 | +summary="Learn how to export your application image to disk in OCI layout format" |
| 5 | ++++ |
| 6 | + |
| 7 | +<div class="quote mb-4"> |
| 8 | + The OCI Image Layout is the directory structure for OCI content-addressable blobs and location-addressable references. |
| 9 | + <div class="author">See the <a href="https://github.com/opencontainers/image-spec/blob/main/image-layout.md">specification.</a></div> |
| 10 | +</div> |
| 11 | + |
| 12 | +Exporting to OCI layout format is an **experimental** feature available on pack since version 0.30.0 |
| 13 | + |
| 14 | +### 1. Enable experimental feature |
| 15 | + |
| 16 | +Verify your pack version is equal or greater than 0.30.0 |
| 17 | + |
| 18 | +```bash |
| 19 | +pack version |
| 20 | +``` |
| 21 | + |
| 22 | +Enable the experimental features on pack |
| 23 | + |
| 24 | +```bash |
| 25 | +pack config experimental true |
| 26 | +``` |
| 27 | + |
| 28 | +You can confirm everything is fine, checking the `config.toml` file in your `PACK_HOME` installation folder. For example: |
| 29 | + |
| 30 | +```bash |
| 31 | +cat ~/.pack/config.toml |
| 32 | +experimental = true |
| 33 | +layout-repo-dir = "<$HOME>/.pack/layout-repo" |
| 34 | +``` |
| 35 | + |
| 36 | +The configuration shows the experimental mode was **enabled** and a local directory to save images on disk was configured to path `<$HOME>/.pack/layout-repo`. `layout-repo-dir` is being used as a [local repository](https://github.com/buildpacks/rfcs/blob/main/text/0119-export-to-oci.md#how-it-works) |
| 37 | +to save images requires by `pack build` command in OCI layout format. |
| 38 | + |
| 39 | +### 2. Build the app |
| 40 | + |
| 41 | +Please first follow the steps to [build an app](/docs/app-developer-guide/build-an-app), once you have successfully built an application you can export the sample application to disk in OCI layout format. |
| 42 | + |
| 43 | +The OCI layout feature must be enabled using the convention `oci:<path/to/save/image>` in the `<image-name>` parameter when invoking `pack build`. |
| 44 | + |
| 45 | +For example: |
| 46 | + |
| 47 | +```bash |
| 48 | +pack build oci:sample-app --path samples/apps/java-maven --builder cnbs/sample-builder:bionic |
| 49 | +``` |
| 50 | + |
| 51 | +It will save the image in a folder `./sample-app` created in your current directory. |
| 52 | + |
| 53 | +### 3. Check your image |
| 54 | + |
| 55 | +**Congratulations!** |
| 56 | + |
| 57 | +You can verify your application image was saved on disk in a folder called `./sample-app` in your current directory in OCI layout format. For example: |
| 58 | + |
| 59 | +```bash |
| 60 | +tree sample-app |
| 61 | + |
| 62 | +sample-app |
| 63 | +├── blobs |
| 64 | +│ └── sha256 |
| 65 | +│ ├── 141bfb0cd434d425bc70edb9e56ea11d07aed76450eb0e73e6110645f251a8d3 |
| 66 | +│ ├── 2fa192256ce255c6ea6c1296eadfe2feba8094f40e6aa85e699645caca2e85d8 |
| 67 | +│ ├── 5a44e4f7b58d74fe6f92dd7028075c91191128d1e2e7f39846fe061a9a98836e |
| 68 | +│ ├── 72d9f18d70f395ff9bfae4d193077ccea3ca583e3da3dd66f5c84520c0100727 |
| 69 | +│ ├── 827746ec7ba80f4e4811b6c9195b6f810fbc2d58a6c9cc337bf0305791f24e97 |
| 70 | +│ ├── ad13830c92258c952f25d561d8bf7d9eb58b8a3003960db1502cbda8239130b5 |
| 71 | +│ ├── b97b58b190d5f731c879b0f7446a2bd554863b51851e03757199c74dd922ce61 |
| 72 | +│ ├── c44222730efa142cd5bedc0babf82a9a07d325494be7f5c3cfde56f43166b65f |
| 73 | +│ ├── e1048fb89c3194a1f0542c0847aa086a7034dd7867c48fe8c93675cf36f90610 |
| 74 | +│ ├── f0a30c5bc44742065b1b4ffa95271a39994f05ba7a03dd7e7143d1d3e45fa0b1 |
| 75 | +│ └── f9d6350d0c44c0e7165a522155f53181ce8c163a6b8ead1f6baea22d1a8d8a78 |
| 76 | +├── index.json |
| 77 | +└── oci-layout |
| 78 | + |
| 79 | +3 directories, 13 files |
| 80 | +``` |
| 81 | +If you want to keep playing with the image in OCI layout format, one tool you can take a look at is [umoci](https://umo.ci/). It can help you to create a |
| 82 | +[runtime bundler](https://github.com/opencontainers/runtime-spec) that can be executed with another tool like [runc](https://github.com/opencontainers/runc) |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +## Extra configuration |
| 87 | + |
| 88 | +### Skip saving your run-image layers on disk |
| 89 | + |
| 90 | +Before using this option we suggest to remove your local layout directory (the one configured in your pack config.toml with the key `layout-repo-dir`) and |
| 91 | +your application image folder (if you are planning to use the same folder). The reason for this is pack doesn't remove the blobs saved in the `layout-repo-dir` if you use the `--sparse` flag |
| 92 | + |
| 93 | +If you don't need your `run-image` layers on disk, you can skip them using `--sparse` flag in your `pack build` command invocation. |
| 94 | + |
| 95 | +For example: |
| 96 | + |
| 97 | +```bash |
| 98 | +pack build oci:sample-app --sparse --path samples/apps/java-maven --builder cnbs/sample-builder:bionic |
| 99 | +``` |
| 100 | + |
| 101 | +Verify your application image |
| 102 | + |
| 103 | +```bash |
| 104 | +sample-app |
| 105 | +├── blobs |
| 106 | +│ └── sha256 |
| 107 | +│ ├── 2ebed3ab57806441e2bf814eaf0648ed77289e058340d2b76d32b422fbaac5d8 |
| 108 | +│ ├── 2fa192256ce255c6ea6c1296eadfe2feba8094f40e6aa85e699645caca2e85d8 |
| 109 | +│ ├── 5a44e4f7b58d74fe6f92dd7028075c91191128d1e2e7f39846fe061a9a98836e |
| 110 | +│ ├── 741e558b7b807fea350b26b8152170a2463277cb3d1268b60de76ec12608518a |
| 111 | +│ ├── 907c84671180d979a38affb62d9a6ea8e9a510e27639e0b60a34a42f1a846ddc |
| 112 | +│ ├── ad13830c92258c952f25d561d8bf7d9eb58b8a3003960db1502cbda8239130b5 |
| 113 | +│ ├── c44222730efa142cd5bedc0babf82a9a07d325494be7f5c3cfde56f43166b65f |
| 114 | +│ └── f9d6350d0c44c0e7165a522155f53181ce8c163a6b8ead1f6baea22d1a8d8a78 |
| 115 | +├── index.json |
| 116 | +└── oci-layout |
| 117 | + |
| 118 | +3 directories, 10 files |
| 119 | +``` |
| 120 | + |
| 121 | +As you can see, there are 3 missing files at `sample-app/blobs/sha256` folder. The missing 3 blobs are the blobs from the |
| 122 | +`run-image` that were not downloaded but if you check your config file you'll notice you have the same number of layers as |
| 123 | +when you export the full image. |
| 124 | + |
| 125 | +## Implementation notes |
| 126 | + |
| 127 | +### Media Types |
| 128 | + |
| 129 | +According to the OCI specification, the [compatibles media types](https://github.com/opencontainers/image-spec/blob/main/media-types.md#compatibility-matrix) for the index.json files must be: |
| 130 | + |
| 131 | +- `application/vnd.oci.image.index.v1+json` or |
| 132 | +- `application/vnd.docker.distribution.manifest.list.v2+json` |
| 133 | + |
| 134 | +If you are trying to use the lifecycle directly without using `pack` to export your image, take on consideration that tools like: |
| 135 | + |
| 136 | +[skopeo](https://github.com/containers/skopeo) |
| 137 | +```bash |
| 138 | +skopeo copy -a docker://<your-image> <dest> |
| 139 | +``` |
| 140 | +It will give you `application/vnd.oci.image.index.v1+json` media type, which is currently working |
| 141 | + |
| 142 | +But [crane](https://github.com/google/go-containerregistry/tree/main/cmd/crane) |
| 143 | + |
| 144 | +```bash |
| 145 | +crane pull <your-image> <dest> --format=oci |
| 146 | +``` |
| 147 | +It will give you `application/vnd.docker.distribution.manifest.list.v2+json`, which will fail because of the [state of our current implementation](https://github.com/buildpacks/rfcs/pull/203#discussion_r1092449172), we will improve this behavior in future versions. |
| 148 | + |
| 149 | + |
| 150 | + |
| 151 | + |
| 152 | + |
0 commit comments