diff --git a/manifest.md b/manifest.md index 9bcd49534..0fec0e160 100644 --- a/manifest.md +++ b/manifest.md @@ -4,113 +4,90 @@ draft = true +++ -# Image Manifest Version 2, Schema 2 - -This document outlines the format of of the V2 image manifest, schema version 2. -The original (and provisional) image manifest for V2 (schema 1), was introduced -in the Docker daemon in the [v1.3.0 -release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453) -and is specified in the [schema 1 manifest definition](./manifest-v2-1.md) +# Image Manifest -This second schema version has two primary goals. The first is to allow -multi-architecture images, through a "fat manifest" which references image -manifests for platform-specific versions of an image. The second is to -move the Docker engine towards content-addressable images, by supporting -an image model where the image's configuration can be hashed to generate -an ID for the image. +There are three main goals of the Image Manifest Specification. +The first goal is content-addressable images, by supporting an image model where the image's configuration can be hashed to generate a unique ID for the image and its components. +The second goal is to allow multi-architecture images, through a "fat manifest" which references image manifests for platform-specific versions of an image. +The third goal is to be translatable to the [OpenContainers/runtime-spec](https://github.com/opencontainers/runtime-spec) # Media Types -The following media types are used by the manifest formats described here, and -the resources they reference: +The following media types are used by the manifest formats described here, and the resources they reference: -- `application/vnd.docker.distribution.manifest.v1+json`: schema1 (existing manifest format) -- `application/vnd.docker.distribution.manifest.v2+json`: New image manifest format (schemaVersion = 2) -- `application/vnd.docker.distribution.manifest.list.v2+json`: Manifest list, aka "fat manifest" -- `application/vnd.docker.image.rootfs.diff.tar.gzip`: "Layer", as a gzipped tar -- `application/vnd.docker.container.image.v1+json`: Container config JSON +- `application/vnd.oci.image.manifest.list.v1+json`: Manifest list, aka "fat manifest" +- `application/vnd.oci.image.manifest.v1+json`: Image manifest format +- `application/vnd.oci.image.rootfs.tar.gzip`: "Layer", as a gzipped tar archive +- `application/vnd.oci.image.serialization.v1+json`: Container config JSON ## Manifest List -The manifest list is the "fat manifest" which points to specific image manifests -for one or more platforms. Its use is optional, and relatively few images will -use one of these manifests. A client will distinguish a manifest list from an -image manifest based on the Content-Type returned in the HTTP response. +The manifest list is the "fat manifest" which points to specific image manifests for one or more platforms. +While the use of a manifest list is OPTIONAL for image providers, image consumers SHOULD be prepared to process them. +A client will distinguish a manifest list from an image manifest based on the Content-Type returned in the HTTP response. ## *Manifest List* Field Descriptions - **`schemaVersion`** *int* - - This field specifies the image manifest schema version as an integer. This - schema uses the version `2`. + + This REQUIRED property specifies the image manifest schema version. + This schema uses the version `2`. - **`mediaType`** *string* - The MIME type of the manifest list. This should be set to - `application/vnd.docker.distribution.manifest.list.v2+json`. + This REQUIRED property contains the MIME type of the manifest list. + For this version of the specification, this MUST be set to `application/vnd.oci.image.manifest.list.v1+json`. - **`manifests`** *array* - The manifests field contains a list of manifests for specific platforms. + This REQUIRED property contains a list of manifests for specific platforms. + While the property MUST be present, the size of the array MAY be zero. - Fields of a object in the manifests list are: - - - **`mediaType`** *string* - - The MIME type of the referenced object. This will generally be - `application/vnd.docker.image.manifest.v2+json`, but it could also - be `application/vnd.docker.image.manifest.v1+json` if the manifest - list references a legacy schema-1 manifest. - - - **`size`** *int* - - The size in bytes of the object. This field exists so that a client - will have an expected size for the content before validating. If the - length of the retrieved content does not match the specified length, - the content should not be trusted. - - - **`digest`** *string* + Fields of each object in the manifests list are: + + - **`mediaType`** *string* - The digest of the content, as defined by the - [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). + This REQUIRED property contains the MIME type of the referenced object. + (i.e. `application/vnd.oci.image.manifest.v1+json`) - - **`platform`** *object* + - **`size`** *int* - The platform object describes the platform which the image in the - manifest runs on. A full list of valid operating system and architecture - values are listed in the [Go language documentation for `$GOOS` and - `$GOARCH`](https://golang.org/doc/install/source#environment) + This REQUIRED property specifies the size in bytes of the object. + This field exists so that a client will have an expected size for the content before validating. + If the length of the retrieved content does not match the specified length, the content should not be trusted. - - **`architecture`** *string* + - **`digest`** *string* - The architecture field specifies the CPU architecture, for example - `amd64` or `ppc64le`. + The digest of the content, as defined by the [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). - - **`os`** *string* + - **`platform`** *object* - The os field specifies the operating system, for example - `linux` or `windows`. + This REQUIRED property describes the platform which the image in the manifest runs on. + A full list of valid operating system and architecture values are listed in the [Go language documentation for `$GOOS` and `$GOARCH`](https://golang.org/doc/install/source#environment) - - **`os.version`** *string* + - **`architecture`** *string* - The optional os.version field specifies the operating system version, - for example `10.0.10586`. + This REQUIRED property specified the CPU architecture, for example `amd64` or `ppc64le`. - - **`os.features`** *array* + - **`os`** *string* - The optional os.features field specifies an array of strings, - each listing a required OS feature (for example on Windows - `win32k`). + This REQUIRED property specifies the operating system, for example `linux` or `windows`. - - **`variant`** *string* + - **`os.version`** *string* - The optional variant field specifies a variant of the CPU, for - example `armv6l` to specify a particular CPU variant of the ARM CPU. + This optional property specifies the operating system version, for example `10.0.10586`. - - **`features`** *array* + - **`os.features`** *array* - The optional features field specifies an array of strings, each - listing a required CPU feature (for example `sse4` or `aes`). + This OPTIONAL property specifies an array of strings, each specifying a mandatory OS feature (for example on Windows `win32k`). + + - **`variant`** *string* + + This OPTIONAL property specifies the variant of the CPU, for example `armv6l` to specify a particular CPU variant of the ARM CPU. + + - **`features`** *array* + + This OPTIONAL property specifies an array of strings, each specifying a mandatory CPU feature (for example `sse4` or `aes`). ## Example Manifest List @@ -118,10 +95,10 @@ image manifest based on the Content-Type returned in the HTTP response. ```json { "schemaVersion": 2, - "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", + "mediaType": "application/vnd.oci.image.manifest.list.v1+json", "manifests": [ { - "mediaType": "application/vnd.docker.image.manifest.v2+json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 7143, "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f", "platform": { @@ -130,7 +107,7 @@ image manifest based on the Content-Type returned in the HTTP response. } }, { - "mediaType": "application/vnd.docker.image.manifest.v2+json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 7682, "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270", "platform": { @@ -147,70 +124,63 @@ image manifest based on the Content-Type returned in the HTTP response. # Image Manifest -The image manifest provides a configuration and a set of layers for a container -image. It's the direct replacement for the schema-1 manifest. +The image manifest provides a configuration and a set of layers for a container image. ## *Image Manifest* Field Descriptions - **`schemaVersion`** *int* - - This field specifies the image manifest schema version as an integer. This - schema uses version `2`. + + This REQUIRED property specifies the image manifest schema version. + This schema uses version `2`. - **`mediaType`** *string* - The MIME type of the manifest. This should be set to - `application/vnd.docker.distribution.manifest.v2+json`. + This REQUIRED property contains the MIME type of the image manifest. + For this version of the specification, this MUST be set to `application/vnd.oci.image.manifest.v1+json`. - **`config`** *object* - The config field references a configuration object for a container, by - digest. This configuration item is a JSON blob that the runtime uses - to set up the container. This new schema uses a tweaked version - of this configuration to allow image content-addressability on the - daemon side. + The config field references a configuration object for a container, by digest. + This configuration item is a JSON blob that the runtime uses to set up the container. + This new schema uses a tweaked version of this configuration to allow image content-addressability on the daemon side. Fields of a config object are: - + - **`mediaType`** *string* - - The MIME type of the referenced object. This should generally be - `application/vnd.docker.container.image.v1+json`. - + + This REQUIRED property contains the MIME type of the referenced object. + (i.e. `application/vnd.oci.image.serialization.v1+json`) + - **`size`** *int* - - The size in bytes of the object. This field exists so that a client - will have an expected size for the content before validating. If the - length of the retrieved content does not match the specified length, - the content should not be trusted. - + + This REQUIRED property specifies the size in bytes of the object. + This field exists so that a client will have an expected size for the content before validating. + If the length of the retrieved content does not match the specified length, the content should not be trusted. + - **`digest`** *string* - The digest of the content, as defined by the - [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). + The digest of the content, as defined by the [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). - **`layers`** *array* The layer list is ordered starting from the base image (opposite order of schema1). Fields of an item in the layers list are: - + - **`mediaType`** *string* - - The MIME type of the referenced object. This should - generally be `application/vnd.docker.image.rootfs.diff.tar.gzip`. - + + This REQUIRED property contains the MIME type of the referenced object. + (i.e. `application/vnd.oci.image.rootfs.tar.gzip`) + - **`size`** *int* - - The size in bytes of the object. This field exists so that a client - will have an expected size for the content before validating. If the - length of the retrieved content does not match the specified length, - the content should not be trusted. - + + This REQUIRED property specifies the size in bytes of the object. + This field exists so that a client will have an expected size for the content before validating. + If the length of the retrieved content does not match the specified length, the content should not be trusted. + - **`digest`** *string* - The digest of the content, as defined by the - [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). + The digest of the content, as defined by the [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). ## Example Image Manifest @@ -218,25 +188,25 @@ image. It's the direct replacement for the schema-1 manifest. ```json { "schemaVersion": 2, - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "config": { - "mediaType": "application/vnd.docker.container.image.v1+json", + "mediaType": "application/vnd.oci.image.serialization.v1+json", "size": 7023, "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" }, "layers": [ { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "mediaType": "application/vnd.oci.image.rootfs.tar.gzip", "size": 32654, "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f" }, { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "mediaType": "application/vnd.oci.image.rootfs.tar.gzip", "size": 16724, "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" }, { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "mediaType": "application/vnd.oci.image.rootfs.tar.gzip", "size": 73109, "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" } @@ -246,39 +216,22 @@ image. It's the direct replacement for the schema-1 manifest. # Backward compatibility -The registry will continue to accept uploads of manifests in both the old and -new formats. - -When pushing images, clients which support the new manifest format should first -construct a manifest in the new format. If uploading this manifest fails, -presumably because the registry only supports the old format, the client may -fall back to uploading a manifest in the old format. - -When pulling images, clients indicate support for this new version of the -manifest format by sending the -`application/vnd.docker.distribution.manifest.v2+json` and -`application/vnd.docker.distribution.manifest.list.v2+json` media types in an -`Accept` header when making a request to the `manifests` endpoint. Updated -clients should check the `Content-Type` header to see whether the manifest -returned from the endpoint is in the old format, or is an image manifest or -manifest list in the new format. - -If the manifest being requested uses the new format, and the appropriate media -type is not present in an `Accept` header, the registry will assume that the -client cannot handle the manifest as-is, and rewrite it on the fly into the old -format. If the object that would otherwise be returned is a manifest list, the -registry will look up the appropriate manifest for the amd64 platform and -linux OS, rewrite that manifest into the old format if necessary, and return -the result to the client. If no suitable manifest is found in the manifest -list, the registry will return a 404 error. - -One of the challenges in rewriting manifests to the old format is that the old -format involves an image configuration for each layer in the manifest, but the -new format only provides one image configuration. To work around this, the -registry will create synthetic image configurations for all layers except the -top layer. These image configurations will not result in runnable images on -their own, but only serve to fill in the parent chain in a compatible way. -The IDs in these synthetic configurations will be derived from hashes of their -respective blobs. The registry will create these configurations and their IDs -using the same scheme as Docker 1.10 when it creates a legacy manifest to push -to a registry which doesn't support the new format. +The registry will continue to accept uploads of manifests in both the old and new formats. + +When pushing images, clients which support the new manifest format should first construct a manifest in the new format. +If uploading this manifest fails, presumably because the registry only supports the old format, the client may fall back to uploading a manifest in the old format. + +When pulling images, clients indicate support for this new version of the manifest format by sending the +`application/vnd.oci.image.manifest.v1+json` and +`application/vnd.oci.image.manifest.list.v1+json` media types in an `Accept` header when making a request to the `manifests` endpoint. +Updated clients should check the `Content-Type` header to see whether the manifest returned from the endpoint is in the old format, or is an image manifest or manifest list in the new format. + +If the manifest being requested uses the new format, and the appropriate media type is not present in an `Accept` header, the registry will assume that the client cannot handle the manifest as-is, and rewrite it on the fly into the old format. +If the object that would otherwise be returned is a manifest list, the registry will look up the appropriate manifest for the amd64 platform and linux OS, rewrite that manifest into the old format if necessary, and return the result to the client. +If no suitable manifest is found in the manifest list, the registry will return a 404 error. + +One of the challenges in rewriting manifests to the old format is that the old format involves an image configuration for each layer in the manifest, but the new format only provides one image configuration. +To work around this, the registry will create synthetic image configurations for all layers except the top layer. +These image configurations will not result in runnable images on their own, but only serve to fill in the parent chain in a compatible way. +The IDs in these synthetic configurations will be derived from hashes of their respective blobs. +The registry will create these configurations and their IDs using the same scheme as Docker 1.10 when it creates a legacy manifest to push to a registry which doesn't support the new format. diff --git a/serialization.md b/serialization.md index 57a599b8f..d32029dd0 100644 --- a/serialization.md +++ b/serialization.md @@ -1,10 +1,7 @@ -# Docker Image Specification v1.0.0 +# OpenContainers Image Serialization Specification -An *Image* is an ordered collection of root filesystem changes and the -corresponding execution parameters for use within a container runtime. This -specification outlines the format of these filesystem changes and corresponding -parameters and describes how to create and use them for use with a container -runtime and execution tool. +An *Image* is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime. +This specification outlines the format of these filesystem changes and corresponding parameters and describes how to create and use them for use with a container runtime and execution tool. ## Terminology @@ -15,102 +12,70 @@ This specification uses the following terms: Layer
- Images are composed of layers. Image layer is a general - term which may be used to refer to one or both of the following: + Images are composed of layers. + Image layer is a general term which may be used to refer to one or both of the following:
  1. The metadata for the layer, described in the JSON format.
  2. The filesystem changes described by a layer.
