Container Registry and Builds
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. See the section bibliography for the reference material consulted while preparing these pages. |
Commands and behaviour below are current for the gcloud CLI 586.x line, Artifact Registry and Cloud Build as documented on
docs.cloud.google.com, Jib 3.x and the google-github-actions/auth action v3 (checked 2026-09-30); re-verify against
gcloud version and the linked reference pages before relying on them in a pipeline.
The Bookshelf services (catalog-api, orders-api and notifier, see Google Cloud) all start as
source code in a Git repository and end as container images that Cloud Run or GKE pull. Two Google Cloud products sit in
between: Artifact Registry stores the images (and Maven, npm and Python packages), and Cloud Build turns source into those
artifacts. This page covers both, plus the ways to build without writing a Dockerfile and the GitHub Actions route that
authenticates without a key. Container registries and image tagging in general are in
Registries and Docker Hub; pipeline mechanics in
Docker CI/CD with GitHub Actions; the AWS counterpart is Container Registry.
Start by enabling the APIs used here:
gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com \
containerscanning.googleapis.com
Derived from Store Docker container images in Artifact Registry.
Artifact Registry and the end of Container Registry
Artifact Registry is the single managed store for build artifacts on Google Cloud. A repository is regional or multi-regional, holds one format, and has one mode.
- Formats
-
Docker (and OCI) images, Maven, npm, Python (PyPI), Go modules, Apt, Yum, Helm charts (as OCI), generic files and Kubeflow pipelines. The format is fixed at creation.
- Standard repositories
-
Where your own artifacts are pushed. Cleanup policies and most settings apply here.
- Remote repositories
-
A pull-through cache of an upstream such as Docker Hub, Maven Central, npm or PyPI. See Remote and virtual repositories.
- Virtual repositories
-
One endpoint that merges several standard and remote repositories by priority.
Image addresses follow the pattern LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:TAG. For Bookshelf the Docker
repository is bookshelf, giving us-central1-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api.
Container Registry is gone
Container Registry (gcr.io, eu.gcr.io, us.gcr.io, asia.gcr.io) was deprecated on 2023-05-15 and shut down on
2025-03-18. Writes are no longer possible, and images that were not copied to Artifact Registry before the shutdown
are no longer available. Older guides, tutorials and Cloud Build examples still push to gcr.io/PROJECT_ID/IMAGE; the
current approach is an Artifact Registry Docker repository with a pkg.dev address.
The gcr.io host names themselves still work, but only as gcr.io repositories hosted in Artifact Registry: a special
repository named gcr.io (or us.gcr.io and so on) created in your project, which serves the old address from
Artifact Registry. Use it only to keep existing deployment manifests working while you migrate; new code should use
pkg.dev addresses. Google’s migration tooling copies existing images and can redirect gcr.io traffic:
# Create a gcr.io repository in Artifact Registry (multi-region "us" maps to gcr.io)
gcloud artifacts repositories create gcr.io \
--repository-format=docker --location=us \
--description="Serves gcr.io addresses from Artifact Registry"
# Copy images and enable redirection of gcr.io hosts
gcloud artifacts docker upgrade migrate --projects="$PROJECT_ID"
Derived from Transition from Container Registry and Container Registry deprecation.
Creating a Docker repository
In the Google Cloud console
-
Select the project in the project picker and open Artifact Registry (use the search bar, or the navigation menu under CI/CD). Enable the API if prompted.
-
Select Create repository.
-
Enter the name
bookshelf, choose format Docker, mode Standard, location type Region andus-central1. -
Leave the encryption as Google-managed encryption key (choose a Cloud KMS key for a customer-managed key), set Immutable image tags if releases must never be overwritten, and optionally enable vulnerability scanning.
-
Optionally add cleanup policies in the same dialog (see Cleanup policies), then select Create.
-
Open the repository and select Setup instructions to see the
gcloud auth configure-dockercommand.
With the gcloud CLI
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
REPO=bookshelf
gcloud artifacts repositories create "$REPO" \
--repository-format=docker \
--location="$REGION" \
--description="Bookshelf service images" \
--immutable-tags
# Let the local Docker client use gcloud credentials for this registry host
gcloud auth configure-docker "$REGION-docker.pkg.dev"
# Tag and push a locally built image
docker build -t "$REGION-docker.pkg.dev/$PROJECT_ID/$REPO/catalog-api:1.0.0" .
docker push "$REGION-docker.pkg.dev/$PROJECT_ID/$REPO/catalog-api:1.0.0"
gcloud artifacts docker images list "$REGION-docker.pkg.dev/$PROJECT_ID/$REPO" \
--include-tags --format="table(package,version,tags)"
Derived from Store Docker container images in Artifact Registry and Configure authentication to Artifact Registry for Docker.
gcloud auth configure-docker writes a credential helper entry into the Docker configuration. On machines without gcloud
(or in CI) a short-lived access token works with a standard docker login:
gcloud auth print-access-token | \
docker login -u oauth2accesstoken --password-stdin "https://$REGION-docker.pkg.dev"
Derived from Configure authentication to Artifact Registry for Docker.
Immutable tags (--immutable-tags) make a tag fixed once it is pushed, which is the safe default for release tags
that deployment manifests pin. Digests (image@sha256:…) are always immutable and are what Cloud Run and GKE
record after a deploy.
Maven, npm and Python repositories
The same service hosts language packages, which suits Bookshelf’s shared bookshelf-domain library. Each format has a
print-settings helper that emits the client configuration for you.
In the Google Cloud console
-
Open Artifact Registry and select Create repository.
-
Choose the format Maven (or npm or Python), mode Standard and the region. For Maven also choose the version policy: Release, Snapshot or Mixed.
-
Select Create, open the repository and select Setup instructions for the
pom.xml,.npmrcorpipsnippet.
With the gcloud CLI
gcloud artifacts repositories create bookshelf-maven \
--repository-format=maven --location="$REGION" \
--version-policy=release
gcloud artifacts repositories create bookshelf-npm \
--repository-format=npm --location="$REGION"
gcloud artifacts repositories create bookshelf-python \
--repository-format=python --location="$REGION"
# Print the client configuration to paste into pom.xml, .npmrc or pip.conf
gcloud artifacts print-settings mvn --repository=bookshelf-maven --location="$REGION"
gcloud artifacts print-settings npm --repository=bookshelf-npm --location="$REGION" --scope=@bookshelf
gcloud artifacts print-settings python --repository=bookshelf-python --location="$REGION"
Derived from Store Java packages, Store Node.js packages and Store Python packages.
The Maven output uses the artifactregistry:// URL scheme with the Artifact Registry Maven wagon, which authenticates
with Application Default Credentials:
<distributionManagement>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/my-project-id/bookshelf-maven</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/my-project-id/bookshelf-maven</url>
</repository>
</repositories>
<build>
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>RELEASE_VERSION</version>
</extension>
</extensions>
</build>
Replace RELEASE_VERSION with the current wagon release listed in that page. For npm, run
npx google-artifactregistry-auth to refresh the token in .npmrc; for Python, install the
keyrings.google-artifactregistry-auth package so pip and twine use gcloud credentials instead of a stored password.
Application Default Credentials are covered in Identity and Access.
Remote and virtual repositories
A remote repository caches an upstream source on first pull and serves it from then on, which speeds up builds, keeps them working when the upstream is down or rate-limiting, and gives one place to scan dependencies. Supported upstreams include Docker Hub, other Docker registries, Maven Central, npm, PyPI, Apt and Yum sources. A virtual repository exposes several repositories behind one address and resolves a request from the first upstream (by priority) that has it, which also protects against dependency-confusion attacks when the internal repository has the highest priority.
In the Google Cloud console
-
In Artifact Registry, select Create repository and choose Remote as the mode.
-
Pick the format (for example Docker), the Remote repository source (for example Docker Hub), and optionally an upstream username and a Secret Manager secret version holding the access token, to avoid anonymous pull limits.
-
Create a second repository with mode Virtual, then add upstream repositories and set a priority for each (a lower number means higher priority).
With the gcloud CLI
# Pull-through cache of Docker Hub (token kept in Secret Manager)
gcloud artifacts repositories create dockerhub-cache \
--repository-format=docker --location="$REGION" \
--mode=remote-repository \
--remote-repo-config-desc="Docker Hub cache" \
--remote-docker-repo=DOCKER-HUB \
--remote-username="my-dockerhub-user" \
--remote-password-secret-version="projects/$PROJECT_ID/secrets/dockerhub-token/versions/latest"
# Virtual repository that prefers internal images over the cache
cat > upstream-policy.json <<'EOF'
[
{"id": "internal", "repository": "projects/my-project-id/locations/us-central1/repositories/bookshelf", "priority": 10},
{"id": "dockerhub", "repository": "projects/my-project-id/locations/us-central1/repositories/dockerhub-cache", "priority": 20}
]
EOF
gcloud artifacts repositories create bookshelf-all \
--repository-format=docker --location="$REGION" \
--mode=virtual-repository \
--upstream-policy-file=upstream-policy.json
Derived from Remote repositories and Virtual repositories.
The format, mode, upstream source, location and encryption of a repository cannot be changed after creation, so decide
them up front. The Artifact Registry service agent needs roles/secretmanager.secretAccessor on the token secret.
Cleanup policies
Without a policy every pushed image is kept and billed for storage forever. A cleanup policy is a JSON rule set on a
standard repository: delete rules remove versions matching a condition (tag state, tag or version prefixes, package
name prefixes, olderThan, newerThan), and keep rules protect versions from deletion; keep rules win over delete
rules. A most recent versions keep rule retains the latest N versions of each package. Policies run on a schedule
(changes take effect within about a day), so use a dry run first.
In the Google Cloud console
-
Open the repository in Artifact Registry and select Edit repository (or set policies while creating it).
-
Under Cleanup policies choose Dry run, then Add a policy.
-
Add a Delete policy for untagged images older than 7 days and a Keep policy for the 10 most recent versions.
-
Review in Cloud Logging which versions the dry run reports as deleted (the repository’s audit log entries, as described in the documentation), then switch the repository from Dry run to Delete artifacts.
With the gcloud CLI
cat > cleanup.json <<'EOF'
[
{
"name": "delete-untagged",
"action": {"type": "Delete"},
"condition": {"tagState": "untagged", "olderThan": "7d"}
},
{
"name": "keep-release-tags",
"action": {"type": "Keep"},
"condition": {"tagState": "tagged", "tagPrefixes": ["v", "release"]}
},
{
"name": "keep-recent",
"action": {"type": "Keep"},
"mostRecentVersions": {"keepCount": 10}
}
]
EOF
gcloud artifacts repositories set-cleanup-policies bookshelf \
--location="$REGION" --policy=cleanup.json --dry-run
# After reviewing what would be deleted
gcloud artifacts repositories set-cleanup-policies bookshelf \
--location="$REGION" --policy=cleanup.json --no-dry-run
gcloud artifacts repositories list-cleanup-policies bookshelf --location="$REGION"
Derived from Configure cleanup policies.
Cleanup policies apply to standard repositories only, not to remote or virtual ones. Deleted versions are not recoverable, so keep release tags explicitly and prefer an immutable-tag repository for them.
Access control
Artifact Registry uses IAM roles that can be granted on the project, or (preferably) on a single repository.
| Role | Allows |
|---|---|
|
Download images and packages, list repository contents. What Cloud Run, GKE nodes and Compute Engine VMs need. |
|
Reader plus upload. What a CI service account needs. |
|
Writer plus delete artifacts and manage tags and IAM policy of the repository. |
|
Create and delete repositories and change their settings. |
Derived from Configure access control for Artifact Registry.
# CI pushes: writer on one repository only
gcloud artifacts repositories add-iam-policy-binding bookshelf \
--location="$REGION" \
--member="serviceAccount:ci-builder@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/artifactregistry.writer"
# The Cloud Run runtime pulls images: reader
gcloud artifacts repositories add-iam-policy-binding bookshelf \
--location="$REGION" \
--member="serviceAccount:catalog-api@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/artifactregistry.reader"
Derived from Configure access control for Artifact Registry.
In practice Cloud Run pulls images with the Cloud Run service agent, and GKE nodes use the node service account, so those principals (not the application’s runtime account) need the reader role when the repository lives in another project. Private Google Access or Private Service Connect keeps pulls off the public internet; see VPC Networking on Google Cloud.
Vulnerability scanning with Artifact Analysis
Artifact Analysis (formerly Container Analysis) scans images pushed to Artifact Registry when automatic scanning is enabled through the Container Scanning API. It records OS and language-package vulnerabilities on push and keeps the findings up to date as new vulnerabilities are published. Findings appear in the console under each image version and can feed Security Command Center. Scanning is billed per scanned image; see the pricing page below.
gcloud services enable containerscanning.googleapis.com
gcloud artifacts docker images describe \
"$REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api:1.0.0" \
--show-package-vulnerability
Derived from Automatically scan for vulnerabilities.
Image hardening choices (base images, non-root users, minimal layers) are covered in Image Best Practices and Supply-Chain Security. Binary Authorization can additionally require that images deployed to Cloud Run or GKE carry an attestation; see Governance, Security and Compliance.
Cloud Build
Cloud Build is a managed, serverless build service. A build is a list of steps, each running a container image
(a builder) against a shared /workspace directory, executed on Google-managed workers or on a private pool inside
your VPC. Builds are billed by build minutes on the chosen machine type, with a monthly free allowance for the default
machine type.
Submitting a build
The simplest build takes a source directory and a Dockerfile:
gcloud builds submit \
--tag "$REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api:1.0.0" .
Derived from Build and push a Docker image with Cloud Build.
The CLI uploads the source (honouring .gcloudignore, falling back to .gitignore) to a Cloud Storage bucket, runs the
build in the cloud and streams the log. For anything beyond one image use a build configuration file:
# cloudbuild.yaml
steps:
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', '${_IMAGE}:$SHORT_SHA', '-t', '${_IMAGE}:latest', '.']
- name: gcr.io/cloud-builders/docker
args: ['push', '--all-tags', '${_IMAGE}']
substitutions:
_IMAGE: us-central1-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api
options:
logging: CLOUD_LOGGING_ONLY
images: []
Derived from Create a build configuration file and Substitute variable values.
Built-in substitutions such as $PROJECT_ID, $SHORT_SHA, $BRANCH_NAME and $TAG_NAME are filled by Cloud Build;
user-defined ones must start with an underscore. The gcr.io/cloud-builders/* builder images are Google-maintained
and are still served from gcr.io repositories hosted in Artifact Registry, which is the one remaining legitimate use of
the old host name in a new pipeline. Run it with:
gcloud builds submit --config cloudbuild.yaml .
gcloud builds list --limit=5 --format="table(id,status,createTime,duration)"
gcloud builds log "$(gcloud builds list --limit=1 --format='value(id)')"
Derived from gcloud builds submit.
In the Google Cloud console
-
Open Cloud Build (enable the API if prompted) and check the region selector at the top: builds, triggers and connections are regional resources, with a
globaloption for legacy builds. -
History lists builds with their status and logs; select a build to see each step.
-
Settings shows the service account builds run as and the default logging option.
-
Worker pools (private pools) are created here when builds must reach a private network.
The build service account
Builds run as a service account. Historically this was the legacy Cloud Build service account
(PROJECT_NUMBER@cloudbuild.gserviceaccount.com) with broad permissions, and organizations created after mid-2024
default to the Compute Engine default service account instead, depending on organization policy. Both are broader
than a build needs. The current recommendation is a user-specified service account with only the roles required
(Artifact Registry writer, Logs Writer, and access to the source and any secrets), selected per trigger or per build:
gcloud iam service-accounts create ci-builder --display-name="Bookshelf CI builder"
for ROLE in roles/artifactregistry.writer roles/logging.logWriter; do
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="serviceAccount:ci-builder@$PROJECT_ID.iam.gserviceaccount.com" \
--role="$ROLE"
done
gcloud builds submit --config cloudbuild.yaml \
--service-account="projects/$PROJECT_ID/serviceAccounts/ci-builder@$PROJECT_ID.iam.gserviceaccount.com" .
Derived from Configure user-specified service accounts.
A user-specified account must write its own logs (CLOUD_LOGGING_ONLY or a bucket you own), which is why the
cloudbuild.yaml above sets options.logging. Never mint a JSON key for the builder; see
Identity and Access for why keys are blocked by default in new organizations.
Source repositories and triggers
A trigger starts a build when code changes in a connected repository. Triggers need the repository to be reachable by Cloud Build.
Cloud Source Repositories, Google’s original hosted Git, has been closed to new customers since 2024-06-17. Older Cloud Build guides still start with it or with the "1st generation" GitHub App connection, which is now legacy. The current approach is a 2nd-generation repository connection to GitHub, GitHub Enterprise, GitLab or Bitbucket. For Git hosted on Google Cloud, Secure Source Manager is the managed alternative: a regional, single-tenant Git service with pull requests, issues, branch protection, VPC Service Controls support, customer-managed encryption keys and Cloud Build triggers. Developer Connect is the newer integration layer that links external repositories to several Google Cloud services, including Cloud Build and Cloud Run source deployments.
In the Google Cloud console
-
In Cloud Build, open Repositories and select the 2nd gen tab, then Create host connection.
-
Choose the provider (for example GitHub), a region and a connection name such as
bookshelf-github, then authorize in the browser and install the Cloud Build GitHub App on the account or organization (this needs admin rights on the repository). -
Select Link repository, pick the connection and the
bookshelfrepository. -
Open Triggers, select Create trigger, give it a name and region, choose the event (push to a branch, push of a tag, pull request or manual), pick the repository from the 2nd-gen connection, enter the branch regex
^main$, choose Cloud Build configuration filecloudbuild.yaml, and select theci-builderservice account. -
Select Create; push a commit to
mainand watch History.
With the gcloud CLI
gcloud builds connections create github bookshelf-github --region="$REGION"
# Open the printed URL to authorize, then check the state
gcloud builds connections describe bookshelf-github --region="$REGION" \
--format="value(installationState.stage)"
gcloud builds repositories create catalog-api \
--remote-uri="https://github.com/my-org/catalog-api.git" \
--connection=bookshelf-github --region="$REGION"
gcloud builds triggers create github \
--name=catalog-api-main \
--region="$REGION" \
--repository="projects/$PROJECT_ID/locations/$REGION/connections/bookshelf-github/repositories/catalog-api" \
--branch-pattern='^main$' \
--build-config=cloudbuild.yaml \
--service-account="projects/$PROJECT_ID/serviceAccounts/ci-builder@$PROJECT_ID.iam.gserviceaccount.com"
Derived from Connect to a GitHub repository, Cloud Build repositories and Create and manage build triggers.
A connection cannot be global: it must be in a region, and a trigger in that region can use it. Use a pull-request trigger with the Comment control option when forks may submit code, so untrusted contributors cannot run builds with your service account.
Building without a Dockerfile
Jib for Spring Boot
Jib builds an optimized, layered image for a Java project straight from Maven or Gradle, with no Docker daemon and no Dockerfile. It pushes to Artifact Registry using the same credential helper as above. The Spring Boot image alternatives (layered jars, Dockerfile, buildpacks) are compared in Java and Spring Boot Images.
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.5</version>
<configuration>
<from><image>eclipse-temurin:21-jre</image></from>
<to><image>us-central1-docker.pkg.dev/my-project-id/bookshelf/catalog-api</image></to>
</configuration>
</plugin>
./mvnw compile jib:build # push directly to Artifact Registry
./mvnw compile jib:dockerBuild # or build into the local Docker daemon
Derived from Jib Maven plugin and Build and test Java applications.
Check the plugin’s page for the newest release; the version above is only an example. Jib authenticates using
Docker credential helpers, so gcloud auth configure-docker locally and the WIF-provided credentials in CI work
without configuration. In Cloud Build, run the same command in a Maven builder step.
Buildpacks
Google Cloud buildpacks detect the language, build with the right toolchain and produce a container image with no Dockerfile. Cloud Run source deploys use them under the hood (see Cloud Run), and you can call them directly from Cloud Build:
gcloud builds submit \
--pack image="$REGION-docker.pkg.dev/$PROJECT_ID/bookshelf/catalog-api:1.0.0" .
# Or build and deploy in one command
gcloud run deploy catalog-api --source . --region "$REGION"
Derived from Build an application with buildpacks and Deploy services from source code.
Buildpacks suit teams that want security patching of the base image handled by the platform. A Dockerfile remains the better choice when you need exact control of the runtime image.
Pushing from GitHub Actions without keys
GitHub Actions can build and push to Artifact Registry using Workload Identity Federation, so the repository holds no
secret. The pool, provider and service account bindings are created as described in
Identity and Access; the service account needs roles/artifactregistry.writer on the
bookshelf repository and the workflow needs id-token: write.
name: build-and-push
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
env:
IMAGE: us-central1-docker.pkg.dev/my-project-id/bookshelf/catalog-api
jobs:
image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- id: auth
uses: google-github-actions/auth@v3
with:
workload_identity_provider: projects/<project-number>/locations/global/workloadIdentityPools/github/providers/bookshelf-repo
service_account: ci-builder@my-project-id.iam.gserviceaccount.com
- uses: google-github-actions/setup-gcloud@v3
- run: gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
- run: |
docker build -t "$IMAGE:${{ github.sha }}" .
docker push "$IMAGE:${{ github.sha }}"
Derived from google-github-actions/auth and Configure authentication to Artifact Registry for Docker.
Tag by commit SHA and deploy by digest. The wider workflow design (caching, matrix builds, environments, scanning) is in Docker CI/CD with GitHub Actions, and layer caching in Build Cache and Multi-Stage Builds. Choose Cloud Build when builds must run inside a private network or reuse Google-managed triggers, and GitHub Actions when the team already lives there; both publish to the same repository.
Pricing model, limits and launch stages
- Pricing
-
Artifact Registry charges for stored data (per GB-month), for data transferred out of a region or to the internet (traffic within the same region is free), and for remote and virtual repository pass-through traffic. There is a small free storage allowance per month. Cloud Build charges per build minute by machine type, has a free allowance for the default machine type, and private pools are billed separately. Artifact Analysis scanning is billed per scanned image. Always check the dated pricing pages linked below, because rates change.
- Cost drivers and controls
-
Untagged and old image versions (use cleanup policies), cross-region pulls (keep the repository in the same region as Cloud Run or GKE), large images (multi-stage builds and slim bases), long builds (cache layers with
--cache-fromor Kaniko-style caching). - Limits
-
A build has a default timeout of 60 minutes, configurable up to 24 hours. Quotas apply to concurrent builds per region and to repositories, requests and bandwidth per project; they are listed on the quota pages below.
- Launch stages and dated changes
-
Container Registry shut down on 2025-03-18 after deprecation on 2023-05-15. Cloud Source Repositories closed to new customers on 2024-06-17. Cloud Build 1st-generation repository integrations are legacy; use 2nd-generation connections. Check the release notes for features marked Preview, because remote and virtual repositories for some formats and some Developer Connect integrations have been introduced at different stages.
Troubleshooting
denied: Permission "artifactregistry.repositories.uploadArtifacts" denied-
The identity pushing lacks the writer role on that repository, or the Docker client is not authenticated for that host. Run
gcloud auth configure-docker REGION-docker.pkg.devand check the role binding. name unknown: Repository "…" not found-
The repository does not exist in that location, or the image path has the wrong project, region or repository. Pushing creates images, never repositories, except for
gcr.iorepositories created automatically on first push in some projects. manifest unknownon Cloud Run or GKE-
The tag or digest was removed (a cleanup policy or immutable-tag conflict) or the runtime service agent cannot read the repository. Deploy by digest and keep release tags protected.
- Build fails with a logging error
-
A user-specified service account is used with no logging option. Set
options.loggingtoCLOUD_LOGGING_ONLYor provide alogsBucket. - Trigger never fires
-
The connection
installationStateis not complete, the GitHub App lacks access to the repository, or the branch regex does not match. Check the trigger’s region matches the connection’s region. - Old pipeline fails pushing to
gcr.io/PROJECT_ID/… -
It relies on the retired Container Registry. Create the Docker repository, update the image paths, and use the transition steps above.
Clean up
Delete in dependency order. The following removes the Bookshelf resources created above; a throwaway project can be deleted instead, which removes everything after a 30-day recovery window.
gcloud builds triggers delete catalog-api-main --region="$REGION"
gcloud builds repositories delete catalog-api --connection=bookshelf-github --region="$REGION"
gcloud builds connections delete bookshelf-github --region="$REGION"
gcloud artifacts repositories delete bookshelf-all --location="$REGION"
gcloud artifacts repositories delete dockerhub-cache --location="$REGION"
gcloud artifacts repositories delete bookshelf --location="$REGION"
gcloud artifacts repositories delete bookshelf-maven --location="$REGION"
gcloud artifacts repositories delete bookshelf-npm --location="$REGION"
gcloud artifacts repositories delete bookshelf-python --location="$REGION"
# gcr.io repository, if created for the transition
gcloud artifacts repositories delete gcr.io --location=us
gcloud iam service-accounts delete "ci-builder@$PROJECT_ID.iam.gserviceaccount.com"
Derived from Manage repositories. Delete the virtual
repository before the repositories it references. Also remove the Cloud Build source bucket
(gs://PROJECT_ID_cloudbuild), the Workload Identity pool provider from the GitHub Actions setup, and the Cloud Build
GitHub App installation in GitHub, which cannot be removed from Google Cloud. See
Shutting down projects.