1"use strict";(globalThis.webpackChunkoras_www||=[]).push([[7495],{88462(e,n,o){o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"how_to_guides/manifest_config","title":"Manifest Config","description":"According to OCI Image Manifest Specification,","source":"@site/versioned_docs/version-1.3/how_to_guides/manifest_config.mdx","sourceDirName":"how_to_guides","slug":"/how_to_guides/manifest_config","permalink":"/docs/how_to_guides/manifest_config","draft":false,"unlisted":false,"editUrl":"https://github.com/oras-project/oras-www/edit/main/versioned_docs/version-1.3/how_to_guides/manifest_config.mdx","tags":[],"version":"1.3","sidebarPosition":4,"frontMatter":{"title":"Manifest Config","sidebar_position":4},"sidebar":"tutorialSidebar","previous":{"title":"Pushing and Pulling","permalink":"/docs/how_to_guides/pushing_and_pulling"},"next":{"title":"Manifest Annotations","permalink":"/docs/how_to_guides/manifest_annotations"}}');var t=o(74848),s=o(28453);const a={title:"Manifest Config",sidebar_position:4},c="Manifest Config",l={},d=[{value:"Customize config",id:"customize-config",level:2},{value:"Docker behaviors",id:"docker-behaviors",level:2},{value:"Empty config file",id:"empty-config-file",level:3},{value:"Empty JSON object",id:"empty-json-object",level:3},{value:"Arbitrary OS",id:"arbitrary-os",level:3},{value:"Arbitrary config media type",id:"arbitrary-config-media-type",level:3},{value:"Push / Pull config",id:"push--pull-config",level:2}];function r(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"manifest-config",children:"Manifest Config"})}),"\n",(0,t.jsxs)(n.p,{children:["According to ",(0,t.jsx)(n.a,{href:"https://github.com/opencontainers/image-spec/blob/main/manifest.md#image-manifest-property-descriptions",children:"OCI Image Manifest Specification"}),",\nthe property ",(0,t.jsx)(n.code,{children:"config"})," is required by an image manifest.\nSince ",(0,t.jsx)(n.code,{children:"oras"})," does not make use of the configuration object, an empty JSON object ",(0,t.jsx)(n.code,{children:"{}"})," is used by default when pushing, and never being fetched when pulling."]}),"\n",(0,t.jsx)(n.p,{children:"The descriptor of the default configuration object is fixed as follows."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "mediaType": "application/vnd.oci.image.config.v1+json",\n "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",\n "size": 2\n}\n'})}),"\n",(0,t.jsx)(n.h2,{id:"customize-config",children:"Customize config"}),"\n",(0,t.jsxs)(n.p,{children:["To push a file ",(0,t.jsx)(n.code,{children:"hi.txt"})," with the custom manifest config file ",(0,t.jsx)(n.code,{children:"config.json"}),", you can run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"oras push --config config.json localhost:5000/hello:latest hi.txt\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The media type of the config is set to the default value ",(0,t.jsx)(n.code,{children:"application/vnd.unknown.config.v1+json"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the file reference, it is possible to change the media type of the manifest config. To push a file ",(0,t.jsx)(n.code,{children:"hi.txt"})," with the custom manifest config file ",(0,t.jsx)(n.code,{children:"config.json"})," with the custom media type ",(0,t.jsx)(n.code,{children:"application/vnd.oras.config.v1+json"}),", run"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"oras push --config config.json:application/vnd.oras.config.v1+json localhost:5000/hello:latest hi.txt\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In addition, it is possible to pass a null device ",(0,t.jsx)(n.code,{children:"/dev/null"})," (",(0,t.jsx)(n.code,{children:"NUL"})," on Windows) to ",(0,t.jsx)(n.code,{children:"oras"})," for an empty config file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"oras push --config /dev/null:application/vnd.oras.config.v1+json localhost:5000/hello:latest hi.txt\n"})}),"\n",(0,t.jsx)(n.h2,{id:"docker-behaviors",children:"Docker behaviors"}),"\n",(0,t.jsxs)(n.p,{children:["The config used by ",(0,t.jsx)(n.code,{children:"oras"})," is not a real config.\nTherefore, the pushed image cannot be recognized or pulled by ",(0,t.jsx)(n.code,{children:"docker"})," as expected.\nIn this section, docker behaviors are shown given various configurations."]}),"\n",(0,t.jsx)(n.h3,{id:"empty-config-file",children:"Empty config file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ oras push --export-manifest /dev/null localhost:5000/hello:latest hi.txt\nUploading a948904f2f0f hi.txt\nPushed localhost:5000/hello:latest\nDigest: sha256:34897815cbf060e1d11b4c2938c7476d9326269e2179aef3559ce25af11a9ced\n$ docker pull localhost:5000/hello:latest\nlatest: Pulling from hello\na948904f2f0f: Extracting [==================================================>] 12B/12B\nunexpected end of JSON input\n"})}),"\n",(0,t.jsx)(n.h3,{id:"empty-json-object",children:"Empty JSON object"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ cat config.json\n{}\n$ oras push --config config.json localhost:5000/hello:latest hi.txt\nUploading a948904f2f0f hi.txt\nPushed localhost:5000/hello:latest\nDigest: sha256:44d13da4d42a20ceed7ee3411b103a6f82ef02a2eac981d5e3d799c41e3015d7\n$ docker pull localhost:5000/hello:latest\nlatest: Pulling from hello\na948904f2f0f: Pulling fs layer\ninvalid rootfs in image configuration\n"})}),"\n",(0,t.jsx)(n.h3,{id:"arbitrary-os",children:"Arbitrary OS"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'$ cat config.json\n{\n "architecture": "cloud",\n "os": "oras"\n}\n$ oras push --config config.json localhost:5000/hello:latest hi.txt\nUploading a948904f2f0f hi.txt\nPushed localhost:5000/hello:latest\nDigest: sha256:e6428c9cb88505a1859a01f4b7602bdb263d5f65399ef72d3397afd9bfb25b2c\n$ docker pull localhost:5000/hello:latest\nlatest: Pulling from hello\na948904f2f0f: Extracting [==================================================>] 12B/12B\noperating system is not supported\n'})}),"\n",(0,t.jsx)(n.h3,{id:"arbitrary-config-media-type",children:"Arbitrary config media type"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'$ oras push --artifact-type application/vnd.oras.config.v1+json localhost:5000/hello:latest hi.txt\nUploading a948904f2f0f hi.txt\nPushed localhost:5000/hello:latest\nDigest: sha256:5d8ea018049870aab566350660b9a003c646a7f955f9996d35cc0c71bf41b3d0\n$ docker pull localhost:5000/hello:latest\nError response from daemon: Encountered remote "application/vnd.oras.config.v1+json"(unknown) when fetching\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Layers are not pulled in this case. Thus ",(0,t.jsx)(n.strong,{children:"it is encouraged to specify customized config media type"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Additionally, the latest version of ",(0,t.jsx)(n.code,{children:"dockerd"})," recognizes OCI manifests and does not verify the OCI config media type."]}),"\n",(0,t.jsx)(n.h2,{id:"push--pull-config",children:"Push / Pull config"}),"\n",(0,t.jsxs)(n.p,{children:["As mentioned in the beginning of this doc, the manifest config is not used by ",(0,t.jsx)(n.code,{children:"oras"})," and is not worth pulling in most scenarios.\nHowever, it is still possible to push pullable config with the ",(0,t.jsx)(n.code,{children:"oras"})," CLI by leveraging ",(0,t.jsx)(n.a,{href:"/docs/how_to_guides/manifest_annotations",children:"Manifest Annotations"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'$ cat config.json\n{\n "foo": "bar"\n}\n$ cat annotations.json\n{\n "$config": {\n "org.opencontainers.image.title": "config.json"\n }\n}\n$ oras push --config config.json --annotation-file annotations.json localhost:5000/hello:latest hi.txt\nUploading a948904f2f0f hi.txt\nUploading 57f840b6073c config.json\nPushed localhost:5000/hello:latest\nDigest: sha256:12e3de7e4a65ffc46a6158ac2df07ecc6fd1af8b0109b4c42a90067f7e907f43\n$ oras pull -a localhost:5000/hello:latest\nDownloaded a948904f2f0f hi.txt\nDownloaded 57f840b6073c config.json\nPulled localhost:5000/hello:latest\nDigest: sha256:12e3de7e4a65ffc46a6158ac2df07ecc6fd1af8b0109b4c42a90067f7e907f43\n'})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},28453(e,n,o){o.d(n,{R:()=>a,x:()=>c});var i=o(96540);const t={},s=i.createContext(t);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.