- To refer to the former you may use the term Layer JSON or - Layer Metadata. To refer to the latter you may use the term - Image Filesystem Changeset or Image Diff. + To refer to the former you may use the term Layer JSON or Layer Metadata. + To refer to the latter you may use the term Image Filesystem Changeset or Image Diff.
Image JSON
- Each layer has an associated JSON structure which describes some - basic information about the image such as date created, author, and the - ID of its parent image as well as execution/runtime configuration like - its entry point, default arguments, CPU/memory shares, networking, and - volumes. + Each layer has an associated JSON structure which describes some basic information about the image such as date created, author, and the ID of its parent image as well as execution/runtime configuration like its entry point, default arguments, CPU/memory shares, networking, and volumes.
Image Filesystem Changeset
- Each layer has an archive of the files which have been added, changed, - or deleted relative to its parent layer. Using a layer-based or union - filesystem such as AUFS, or by computing the diff from filesystem - snapshots, the filesystem changeset can be used to present a series of - image layers as if they were one cohesive filesystem. + Each layer has an archive of the files which have been added, changed, or deleted relative to its parent layer. + Using a layer-based or union filesystem such as AUFS, or by computing the diff from filesystem snapshots, the filesystem changeset can be used to present a series of image layers as if they were one cohesive filesystem.
Image ID
- Each layer is given an ID upon its creation. It is - represented as a hexadecimal encoding of 256 bits, e.g., - a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9. + Each layer is given an ID upon its creation. + It is represented as a hexadecimal encoding of 256 bits, e.g., a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9. Image IDs should be sufficiently random so as to be globally unique. - 32 bytes read from /dev/urandom is sufficient for all - practical purposes. Alternatively, an image ID may be derived as a - cryptographic hash of image contents as the result is considered - indistinguishable from random. The choice is left up to implementors. + 32 bytes read from /dev/urandom is sufficient for all practical purposes. + Alternatively, an image ID may be derived as a cryptographic hash of image contents as the result is considered indistinguishable from random. + The choice is left up to implementors.
Image Parent
- Most layer metadata structs contain a parent field which - refers to the Image from which another directly descends. An image - contains a separate JSON metadata file and set of changes relative to - the filesystem of its parent image. Image Ancestor and - Image Descendant are also common terms. + Most layer metadata structs contain a parent field which refers to the Image from which another directly descends. + An image contains a separate JSON metadata file and set of changes relative to the filesystem of its parent image. + Image Ancestor and Image Descendant are also common terms.
Image Checksum
- Layer metadata structs contain a cryptographic hash of the contents of - the layer's filesystem changeset. Though the set of changes exists as a - simple Tar archive, two archives with identical filenames and content - will have different SHA digests if the last-access or last-modified - times of any entries differ. For this reason, image checksums are - generated using the TarSum algorithm which produces a cryptographic - hash of file contents and selected headers only. Details of this - algorithm are described in the separate TarSum specification. + The checksum is a cryptographic digest of the artifact.
Tag
- A tag serves to map a descriptive, user-given name to any single image - ID. An image name suffix (the name component after :) is - often referred to as a tag as well, though it strictly refers to the - full name of an image. Acceptable values for a tag suffix are - implementation specific, but they SHOULD be limited to the set of - alphanumeric characters [a-zA-z0-9], punctuation - characters [._-], and MUST NOT contain a : - character. + A tag serves to map a descriptive, user-given name to any single image ID. + An image name suffix (the name component after :) is often referred to as a tag as well, though it strictly refers to the full name of an image. + Acceptable values for a tag suffix are implementation specific, but they SHOULD be limited to the set of alphanumeric characters [a-zA-z0-9], punctuation characters [._-], and MUST NOT contain a : character.
Repository
- A collection of tags grouped under a common prefix (the name component - before :). For example, in an image tagged with the name - my-app:3.1.4, my-app is the Repository - component of the name. Acceptable values for repository name are - implementation specific, but they SHOULD be limited to the set of - alphanumeric characters [a-zA-z0-9], and punctuation - characters [._-], however it MAY contain additional - / and : characters for organizational - purposes, with the last : character being interpreted - dividing the repository component of the name from the tag suffix - component. + A collection of tags grouped under a common prefix (the name component before :). + For example, in an image tagged with the name my-app:3.1.4, my-app is the Repository component of the name. + Acceptable values for repository name are implementation specific, but they SHOULD be limited to the set of alphanumeric characters [a-zA-z0-9], and punctuation characters [._-], however it MAY contain additional / and : characters for organizational purposes, with the last : character being interpreted dividing the repository component of the name from the tag suffix component.
@@ -165,27 +130,24 @@ Here is an example image JSON file: id string
- Randomly generated, 256-bit, hexadecimal encoded. Uniquely identifies - the image. + Randomly generated, 256-bit, hexadecimal encoded. + Uniquely identifies the image.
parent string
- ID of the parent image. If there is no parent image then this field - should be omitted. A collection of images may share many of the same - ancestor layers. This organizational structure is strictly a tree with - any one layer having either no parent or a single parent and zero or - more descendant layers. Cycles are not allowed and implementations - should be careful to avoid creating them or iterating through a cycle - indefinitely. + ID of the parent image. + If there is no parent image then this field should be omitted. + A collection of images may share many of the same ancestor layers. + This organizational structure is strictly a tree with any one layer having either no parent or a single parent and zero or more descendant layers. + Cycles are not allowed and implementations should be careful to avoid creating them or iterating through a cycle indefinitely.
created string
- ISO-8601 formatted combined date and time at which the image was - created. + ISO-8601 formatted combined date and time at which the image was created.
author string @@ -198,15 +160,14 @@ Here is an example image JSON file: architecture string
- The CPU architecture which the binaries in this image are built to run - on. Possible values include: + The CPU architecture which the binaries in this image are built to run on. + Possible values include: - More values may be supported in the future and any of these may or may - not be supported by a given container runtime implementation. + More values may be supported in the future and any of these may or may not be supported by a given container runtime implementation.
os string @@ -226,24 +187,20 @@ Here is an example image JSON file: checksum string
- Image Checksum of the filesystem changeset associated with the image - layer. + Image Checksum of the filesystem changeset associated with the image layer.
Size integer
- The size in bytes of the filesystem changeset associated with the image - layer. + The size in bytes of the filesystem changeset associated with the image layer.
config struct
- The execution parameters which should be used as a base when running a - container using the image. This field can be null, in - which case any execution parameters should be specified at creation of - the container. + The execution parameters which should be used as a base when running a container using the image. + This field can be null, in which case any execution parameters should be specified at creation of the container.

