Container Deployment Pipeline: From Local Build to GCP
Shipping containerized workloads to Google Cloud Platform (GCP) needs more than running docker push
. A robust deployment covers authentication, registry management, and orchestration—plus error handling for common failure scenarios.
Prerequisites
- Docker: 24.0+ (
docker --version
) - GCP
gcloud
CLI: 457.0.0+ - Access to an existing GCP project with billing enabled
Note: Service account permissions must include roles/storage.admin
for pushing images, otherwise you'll be blocked at the registry.
1. Authenticate to GCP from Terminal
Multiple auth routes exist, but most engineers stick with service account keys for CI/CD. Locally, use:
gcloud auth login
gcloud config set project my-gcp-project
Tokens expire, so for production, prefer workload identity or short-lived credentials via CI.
2. Build and Tag the Container
Consistency counts: always tag with version and commit SHA to avoid "latest" ambiguity.
docker build -t gcr.io/my-gcp-project/my-app:1.4.2-$(git rev-parse --short HEAD) .
Gotcha: Docker Hub rate limits don't apply to GCR, but pay attention to repository location (us.gcr.io
, eu.gcr.io
, etc.) to minimize latency.
3. Push Image to Google Container Registry (GCR)
Enable GCR API (gcloud services enable containerregistry.googleapis.com
) before first push.
docker push gcr.io/my-gcp-project/my-app:1.4.2-abc1234
Known issue: Old images accumulate quickly; set up lifecycle policies periodically.
4. Deploy via Google Kubernetes Engine (GKE)
Manifests become mandatory here. Example deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: gcr.io/my-gcp-project/my-app:1.4.2-abc1234
ports:
- containerPort: 8080
Apply it:
kubectl apply -f deployment.yaml
Check deployment status:
kubectl rollout status deployment/my-app
If you see:
Failed to pull image "gcr.io/my-gcp-project/my-app:1.4.2-abc1234": rpc error: code = Unknown desc = Error response from daemon: manifest unknown
Double-check tag and image push.
Conclusion Buried Early
At this stage, the container is production-grade: image tagged, pushed to secure registry, and deployed on autoscaling infrastructure. For higher uptime, enable GKE health checks and tune pod disruption budgets.
One Non-Obvious Tip
GKE's imagePullPolicy: Always can introduce cold starts if the cluster loses connectivity. For critical, high-availability workloads, pin the image tag and switch to IfNotPresent
.
Deployment Workflow Visualized
+------------------+ docker build +---------------+ docker push +----------+
| Developer (local)|----------------------->| Docker Image |------------------->| GCR |
+------------------+ +---------------+ +----------+
|
| kubectl apply
v
+----------+
| GKE |
+----------+
Alternatives exist: Artifact Registry supersedes GCR for new projects, with better IAM integration. This guide, however, balances compatibility and maturity.
Table: Key Commands and Tools
Task | Command/Tool |
---|---|
Authenticate GCP | gcloud auth login |
Build Docker Image | docker build -t ... |
Push to GCR | docker push ... |
Deploy to GKE | kubectl apply -f deployment.yaml |
Some steps will vary in a real CI/CD pipeline; manual secrets handling is a frequent weak spot. Secure with Secret Manager where possible.