Welcome to the third lesson in our course on working with container registries. In the previous lesson, you created a secure Artifact Registry repository with vulnerability scanning enabled. Now you have an empty repository waiting for container images, but how do you actually get your applications into Artifact Registry?
This lesson bridges that gap by teaching you the complete workflow for getting locally built Docker images into your Artifact Registry repository. We'll start with a simple containerized web application, build it into a Docker image on your local machine, authenticate Docker to work with Artifact Registry, tag the image with the proper Google Cloud naming convention, and finally push it to your repository.
By the end of this lesson, you'll execute the full sequence: docker build to create your image locally, gcloud auth configure-docker to authenticate, docker tag to prepare the image for Artifact Registry, and docker push to upload it. This workflow forms the foundation for all Artifact Registry operations, whether you're working manually or setting up automated CI/CD pipelines.
The sample application we'll use is a minimal Flask-based web application that responds with "Hello from Artifact Registry!" when accessed. While simple, this demonstrates the complete process we'll use for any containerized application, from microservices to complex web applications.
Before pushing your first image to Artifact Registry, you need to confirm that your repository from the previous lesson exists and gather the specific details required for the push process. The repository URI you created earlier contains your Google Cloud project ID and location, both of which are essential for the tagging and authentication steps.
Run this command to verify your repository exists and note its details:
The output should show your repository details, including the repository format (DOCKER) and location. From this information, you can construct your repository URI, which looks like us-central1-docker.pkg.dev/PROJECT_ID/my-web-app. This URI contains three critical pieces of information: your location (us-central1), your Google Cloud project ID (PROJECT_ID), and your repository name (my-web-app). We'll need these components for the authentication and tagging steps.
Your gcloud CLI must be configured with credentials that have Artifact Registry permissions. The key IAM roles you need are roles/artifactregistry.writer for pushing images and roles/artifactregistry.reader for pulling images. Note that while you needed roles/artifactregistry.repoAdmin to create your repository in the previous lesson, pushing images only requires roles/artifactregistry.writer. This separation allows teams to grant developers push access without giving them repository management permissions. You can verify your current project with:
The first step in getting an image to Artifact Registry is having an image to push. We'll build a simple Flask-based web application that demonstrates the complete containerization process. The application consists of three files: a Python application file with our Flask server, a requirements file listing dependencies, and a Dockerfile that defines how to build the container image.
The Python application in docker-app/app.py contains a simple Flask web server that responds with "Hello from Artifact Registry!" when accessed. The Dockerfile uses python:3.11-slim as the base image for a lightweight container, installs Flask from requirements.txt, copies the application code, and exposes port 5000 for web traffic.
Navigate to the directory containing your application files and build the Docker image:
The docker build command reads the Dockerfile in the current directory (indicated by the .) and creates an image tagged as my-web-app. The build process downloads the python:3.11-slim base image and packages your Flask application into a complete container image.
After the build completes, verify that your image exists locally:
You should see output showing your newly created image with the my-web-app repository name and tag. This local image is now ready to be tagged and pushed to Artifact Registry, but first, you need to authenticate Docker to work with your Google Cloud registry.
Before Docker can push images to Artifact Registry, it must authenticate with the registry using your Google Cloud credentials. Unlike some other registries that require frequent re-authentication, Google Cloud's authentication setup is typically a one-time configuration per machine that persists across sessions.
The authentication process configures Docker to use your gcloud credentials when accessing Artifact Registry. Google provides a straightforward command that sets up this integration:
Replace us-central1 with your actual location if you're using a different region. This command updates your Docker configuration file to use gcloud as a credential helper for the specified Artifact Registry hostname. The hostname follows the pattern <location>-docker.pkg.dev.
When the configuration succeeds, you'll see a message confirming that Docker is now configured to use gcloud for authentication to the specified registry. This is a persistent configuration that remains active as long as your gcloud credentials are valid.
You can configure multiple Artifact Registry locations by running the command again with different hostnames. In automated environments like CI/CD pipelines, this authentication step is typically included in setup scripts, often combined with service account authentication for non-interactive workflows.
Docker images must be tagged with the complete Artifact Registry repository URI before they can be pushed to Artifact Registry. The tag tells Docker exactly where to push the image and what to call it in the registry. Artifact Registry requires a specific naming format that includes your location, project ID, repository name, image name, and tag.
Tag your local image with the Artifact Registry repository URI:
Replace PROJECT_ID with your actual Google Cloud project ID and adjust the location if needed. Remember, you can find your project ID by running gcloud config get-value project. This command creates a new tag for your existing image without duplicating the image data. The format <location>-docker.pkg.dev/<project-id>/<repository-name>/<image-name>:<tag> is required for all Artifact Registry images.
Note that the repository name (my-web-app) appears in the path, followed by the image name (also my-web-app in this case). While we're using the same name for both, they can be different. The repository is the container you created in the previous lesson, while the image name identifies this specific application within that repository.
The tag portion (:latest in this example) is optional but recommended. If you omit it, Docker assumes :latest. While :latest is convenient for development, production environments typically use specific version tags like :v1.2.3 or :build-456 to ensure predictable deployments.
With your image properly tagged and Docker authenticated to Artifact Registry, you can now push the image to your repository. The push process uploads all the image layers to Artifact Registry, where they're stored securely and made available for deployment.
Push your tagged image to Artifact Registry:
The push command uploads your image layers to Artifact Registry. You'll see progress indicators showing each layer being pushed. Docker optimizes this process by only uploading layers that don't already exist in the registry, which speeds up subsequent pushes of related images.
Once the push completes, verify that your image is now stored in Artifact Registry:
This command shows all images in your repository. You should see your image with the :latest tag along with details like the image digest and upload timestamp. The image digest is a unique identifier based on the image content, ensuring integrity and enabling precise image references.
For more detailed information about a specific image, including its layers and metadata, use:
Since the Container Analysis API is enabled for your Google Cloud project, vulnerability scanning automatically begins when you push images to Artifact Registry. You can check the scan results by viewing the image details in the Google Cloud Console or by querying the Container Analysis API. Initial scans typically complete within a few minutes and provide valuable security insights about your container images.
Understanding common issues helps you troubleshoot image pushes quickly.
- Authentication Failures: If you see "permission denied," re-run
gcloud auth configure-docker <location>-docker.pkg.dev. Ensure you are logged intogcloudwith an account that has the correct permissions. - Incorrect URI or Tag Format: Push failures can result from typos in the image tag. The URI must exactly match the format:
<location>-docker.pkg.dev/<project-id>/<repository-name>/<image-name>:<tag>. - Location or Project ID Mismatch: Ensure the location and project ID in your image tag match the repository's configuration. Use the project ID, not the project name.
- Insufficient IAM Permissions: "Permission denied" errors often mean your account lacks the
roles/artifactregistry.writerrole. This role is required to push images. - Accidental Tag Overwrites: Pushing an image with a tag that already exists (e.g.,
:latest) overwrites the previous version. For production, use unique tags like version numbers or Git SHAs to prevent accidental updates.
Most of these issues stem from simple configuration errors and can be resolved by carefully checking your commands and permissions.
You've successfully learned the complete workflow for getting Docker images into Artifact Registry. Starting with a local Docker image, you authenticated Docker to work with Artifact Registry using gcloud credentials, tagged your image with the proper Google Cloud naming format, and pushed it to your secure repository. You also verified the upload and confirmed that vulnerability scanning is available through the Container Analysis API.
This end-to-end process — build, authenticate, tag, push, verify — forms the foundation for all Artifact Registry operations. Whether you're deploying a simple web application or managing complex microservices architectures, these same steps apply. The authentication and tagging steps are particularly important to master since they're required for every push operation.
In the upcoming practice exercises, you'll work through this entire workflow hands-on. You'll push your own images to Artifact Registry, experiment with different tags, examine vulnerability scan results, and troubleshoot common errors like authentication failures and tag formatting issues. These exercises will reinforce the concepts and give you confidence to use Artifact Registry in your own projects and production environments.
