Learning paths / Containers / Registries

Try it: push to a registry

Reading · 12 min · Module 5, lesson 3 of 417 min left in this module

Module 5 · RegistriesLesson 3 of 4

Goal: Tag an image with a registry name, push it to Docker Hub or GHCR, and pull it back as a stranger would.

3:06 · captions and chapters · narrated with an AI-generated voice
Transcript

Narration uses an AI-generated voice.

[00:00] Where we're going

By the end of this video, your image will be in a registry, and anyone can pull it back and run it. Right now, the image lives only on your machine. A push copies it up to a registry. And from there, any machine can pull it, even one that has never signed in. One note before we start. We'll push to a local registry, running in Docker on this machine. It stands in for Docker Hub or GitHub's registry. The steps are the same. Only the name changes.

[00:32] The name says where

So first, the name. A push goes wherever the image's name points. It has three parts. The registry is the server. The repository is the owner and the image name. That's where your username goes. And the tag says which version. On Docker Hub, you can leave the registry out, and Docker fills it in. On GitHub, the name starts with GitHub's registry address. And in this video, it starts with the local registry's address, with the word you standing in for your username.

[01:08] Build and tag

In the app folder of the compose stack lab, build the image, for the processors most servers use. Look at the last step. That's its full name. We left out the registry and the owner, so Docker filled in Docker Hub, and the library owner.

With Docker Hub or GitHub, you'd sign in next, with a token, the way the lesson shows. This local registry doesn't ask. Now tag the image with its registry name. List your images, and there are two names. Look at the ID column. It's the same for both. A tag is just a second name, so nothing is copied.

[01:50] Push it

Now push it. Each layer uploads. Only the layers the registry doesn't have yet are sent, so the next push of a small change is quick. It ends with the tag, and a digest. On Docker Hub, your repository is already public. On GitHub, you switch the package to public in its settings.

[02:11] Pull it back

Now pull it back, the way a stranger would. Sign out, and delete both of your local names. Then run it by its full name. Docker can't find it here, so it pulls it from the registry. Ask the health check, and it answers, status okay. Then remove the container.

[02:29] Recap

So that's the whole trip. You built the image, and gave it a registry name. You pushed it up, and pulled it back. And the pull needed no credentials. So ComputeSphere can pull it too.

Here's a question to check yourself. After you sign out, the pull fails with denied. What's wrong? The image is still private. Signed out, you're a stranger, and a stranger can only pull a public image. Next, a short check on registries. I'll see you there.

You need Docker running (set up in lesson 3.1.1), the Learn samples you cloned in lesson 3.4.5, and a Docker Hub or GitHub account.

Which registry?

Either works for every lab in this path. Pick Docker Hub if you already have an account there, GHCR if your code lives on GitHub. Wherever this lesson says <you>, use your username in lowercase.

  1. Build the image

    You'll push compose-web, the small web app you'll run with Compose in the next module. Lesson 3.4.5 left you in learn/labs/bloated-app, so from there:

    cd ../compose-stack/app
    docker build --platform linux/amd64 -t compose-web:1.0.0 .
    

    Starting fresh? git clone https://github.com/computesphere-samples/learn.git, then cd learn/labs/compose-stack/app.

    --platform linux/amd64 builds for the processors most servers use, ComputeSphere's included. Built on an Apple Silicon Mac without it, the image won't start on ComputeSphere.

    You should seeA build that ends with naming to docker.io/library/compose-web:1.0.0.

  2. Make a token

    In Docker Hub, create a repository named compose-web and set it to Public. Then go to Account settings, Personal access tokens, Generate new token, with read and write access.

    You should seeA token copied somewhere safe; it's shown only once.

  3. Sign in

    read -s CR_PAT          # paste the token, then Enter
    
    echo "$CR_PAT" | docker login -u <you> --password-stdin
    

    Then unset CR_PAT, so the token doesn't linger in your shell.

    You should seeLogin Succeeded

  4. Tag it for the registry

    docker tag compose-web:1.0.0 <you>/compose-web:1.0.0
    
    docker image ls
    

    A tag is a second name for the same image, so nothing is copied.

    You should seeTwo names with the same image ID.

  5. Push it

    docker push <you>/compose-web:1.0.0              # Docker Hub
    docker push ghcr.io/<you>/compose-web:1.0.0      # GHCR
    

    Only layers the registry doesn't already have are uploaded, so the next push of a small change is quick.

    You should seeThe layers upload, then a line with 1.0.0 and a sha256 digest.

  6. Make it public

    Docker Hub: open your compose-web repository; it's already public.

    GHCR: on GitHub open Your profile, then Packages, then compose-web. Choose Package settings, then Change visibility under Danger Zone, and pick Public. A public package can't be made private again.

    You should seeThe image page shows the 1.0.0 tag and Public.

  7. Pull it back as a stranger

    Sign out, delete your local copies, and run it from the registry. <image> is the full name you pushed. The app listens on 3000; if port 3000 is taken on your machine, use -p 3001:3000 and localhost:3001.

    docker logout                                    # add ghcr.io for GHCR
    docker rmi compose-web:1.0.0 <image>
    docker run -d --rm --name compose-web --platform linux/amd64 -p 3000:3000 <image>
    curl localhost:3000/healthz
    docker rm -f compose-web
    

    Docker pulls it with no credentials, so ComputeSphere can too. --platform linux/amd64 matters on an Apple Silicon Mac: you built the image for amd64 in step 1, and without the flag Docker stops with no matching manifest for linux/arm64/v8. With it, Docker runs the image in emulation. On other machines the flag changes nothing.

    Check yourself

    The pull fails with denied or unauthorized after you sign out. What's wrong?

    You should see{"status":"ok"}