|
| 1 | +--- |
| 2 | +title: "Image Manifest V 2, Schema 1" |
| 3 | +description: "image manifest for the Registry." |
| 4 | +keywords: registry, on-prem, images, tags, repository, distribution, api, advanced, manifest |
| 5 | +--- |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +This document outlines the format of the V2 image manifest. The image |
| 10 | +manifest described herein was introduced in the Docker daemon in the [v1.3.0 |
| 11 | +release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453). |
| 12 | +It is a provisional manifest to provide a compatibility with the [V1 Image |
| 13 | +format](https://github.com/docker/docker/blob/master/image/spec/v1.md), as the |
| 14 | +requirements are defined for the [V2 Schema 2 |
| 15 | +image](https://github.com/docker/distribution/pull/62). |
| 16 | + |
| 17 | + |
| 18 | +Image manifests describe the various constituents of a docker image. Image |
| 19 | +manifests can be serialized to JSON format with the following media types: |
| 20 | + |
| 21 | +Manifest Type | Media Type |
| 22 | +------------- | ------------- |
| 23 | +manifest | "application/vnd.docker.distribution.manifest.v1+json" |
| 24 | +signed manifest | "application/vnd.docker.distribution.manifest.v1+prettyjws" |
| 25 | + |
| 26 | +*Note that "application/json" will also be accepted for schema 1.* |
| 27 | + |
| 28 | +References: |
| 29 | + |
| 30 | + - [Proposal: JSON Registry API V2.1](https://github.com/docker/docker/issues/9015) |
| 31 | + - [Proposal: Provenance step 1 - Transform images for validation and verification](https://github.com/docker/docker/issues/8093) |
| 32 | + |
| 33 | +## *Manifest* Field Descriptions |
| 34 | + |
| 35 | +Manifest provides the base accessible fields for working with V2 image format |
| 36 | + in the registry. |
| 37 | + |
| 38 | +- **`name`** *string* |
| 39 | + |
| 40 | + name is the name of the image's repository |
| 41 | + |
| 42 | +- **`tag`** *string* |
| 43 | + |
| 44 | + tag is the tag of the image |
| 45 | + |
| 46 | +- **`architecture`** *string* |
| 47 | + |
| 48 | + architecture is the host architecture on which this image is intended to |
| 49 | + run. This is for information purposes and not currently used by the engine |
| 50 | + |
| 51 | +- **`fsLayers`** *array* |
| 52 | + |
| 53 | + fsLayers is a list of filesystem layer blob sums contained in this image. |
| 54 | + |
| 55 | + An fsLayer is a struct consisting of the following fields |
| 56 | + - **`blobSum`** *digest.Digest* |
| 57 | + |
| 58 | + blobSum is the digest of the referenced filesystem image layer. A |
| 59 | + digest must be a sha256 hash. |
| 60 | + |
| 61 | + |
| 62 | +- **`history`** *array* |
| 63 | + |
| 64 | + history is a list of unstructured historical data for v1 compatibility. It |
| 65 | + contains ID of the image layer and ID of the layer's parent layers. |
| 66 | + |
| 67 | + history is a struct consisting of the following fields |
| 68 | + - **`v1Compatibility`** string |
| 69 | + |
| 70 | + V1Compatibility is the raw V1 compatibility information. This will |
| 71 | + contain the JSON object describing the V1 of this image. |
| 72 | + |
| 73 | +- **`schemaVersion`** *int* |
| 74 | + |
| 75 | + SchemaVersion is the image manifest schema that this image follows. |
| 76 | + |
| 77 | +>**Note**:the length of `history` must be equal to the length of `fsLayers` and |
| 78 | +>entries in each are correlated by index. |
| 79 | +
|
| 80 | +## Signed Manifests |
| 81 | + |
| 82 | +Signed manifests provides an envelope for a signed image manifest. A signed |
| 83 | +manifest consists of an image manifest along with an additional field |
| 84 | +containing the signature of the manifest. |
| 85 | + |
| 86 | +The docker client can verify signed manifests and displays a message to the user. |
| 87 | + |
| 88 | +### Signing Manifests |
| 89 | + |
| 90 | +Image manifests can be signed in two different ways: with a *libtrust* private |
| 91 | + key or an x509 certificate chain. When signing with an x509 certificate chain, |
| 92 | + the public key of the first element in the chain must be the public key |
| 93 | + corresponding with the sign key. |
| 94 | + |
| 95 | +### Signed Manifest Field Description |
| 96 | + |
| 97 | +Signed manifests include an image manifest and a list of signatures generated |
| 98 | +by *libtrust*. A signature consists of the following fields: |
| 99 | + |
| 100 | + |
| 101 | +- **`header`** *[JOSE](http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2)* |
| 102 | + |
| 103 | + A [JSON Web Signature](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html) |
| 104 | + |
| 105 | +- **`signature`** *string* |
| 106 | + |
| 107 | + A signature for the image manifest, signed by a *libtrust* private key |
| 108 | + |
| 109 | +- **`protected`** *string* |
| 110 | + |
| 111 | + The signed protected header |
| 112 | + |
| 113 | +## Example Manifest |
| 114 | + |
| 115 | +*Example showing the official 'hello-world' image manifest.* |
| 116 | + |
| 117 | +``` |
| 118 | +{ |
| 119 | + "name": "hello-world", |
| 120 | + "tag": "latest", |
| 121 | + "architecture": "amd64", |
| 122 | + "fsLayers": [ |
| 123 | + { |
| 124 | + "blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" |
| 125 | + }, |
| 126 | + { |
| 127 | + "blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" |
| 128 | + }, |
| 129 | + { |
| 130 | + "blobSum": "sha256:cc8567d70002e957612902a8e985ea129d831ebe04057d88fb644857caa45d11" |
| 131 | + }, |
| 132 | + { |
| 133 | + "blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" |
| 134 | + } |
| 135 | + ], |
| 136 | + "history": [ |
| 137 | + { |
| 138 | + "v1Compatibility": "{\"id\":\"e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\",\"parent\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"created\":\"2014-12-31T22:57:59.178729048Z\",\"container\":\"27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\",\"container_config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [/hello]\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"docker_version\":\"1.4.1\",\"config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/hello\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n" |
| 139 | + }, |
| 140 | + { |
| 141 | + "v1Compatibility": "{\"id\":\"e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\",\"parent\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"created\":\"2014-12-31T22:57:59.178729048Z\",\"container\":\"27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\",\"container_config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [/hello]\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"docker_version\":\"1.4.1\",\"config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/hello\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n" |
| 142 | + }, |
| 143 | + ], |
| 144 | + "schemaVersion": 1, |
| 145 | + "signatures": [ |
| 146 | + { |
| 147 | + "header": { |
| 148 | + "jwk": { |
| 149 | + "crv": "P-256", |
| 150 | + "kid": "OD6I:6DRK:JXEJ:KBM4:255X:NSAA:MUSF:E4VM:ZI6W:CUN2:L4Z6:LSF4", |
| 151 | + "kty": "EC", |
| 152 | + "x": "3gAwX48IQ5oaYQAYSxor6rYYc_6yjuLCjtQ9LUakg4A", |
| 153 | + "y": "t72ge6kIA1XOjqjVoEOiPPAURltJFBMGDSQvEGVB010" |
| 154 | + }, |
| 155 | + "alg": "ES256" |
| 156 | + }, |
| 157 | + "signature": "XREm0L8WNn27Ga_iE_vRnTxVMhhYY0Zst_FfkKopg6gWSoTOZTuW4rK0fg_IqnKkEKlbD83tD46LKEGi5aIVFg", |
| 158 | + "protected": "eyJmb3JtYXRMZW5ndGgiOjY2MjgsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wNC0wOFQxODo1Mjo1OVoifQ" |
| 159 | + } |
| 160 | + ] |
| 161 | +} |
| 162 | +
|
| 163 | +``` |
0 commit comments