Container RunConfig Field Descriptions

@@ -252,9 +209,10 @@ Here is an example image JSON file: User string
-

The username or UID which the process in the container should - run as. This acts as a default value to use when the value is - not specified when creating a container.

+

+ The username or UID which the process in the container should run as. + This acts as a default value to use when the value is not specified when creating a container. +

All of the following are valid:

@@ -267,44 +225,38 @@ Here is an example image JSON file:
  • user:gid
  • -

    If group/gid is not specified, the - default group and supplementary groups of the given - user/uid in /etc/passwd - from the container are applied.

    +

    + If group/gid is not specified, the default group and supplementary groups of the given user/uid in /etc/passwd from the container are applied. +

    Memory integer
    - Memory limit (in bytes). This acts as a default value to use - when the value is not specified when creating a container. + Memory limit (in bytes). + This acts as a default value to use when the value is not specified when creating a container.
    MemorySwap integer
    - Total memory usage (memory + swap); set to -1 to - disable swap. This acts as a default value to use when the - value is not specified when creating a container. + Total memory usage (memory + swap); set to -1 to disable swap. + This acts as a default value to use when the value is not specified when creating a container.
    CpuShares integer
    - CPU shares (relative weight vs. other containers). This acts as - a default value to use when the value is not specified when - creating a container. + CPU shares (relative weight vs. other containers). + This acts as a default value to use when the value is not specified when creating a container.
    ExposedPorts struct
    A set of ports to expose from a container running this image. - This JSON structure value is unusual because it is a direct - JSON serialization of the Go type - map[string]struct{} and is represented in JSON as - an object mapping its keys to an empty object. Here is an - example: + This JSON structure value is unusual because it is a direct JSON serialization of the Go type map[string]struct{} and is represented in JSON as an object mapping its keys to an empty object. + Here is an example:
    {
         "8080": {},
    @@ -324,48 +276,39 @@ Here is an example image JSON file:
                             "port"
                         
                     
    -                with the default protocol being "tcp" if not
    -                specified.
    +                with the default protocol being "tcp" if not specified.
     
    -                These values act as defaults and are merged with any specified
    -                when creating a container.
    +                These values act as defaults and are merged with any specified when creating a container.
                 
    Env array of strings
    Entries are in the format of VARNAME="var value". - These values act as defaults and are merged with any specified - when creating a container. + These values act as defaults and are merged with any specified when creating a container.
    Entrypoint array of strings
    - A list of arguments to use as the command to execute when the - container starts. This value acts as a default and is replaced - by an entrypoint specified when creating a container. + A list of arguments to use as the command to execute when the container starts. + This value acts as a default and is replaced by an entrypoint specified when creating a container.
    Cmd array of strings
    - Default arguments to the entry point of the container. These - values act as defaults and are replaced with any specified when - creating a container. If an Entrypoint value is - not specified, then the first entry of the Cmd - array should be interpreted as the executable to run. + Default arguments to the entry point of the container. + These values act as defaults and are replaced with any specified when creating a container. + If an Entrypoint value is not specified, then the first entry of the Cmd array should be interpreted as the executable to run.
    Volumes struct
    - A set of directories which should be created as data volumes in - a container running this image. This JSON structure value is - unusual because it is a direct JSON serialization of the Go - type map[string]struct{} and is represented in - JSON as an object mapping its keys to an empty object. Here is - an example: + A set of directories which should be created as data volumes in a container running this image. + This JSON structure value is unusual because it is a direct JSON serialization of the Go type map[string]struct{} and is represented in JSON as an object mapping its keys to an empty object. + Here is an example:
    {
         "/var/my-app-data/": {},
         "/etc/some-config.d/": {},
    @@ -375,28 +318,22 @@ Here is an example image JSON file:
                     WorkingDir string
                 
                 
    - Sets the current working directory of the entry point process - in the container. This value acts as a default and is replaced - by a working directory specified when creating a container. + Sets the current working directory of the entry point process in the container. + This value acts as a default and is replaced by a working directory specified when creating a container.
    -Any extra fields in the Image JSON struct are considered implementation -specific and should be ignored by any implementations which are unable to -interpret them. +Any extra fields in the Image JSON struct are considered implementation specific and should be ignored by any implementations which are unable to interpret them. ## Creating an Image Filesystem Changeset An example of creating an Image Filesystem Changeset follows. -An image root filesystem is first created as an empty directory named with the -ID of the image being created. Here is the initial empty directory structure -for the changeset for an image with ID `c3167915dc9d` ([real IDs are much -longer](#id_desc), but this example use a truncated one here for brevity. -Implementations need not name the rootfs directory in this way but it may be -convenient for keeping record of a large number of image layers.): +An image root filesystem is first created as an empty directory named with the ID of the image being created. +Here is the initial empty directory structure for the changeset for an image with ID `c3167915dc9d` ([real IDs are much longer](#id_desc), but this example use a truncated one here for brevity. +Implementations need not name the rootfs directory in this way but it may be convenient for keeping record of a large number of image layers.): ``` c3167915dc9d/ @@ -422,14 +359,13 @@ bin/my-app-binary bin/my-app-tools ``` -The TarSum checksum for the archive file is then computed and placed in the -JSON metadata along with the execution parameters. +The digest checksum for the archive file is then computed and placed in the JSON metadata along with the execution parameters. To make changes to the filesystem of this container image, create a new directory named with a new ID, such as `f60c56784b83`, and initialize it with a snapshot of the parent image's root filesystem, so that the directory is -identical to that of `c3167915dc9d`. NOTE: a copy-on-write or union filesystem -can make this very efficient: +identical to that of `c3167915dc9d`. +NOTE: a copy-on-write or union filesystem can make this very efficient: ``` f60c56784b83/ @@ -440,10 +376,9 @@ f60c56784b83/ my-app-tools ``` -This example change is going add a configuration directory at `/etc/my-app.d` -which contains a default config file. There's also a change to the -`my-app-tools` binary to handle the config layout change. The `f60c56784b83` -directory then looks like this: +This example change is going add a configuration directory at `/etc/my-app.d` which contains a default config file. +There's also a change to the `my-app-tools` binary to handle the config layout change. +The `f60c56784b83` directory then looks like this: ``` f60c56784b83/ @@ -455,13 +390,10 @@ f60c56784b83/ my-app-tools ``` -This reflects the removal of `/etc/my-app-config` and creation of a file and -directory at `/etc/my-app.d/default.cfg`. `/bin/my-app-tools` has also been -replaced with an updated version. Before committing this directory to a -changeset, because it has a parent image, it is first compared with the -directory tree of the parent snapshot, `f60c56784b83`, looking for files and -directories that have been added, modified, or removed. The following changeset -is found: +This reflects the removal of `/etc/my-app-config` and creation of a file and directory at `/etc/my-app.d/default.cfg`. +`/bin/my-app-tools` has also been replaced with an updated version. +Before committing this directory to a changeset, because it has a parent image, it is first compared with the directory tree of the parent snapshot, `f60c56784b83`, looking for files and directories that have been added, modified, or removed. +The following changeset is found: ``` Added: /etc/my-app.d/default.cfg @@ -472,11 +404,10 @@ Deleted: /etc/my-app-config A Tar Archive is then created which contains *only* this changeset: The added and modified files and directories in their entirety, and for each deleted item an entry for an empty file at the same location but with the basename of the -deleted file or directory prefixed with `.wh.`. The filenames prefixed with -`.wh.` are known as "whiteout" files. NOTE: For this reason, it is not possible -to create an image root filesystem which contains a file or directory with a -name beginning with `.wh.`. The resulting Tar archive for `f60c56784b83` has -the following entries: +deleted file or directory prefixed with `.wh.`. +The filenames prefixed with `.wh.` are known as "whiteout" files. +NOTE: For this reason, it is not possible to create an image root filesystem which contains a file or directory with a name beginning with `.wh.`. +The resulting Tar archive for `f60c56784b83` has the following entries: ``` /etc/my-app.d/default.cfg @@ -484,20 +415,17 @@ the following entries: /etc/.wh.my-app-config ``` -Any given image is likely to be composed of several of these Image Filesystem -Changeset tar archives. +Any given image is likely to be composed of several of these Image Filesystem Changeset tar archives. ## Combined Image JSON + Filesystem Changeset Format -There is also a format for a single archive which contains complete information -about an image, including: +There is also a format for a single archive which contains complete information about an image, including: - repository names/tags - all image layer JSON files - all tar archives of each layer filesystem changesets -For example, here's what the full archive of `library/busybox` is (displayed in -`tree` format): +For example, here's what the full archive of `library/busybox` is (displayed in `tree` format): ``` . @@ -520,13 +448,12 @@ For example, here's what the full archive of `library/busybox` is (displayed in └── repositories ``` -There are one or more directories named with the ID for each layer in a full -image. Each of these directories contains 3 files: +There are one or more directories named with the ID for each layer in a full image. +Each of these directories contains 3 files: * `VERSION` - The schema version of the `json` file * `json` - The JSON metadata for an image layer - * `layer.tar` - The Tar archive of the filesystem changeset for an image - layer. + * `layer.tar` - The Tar archive of the filesystem changeset for an image layer. The content of the `VERSION` files is simply the semantic version of the JSON metadata schema: @@ -545,29 +472,14 @@ And the `repositories` file is another JSON file which describes names/tags: } ``` -Every key in this object is the name of a repository, and maps to a collection -of tag suffixes. Each tag maps to the ID of the image represented by that tag. +Every key in this object is the name of a repository, and maps to a collection of tag suffixes. Each tag maps to the ID of the image represented by that tag. ## Loading an Image Filesystem Changeset -Unpacking a bundle of image layer JSON files and their corresponding filesystem -changesets can be done using a series of steps: +Unpacking a bundle of image layer JSON files and their corresponding filesystem changesets can be done using a series of steps: -1. Follow the parent IDs of image layers to find the root ancestor (an image -with no parent ID specified). -2. For every image layer, in order from root ancestor and descending down, -extract the contents of that layer's filesystem changeset archive into a -directory which will be used as the root of a container filesystem. +1. Follow the parent IDs of image layers to find the root ancestor (an image with no parent ID specified). +2. For every image layer, in order from root ancestor and descending down, extract the contents of that layer's filesystem changeset archive into a directory which will be used as the root of a container filesystem. - Extract all contents of each archive. - - Walk the directory tree once more, removing any files with the prefix - `.wh.` and the corresponding file or directory named without this prefix. - - -## Implementations - -This specification is an admittedly imperfect description of an -imperfectly-understood problem. The Docker project is, in turn, an attempt to -implement this specification. Our goal and our execution toward it will evolve -over time, but our primary concern in this specification and in our -implementation is compatibility and interoperability. + - Walk the directory tree once more, removing any files with the prefix `.wh.` and the corresponding file or directory named without this prefix.