For over ten years, I’ve had a background desire that I’ve been trying to find a solution too. In short, it was about sharing programs that I wrote, simply.
Writing Python back in 2014, the worst part was sharing the code with someone else. Technical, fine. I can have them install the correct dependencies. But non-technical? Good luck getting them to install the Python runtime, installing dependencies or anything like that.
The answer eventually came around to binaries. Discovering Golang felt like the exact kind of discovery I needed. Built in binary compilation? Cross OS capability? Sign me up!
But, then there was a new issue. How do I host a binary to be available for download? I tried a basic file server, s3 object storage, licensing software, but nothing has felt quite right. Except, I genuinely like pre-signed urls available with s3 storage.
So, my requirements were:
- Ability to share a single binary. It should be able to include extra items like fonts / config variables.
- Cross OS compilation. Easy to distribute to Windows / Mac
- Easy to host, easy to update and provide updates for.
OCI Storage
Well, I stumbled upon Oras, and it feels like the right kind of storage.
OCI storage is best known for Docker image storage. Think docker image pull or push
I already have a docker registry, so this would just piggyback on top of that.
Uploading is fine. Oras provides a cli called oras to provide push and pull. If you’re already logged into using Docker, then this doesn’t require any additional authentication. I’m a big Docker fan, so this worked out.
oras push docker.mydomain.tld/binaries/myApp:v1 ./myAppTo download, it’s the opposite: oras pull [...]. But you probably see the problem here!
If I was so preoccupied with easy distribution to non-technical folks, I have no chance distributing this to people and leading
with “Well, first download oras…”.
Downloading from OCI, Directly
I needed a download link. Which led me to the question, how do you download something directly from a docker OCI image. repository? Turns out that’s not an especially easy answer
In fact, debugging with docker is cryptic as well. What network calls does docker pull use? Who knows? Good luck!
I ended up using a
mocking tool (mockoon) to proxy the request and reverse engineer the requests
made by docker.
Eventually, as a first iteration I came up with this:
curl https://docker.mydomain.tld/v2/myApp/manifests/sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a \ -sL -H 'Accept: application/vnd.oci.image.manifest.v1+json' \ | jq -r '.layers[0].digest'You can see the response below. You’ll see under the layers there is a digest. Since we uploaded a binary, there’s only one layer.
{9 collapsed lines
"schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", "artifactType": "application/vnd.unknown.artifact.v1", "config": { "mediaType": "application/vnd.oci.empty.v1+json", "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", "size": 2, "data": "e30=" }, "layers": [ { "mediaType": "application/vnd.oci.image.layer.v1.tar", "digest": "sha256:aa437812b9bd7457a9d1945680c453d2ef217264fbf5ed896053991d2b212d15",9 collapsed lines
"size": 7602468, "annotations": { "org.opencontainers.image.title": "straico" } } ], "annotations": { "org.opencontainers.image.created": "2025-12-18T04:10:33Z" }}To download this, we can just download it directly:
wget https://docker.mydomain.tld/v2/myApp/blobs/sha256:aa437812b9bd7457a9d1945680c453d2ef217264fbf5ed896053991d2b212d15 -O /ram/myAppAutomated
Ok. But can I just download it as easily as providing the same kind of url like in docker? Something like this?
./download.sh docker.mydomain.tld/myApp:v1We need to follow through on a few steps
- (Optional) List all tags
- Get manifest associated with a specific tag
- Get first layer associated with that manifest
- Download the layer, which we know is our binary
For far more details, go here, but we’ll just implement it here really quick:
#!/usr/bin/env bashurl="$(echo "$1" | cut -d '/' -f1)"path="$(echo "$1" | cut -d '/' -f2)"
package="$(echo "$path" | cut -d ':' -f1)"tag="$(echo "$path" | cut -d ':' -f2)"
# Step 1, List all tagscurl "https://$url/v2/$package/tags/list"
# Step 2, get the manifest for the tag we want (Plus an extra filename variablemanifest="$(curl -sL "https://$url/v2/$package/manifests/$tag" -H 'Accept: application/vnd.oci.image.manifest.v1+json')"filename="$(echo $manifest | jq -r '.layers[0].annotations."org.opencontainers.image.title"')"
# Step 3, we get the digest of the first layerdigest="$(echo $manifest | jq -r '.layers[0].digest')"
# Finally, we download the binarywget "https://$url/v2/$package/blobs/$digest" -O "$filename"Bonus: Generating a link instead
At the start, I said I wanted to be able to share this with non-technical users, well sharing this bash script doesn’t solve that either.
Realistically, you could just echo out the url and share that instead. It would look something like
https://docker.mydomain.tld/v2/myApp/blobs/sha256:aa437812b9bd7457a9d1945680c453d2ef217264fbf5ed896053991d2b212d15