Skip to main content

Pushing Docker Image to Docker Hub

Pushing Docker Image to Docker Hub
Table of Contents

A custom image that only exists on your laptop is not shipped; it is a local experiment. The moment a teammate or a server needs to run it, the image has to live in a registry. Docker Hub is the one most people start with, and the push workflow is the same shape you will later use against Azure Container Registry or Amazon ECR, so it is worth doing once by hand before automating it. This post walks through that manual path with a small nginx-based image.

What you’ll learn
#

  • Setting up a Docker Hub account and why the username matters for image names
  • Generating an access token instead of logging in with your password
  • Logging in from the CLI safely with --password-stdin
  • Building a custom nginx image from a Dockerfile
  • Tagging the image correctly and pushing it to the registry

1. Create a Docker Hub Account:
#

First, we need a Docker Hub account. Visit https://hub.docker.com/ and sign up; the free tier gives you unlimited public repositories, and you only need to upgrade for private ones. The username you pick is important, because it becomes part of every image name. To pull any image from your repository you use:

Docker pull <username>/<repository name>:<tag>

If we don’t pass a tag, it will fetch the latest image.

2. Generate access token:
#

You can log in to Docker Hub from the CLI with your account username and password, but that hands the CLI full access to your account, and every password change forces a re-login everywhere. Use an access token instead: you can scope it to what the job needs and revoke it without touching anything else.

Go to Account Settings > Security. In my case it shows some existing tokens, but yours may be blank. Click New Access Token.

Docker Hub security settings showing the access token list and New Access Token button

We want to read and write, so select Read & Write; if you also need to delete images, pick that permission instead. Click generate, then copy the token and keep it somewhere safe. It will not be shown again.

Docker Hub dialog showing the newly generated access token

3. Login to Docker Registry:
#

docker login -u <username> -p <accesstoken or account password>

Or just run `docker login` and it will prompt for username and password.

Passing the secret with -p leaves it in your shell history and CI job logs. Use the --password-stdin flag instead, which tells Docker to read the secret from STDIN so you can pipe it in from a file:

cat password.txt | docker login --username <username> --password-stdin

Here, password.txt holds the access token value we generated above.

Terminal output of docker login succeeding with –password-stdin

4. Building a custom image:
#

I have a very simple example using nginx as the base image; the code is in the Git repo. We just need a sample HTML file and a Dockerfile, both in the same folder:

Dockerfile code:

FROM nginx:latest
COPY index.html /usr/share/nginx/html

This Dockerfile pulls the latest nginx image and copies index.html into the html folder on top of it. Let’s build the custom image:

docker build -t my-custom-nginx .

The trailing . (dot) passes the current folder as the build context.

Output:

Terminal output of docker build completing for my-custom-nginx

5. Tag it and push the image to container registry
#

Now tag the locally created image with your Docker Hub username and the image name:

docker tag my-custom-nginx nitin27may/my-custom-nginx:1.0
docker push nitin27may/my-custom-nginx:1.0

In the commands above, nitin27may is my account name, my-custom-nginx is the repository name on Docker Hub, and 1.0 is the tag, so the full image reference is nitin27may/my-custom-nginx:1.0.

Key point: the registry username prefix in the tag is what routes the push. An untagged docker push my-custom-nginx fails because Docker has no idea which account owns it.

Terminal output of docker push uploading the tagged image

Below is the screenshot from Docker Hub showing the pushed image in my account.

Docker Hub repository page listing the my-custom-nginx image and its tag

Worth remembering
#

  • Images are named by registry account: tag as <username>/<repo>:<tag> before pushing, and pick explicit version tags over relying on latest.
  • Log in with a scoped access token piped through --password-stdin; -p on the command line leaks the secret into shell history.
  • The build/tag/push sequence is identical for ACR and ECR; only the login endpoint and name prefix change.

What’s next
#

Doing this by hand is fine exactly once. In the next article I automate the whole sequence with GitHub Actions, so every commit builds, tags, and pushes the image without anyone opening a terminal.

Related

Pushing Custom Images to Docker Hub Using GitHub Actions

··4 mins
In the previous article I built a custom nginx image and pushed it to Docker Hub by hand: build, tag, login, push. That works exactly once. The second time you forget the tag, the third time a teammate pushes from a laptop with a stale base image, and soon nobody can say which commit produced the image running in production. The fix is boring and reliable: let GitHub Actions do the build and push on every commit to master.