Deploy your Own Image to CloudRun - CloudRun 101 - Part 2
🚀 Deploying Your Docker Image to Cloud Run with a Private Artifact Registry: A Step-by-Step Guide
In the last post of this series, we set up our first CloudRun service with a simple "Hello, World." Now, we're ready to take the next step.
In this post, you'll learn how to set up a private artifact registry and use it to deploy your own Docker image to CloudRun. 🚀
Prerequisites
I assume you followed the previous post or have equivalent knowledge. If you're unsure, you can always go back and review or get the previous code from GitHub.
You must have a Google Cloud account and project, as well as gcloud and Terraform installed and running. We’ll also add Docker to the mix this time. Chances are, you already have it installed, but if not, you can find instructions on Docker's website.
To check if Docker is set up correctly, run the following command in your terminal:
docker run hello-world
You should see something like this:
Hello from Docker!
This message shows that your installation appears to be working correctly.
Great, now let's dive into today's task: getting your own Docker 🐳 image up to CloudRun!
Artifact Registry
The Artifact Registry is Google’s product for storing artifacts, including (but not limited to) Docker containers within your project. While you don’t have to use it to deploy your images to CloudRun—DockerHub works just fine—I find it convenient to keep everything in one place.
Like CloudRun, Artifact Registry includes a free tier, allowing you to store up to 500 megabytes for free. If you exceed that, you’ll be charged $0.10 per gigabyte per month. Additionally, data transfers crossing regions incur charges, so we'll set up our registry in the same location as our CloudRun service to avoid extra costs. However, even if you do incur charges, the prices are very reasonable. 💰
To get started, we must first activate the Artifact Registry API. Open apis.tf
and add the following:
resource "google_project_service" "artifact_registry_api" {
project = local.project_id
service = "artifactregistry.googleapis.com"
disable_on_destroy = false
}
This will enable the Artifact Registry API for your project.
Next, create a new file called artifactregistry.tf
and enter the following:
resource "google_artifact_registry_repository" "artifact_registry" {
location = local.region
repository_id = "docker-repository"
description = "Docker Repository for CloudRun"
format = "DOCKER"
cleanup_policies {
id = "delete"
action = "DELETE"
condition {
older_than = "3600s"
}
}
}
Here, local.region
refers to the region we set up in constants.tf
in the last post. This is also used in the CloudRun configuration. Since we're just experimenting, I've added a cleanup policy that removes each image after one hour to ensure we don't incur any unwanted costs.
That’s all for now. Run terraform apply
to set up the artifact registry. In the output, you should see something like this:
...
# google_artifact_registry_repository.artifact_registry will be created
+ resource "google_artifact_registry_repository" "artifact_registry" {
...
+ description = "Docker Repository for CloudRun"
...
+ format = "DOCKER"
...
+ location = <your location>
+ mode = "STANDARD_REPOSITORY"
...
+ project = <your project>
+ repository_id = "docker-repository"
...
+ cleanup_policies {
+ action = "DELETE"
+ id = "delete"
+ condition {
+ older_than = "3600s"
+ package_name_prefixes = []
+ tag_prefixes = []
+ tag_state = "ANY"
+ version_name_prefixes = []
# (1 unchanged attribute hidden)
}
}
}
Before we can publish to the artifact registry, we must authorize access. This can be easily done via:
gcloud auth configure-docker <your location>-docker.pkg.dev
Let's go ahead and publish a Docker image. 🐳
Docker Image
Now we are ready to push a Docker image to our registry. If you don't have one on hand, you can use the small Flask application I wrote for this purpose. It has a GET and a POST endpoint, which we can use to verify that everything is working correctly.
Get the Python code and Dockerfile from GitHub. Then navigate to the directory where you downloaded the files and build the Docker image with the following command:
docker build <path to the files> -t cloudrun101
Next, we need to add a tag containing the location of the registry and the project ID:
docker tag cloudrun101 <your region from constants.tf>-docker.pkg.dev/<your project id>/docker-repository/cloudrun101:latest
Finally, we can push the image:
docker push <your region from constants.tf>-docker.pkg.dev/<your project id>/docker-repository/cloudrun101
If everything succeeded, you can check the registry in the web interface and see something like this:
Now we can use it in our CloudRun service.
Use the Image in CloudRun
We only need to change the image name in our cloudrun.tf
file:
# Terraform configuration to create a Cloud Run service
resource "google_cloud_run_v2_service" "service" {
....
template {
containers {
image = "${local.region}-docker.pkg.dev/${local.project_id}/docker-repository/cloudrun101:latest"
}
}
}
Run terraform apply
to update your CloudRun revision with the new image. Note that I kept the public access as discussed last time for easier testing. Once terraform apply
succeeds, you can test if the image works by opening <your-cloudrun-url>/hello
in your browser.
This may not be the most useful CloudRun service, but it runs our own image from Artifact Registry! Great! 🎉
Wrapping Up
Congratulations! 🎉 You've set up a private artifact registry and deployed your own Docker image to CloudRun.
Remember to run terraform destroy
to clean up your resources.
Stay tuned for the next post, where we'll connect Pub/Sub to CloudRun. Thanks for following along, and happy coding! 🚀