Powerful Cloud Run Deployment: Dockerizing a Full-Stack Application for Seamless Scaling in 2025

Introduction

Cloud Run makes it possible to scale and deploy containerized apps with ease without having to worry about infrastructure management. Effective full-stack application deployment necessitates a methodical approach to cloud deployment, containerization, and security best practices. The entire process of Dockerizing an Express backend and a React frontend, configuring GitHub Actions for continuous integration and delivery, and safely launching the application on Google Cloud Run will all be covered in this tutorial.

1. Setting Up Google Cloud Services

Create Artifact Registry

Before pushing images, create an Artifact Registry repository:

gcloud artifacts repositories create my-repo \
--repository-format=docker \
--location=asia-south2 \
--description="Docker repository"

Create a Service Account and Assign IAM Roles

Create a Service Account to manage Cloud Run deployments:

gcloud iam service-accounts create my-service-account –display-name “Cloud Run Deployer”

Assign the following IAM roles:

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:my-service-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/artifactregistry.writer

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:my-service-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/run.admin

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:my-service-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountUser

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:my-service-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/storage.admin

Additionally, provide Cloud Run Admin access to the default Compute Engine service account:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--role=roles/run.admin

2. Setting Up Docker for Backend and Frontend

Backend – Dockerfile

Ensure your Express server has a GET endpoint for health checks and use the following Dockerfile:

Cloud Run

Frontend – Dockerfile (Serving with Nginx)

For a React frontend, we need to serve the dist directory using Nginx.

Cloud Run

Ensure you create a nginx.conf file to route requests correctly.

3. Configuring GitHub Secrets

To keep sensitive information secure, store API keys, Cloud project credentials, and environment variables in GitHub Secrets.

Go to GitHub Repository → Settings → Secrets and Variables → Actions and add:

  • GCLOUD_PROJECT_ID (Google Cloud Project ID)
  • GCLOUD_SERVICE_KEY (Base64-encoded JSON Key for service account)
  • ARTIFACT_REPO (Artifact Registry Name)
  • Other environment variables used in .env

4. GitHub Actions – Deploy.yml

To automate deployment, create .github/workflows/deploy.yml:

name: Deploy to Cloud Run

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Authenticate with Google Cloud
run: |
echo "${{ secrets.GCLOUD_SERVICE_KEY }}" | base64 --decode > gcloud-service-key.json
gcloud auth activate-service-account --key-file=gcloud-service-key.json
gcloud config set project ${{ secrets.GCLOUD_PROJECT_ID }}

- name: Build and Push Backend Image
run: |
gcloud auth configure-docker ${{ secrets.ARTIFACT_REPO }} --quiet
docker build -t ${{ secrets.ARTIFACT_REPO }}/backend:latest -f backend/Dockerfile ./backend
docker push ${{ secrets.ARTIFACT_REPO }}/backend:latest

- name: Build and Push Frontend Image
run: |
docker build -t ${{ secrets.ARTIFACT_REPO }}/frontend:latest -f frontend/Dockerfile ./frontend
docker push ${{ secrets.ARTIFACT_REPO }}/frontend:latest

- name: Deploy Backend to Cloud Run
run: |
gcloud run deploy backend-service \
--image=${{ secrets.ARTIFACT_REPO }}/backend:latest \
--platform=managed \
--region=asia-south2 \
--allow-unauthenticated \
--set-env-vars=NODE_ENV=production

- name: Deploy Frontend to Cloud Run
run: |
gcloud run deploy frontend-service \
--image=${{ secrets.ARTIFACT_REPO }}/frontend:latest \
--platform=managed \
--region=asia-south2 \
--allow-unauthenticated \
--set-env-vars=REACT_APP_BACKEND_URL=https://backend-service-xyz.run.app

5. Local Testing Before Deployment

Before pushing to GitHub, test the images locally:

Build and Run Backend Locally

cd backend
docker build -t backend-image .
docker run -p 8080:8080 backend-image

Build and Run Frontend Locally

cd frontend
docker build -t frontend-image .
docker run -p 8081:8080 frontend-image

Now, open http://localhost:8081 to verify the frontend connects with the backend.

6. Cloud Deployment & Verification

Once the GitHub workflow completes, verify the services:

Check Cloud Run Status

gcloud run services list --platform=managed

Fetch Logs to Debug Errors

gcloud logs read backend-service --limit=50
gcloud logs read frontend-service --limit=50

Test API Endpoints

Using Postman or curl:

curl -X POST https://backend-service-xyz.run.app/upload -F "file=@sample.pdf"

If everything works, the services are now fully deployed and running on Cloud Run!

Conclusion

This comprehensive guide meticulously covered the essential steps for containerizing a React frontend and an Express backend using Docker. Furthermore, it detailed the crucial process of securing sensitive secrets within GitHub Actions workflows, ensuring the safety of your credentials. The guide also explained how to automate the entire deployment pipeline seamlessly with GitHub Actions and Google Cloud Run, enabling continuous delivery. Finally, it emphasized the importance of thoroughly testing Docker images locally before initiating deployment to the Google Cloud Platform, thereby minimizing potential issues. By diligently following each of these detailed steps, you can confidently ensure a secure, highly scalable, and remarkably efficient deployment of your complete full-stack application hosted on the robust infrastructure of Google Cloud Platform.

check out more blogs. Click here

Check Out our LinkedIn page – Click Here