Back to Blog

Setting Up CI/CD for Next.js on GCP with Cloud Build

4 min read
gcpdevopsci-cdnextjsfirebase

Setting Up CI/CD for Next.js on GCP with Cloud Build

In this tutorial, I'll show you how to set up a complete CI/CD pipeline for a Next.js application using Google Cloud Build and Firebase Hosting.

Why GCP?

Google Cloud Platform offers several advantages for hosting modern web applications:

  • Free tier for personal projects
  • Global CDN through Firebase Hosting
  • Automatic SSL certificates
  • Fast build times with Cloud Build
  • Integrated ecosystem for future backend services

Prerequisites

Before we begin, make sure you have:

  1. A Google Cloud Platform account
  2. A GitHub repository with your Next.js app
  3. GCP CLI (gcloud) installed locally

Step 1: Set Up Firebase Project

First, let's initialize Firebase in your project:

# Install Firebase CLI
npm install -g firebase-tools

# Login to Firebase
firebase login

# Initialize Firebase in your project
firebase init hosting

Select these options:

  • Use existing project or create a new one
  • Set public directory to out (for Next.js static export)
  • Configure as single-page app: Yes
  • Set up automatic builds with GitHub: No (we'll use Cloud Build)

Step 2: Configure Next.js for Static Export

Update your next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    unoptimized: true, // Required for static export
  },
};

module.exports = nextConfig;

Step 3: Create Cloud Build Configuration

Create a cloudbuild.yaml file in your project root:

steps:
  # Install dependencies
  - name: 'node:18'
    entrypoint: npm
    args: ['install']
  
  # Build the application
  - name: 'node:18'
    entrypoint: npm
    args: ['run', 'build']
  
  # Deploy to Firebase Hosting
  - name: 'gcr.io/PROJECT_ID/firebase'
    args: ['deploy', '--only', 'hosting', '--project', 'PROJECT_ID']

timeout: '1200s'

Replace PROJECT_ID with your actual GCP project ID in the cloudbuild.yaml file.

Step 4: Set Up GitHub Trigger

Now let's connect Cloud Build to your GitHub repository:

# Enable required APIs
gcloud services enable cloudbuild.googleapis.com
gcloud services enable firebase.googleapis.com

# Create a build trigger
gcloud builds triggers create github \
  --repo-name=YOUR_REPO_NAME \
  --repo-owner=YOUR_GITHUB_USERNAME \
  --branch-pattern="^main$" \
  --build-config=cloudbuild.yaml

Step 5: Grant Permissions

Cloud Build needs permission to deploy to Firebase:

# Get the Cloud Build service account
PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format='value(projectNumber)')
SERVICE_ACCOUNT="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com"

# Grant Firebase Admin role
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/firebase.admin"

Step 6: Test Your Pipeline

Now push a commit to your main branch:

git add .
git commit -m "Set up CI/CD pipeline"
git push origin main

Watch the build progress in the Cloud Build console:

gcloud builds list --limit=5

Monitoring and Optimization

Build Time Optimization

You can speed up builds by caching dependencies:

steps:
  # Cache node_modules
  - name: 'node:18'
    entrypoint: 'bash'
    args:
      - '-c'
      - |
        npm ci --cache .npm --prefer-offline
        
options:
  machineType: 'E2_HIGHCPU_8'  # Use faster machines

Cost Optimization

Cloud Build offers 120 free build-minutes per day. For a personal blog with occasional updates, you'll likely stay within the free tier!

Monitor your usage:

gcloud builds list --format="table(
  id,
  createTime.date('%Y-%m-%d'),
  status,
  timing.keys()
)"

Bonus: Preview Deployments

Create preview deployments for pull requests:

# cloudbuild-pr.yaml
steps:
  - name: 'node:18'
    entrypoint: npm
    args: ['install']
  
  - name: 'node:18'
    entrypoint: npm
    args: ['run', 'build']
  
  - name: 'gcr.io/PROJECT_ID/firebase'
    args: [
      'hosting:channel:deploy',
      'pr-$SHORT_SHA',
      '--expires',
      '7d',
      '--project',
      'PROJECT_ID'
    ]

Conclusion

You now have a fully automated CI/CD pipeline! Every push to your main branch will:

  1. ✅ Install dependencies
  2. ✅ Build your Next.js app
  3. ✅ Deploy to Firebase Hosting
  4. ✅ Invalidate CDN cache
  5. ✅ Be live in ~2-3 minutes

The best part? It's virtually free for personal projects and scales effortlessly as your traffic grows.

Next Steps:

  • Add automated testing to your pipeline
  • Set up custom domains
  • Configure Cloud CDN for even better performance

Questions? Drop them in the comments or reach out on GitHub!