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
:
Frontend – Dockerfile (Serving with Nginx)
For a React frontend, we need to serve the dist
directory using Nginx.
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