Hi,
I am trying to find a “minimalist” way to upload and run OCI container images to Fly.io. No docker, no builder, no Dockerfile, just a rootfs tar.gz together with OCI manifest and configuration JSONs. Directly “pushed” to registry.fly.io, without using any other Docker container image repository.
My app on Fly is named “test-lachine”.
I pushed an OCI image manifest (content-type application/vnd.oci.image.manifest.v1+json
), and its two blobs (config, content-type application/vnd.oci.image.config.v1+json
, and rootfs tar.gz, content-type application/vnd.oci.image.layer.v1.tar+gzip
) to registry.fly.io/test-lachine
, using HTTP basic authentification x:[[fly access token]] and OCI distribution REST API.
The manifest, as well as the blobs it references, are accepted, and can be fetched (see curl logs below).
However, when I try to deploy the app with “flyctl deploy”, I get:
==> Verifying app config
--> Verified app config
==> Building image
Searching for image 'registry.fly.io/test-lachine' remotely...
Error failed to fetch an image or build from source: You ran into an error connecting to the Fly API. If the error persists, keep this request ID to help Fly Support track it down: 01G685BENR82YGHP4TEFF99Q49-cdg
When trying to see the request sent (on a different container) I can see that a GET
request on /v2/test/manifests/latest
is made with Accept: application/vnd.docker.distribution.manifest.v2+json, application/json
by User-Agent: rest-client/2.1.0 (linux x86_64) ruby/3.1.2p20)
, suggesting that OCI manifests are not supported ?
Or maybe the problem comes from that the fact that the fetch requests are not authenticated ? If so, is it possible to deploy images already pushed to the internal Fly.io registry, without using any other registry ?
Thanks,
cURL logs showing that the manifests and blobs can be fetched:
> GET /v2/test-lachine/manifests/latest HTTP/2
> Host: registry.fly.io
> user-agent: curl/7.83.1
> authorization: Basic **REDACTED**
> accept: application/vnd.oci.image.manifest.v1+json
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
< HTTP/2 200
< content-length: 419
< content-type: application/vnd.oci.image.manifest.v1+json
< docker-content-digest: sha256:1fbb69be2e87c74dfd7e513c12ad218f44d686ddfec4e9e3b109d402a3fc14e9
< docker-distribution-api-version: registry/2.0
< etag: "sha256:1fbb69be2e87c74dfd7e513c12ad218f44d686ddfec4e9e3b109d402a3fc14e9"
< date: Thu, 23 Jun 2022 11:34:47 GMT
< server: Fly/9ece5bcd (2022-06-21)
< via: 2 fly.io
< fly-request-id: 01G685FMBQCCSQFH8DEXTZDVPS-cdg
<
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 291,
"digest": "sha256:c1cab53b10fa47a29918028e3d4679e9b38ef5002477470de3d56c72fe7a0942"
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 717142,
"digest": "sha256:bf075635a2e2a31f602096193389716776c9d8de7d0f7dd925caec89c65ae089"
}
]
}
* Connection #0 to host registry.fly.io left intact
> GET /v2/test-lachine/blobs/sha256:c1cab53b10fa47a29918028e3d4679e9b38ef5002477470de3d56c72fe7a0942 HTTP/2
> Host: registry.fly.io
> user-agent: curl/7.83.1
> accept: */*
> authorization: Basic **REDACTED**
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
< HTTP/2 200
< accept-ranges: bytes
< cache-control: max-age=31536000
< content-length: 291
< content-type: application/octet-stream
< docker-content-digest: sha256:c1cab53b10fa47a29918028e3d4679e9b38ef5002477470de3d56c72fe7a0942
< docker-distribution-api-version: registry/2.0
< etag: "sha256:c1cab53b10fa47a29918028e3d4679e9b38ef5002477470de3d56c72fe7a0942"
< date: Thu, 23 Jun 2022 11:39:43 GMT
< server: Fly/9ece5bcd (2022-06-21)
< via: 2 fly.io
< fly-request-id: 01G685RGSH0Y3HZ8NWBX22YERA-cdg
<
{
"architecture": "amd64",
"os": "linux",
"config": {
"ExposedPorts": { "8080/tcp":{} },
"Cmd": [ "/sbin/httpd","-p","8080","-f","-v" ]
},
"rootfs": {
"diff_ids": [ "sha256:4ea65d4a3ad2286ef38d081c5d85825af7411ab1490b71f93f8f2264ef3fca55" ],
"type": "layers"
}
}
> GET /v2/test-lachine/blobs/sha256:bf075635a2e2a31f602096193389716776c9d8de7d0f7dd925caec89c65ae089 HTTP/2
> Host: registry.fly.io
> user-agent: curl/7.83.1
> accept: */*
> authorization: Basic REDACTED
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [81 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
} [5 bytes data]
< HTTP/2 200
< accept-ranges: bytes
< cache-control: max-age=31536000
< content-length: 717142
< content-type: application/octet-stream
< docker-content-digest: sha256:bf075635a2e2a31f602096193389716776c9d8de7d0f7dd925caec89c65ae089
< docker-distribution-api-version: registry/2.0
< etag: "sha256:bf075635a2e2a31f602096193389716776c9d8de7d0f7dd925caec89c65ae089"
< date: Thu, 23 Jun 2022 11:41:41 GMT
< server: Fly/9ece5bcd (2022-06-21)
< via: 2 fly.io
< fly-request-id: 01G685W911ZGD71FCAHJAZ3X6R-cdg
<
[[[ ... data .... with correct SHA256.]]]