Deploying Next.js to GAE with Cloud Build
TL;DR
A record of getting Next.js running on Google App Engine (GAE). I tried Cloudflare first but AMP pages threw errors, so I put that on hold.
The requirements were:
- Deploy on push/PR via GitHub integration
- Deploy via webhook using curl or similar
So the goal was to create a trigger in Cloud Build and deploy to GAE.
Deploying to GAE
To get things running first, let's write the configuration files and deploy. Since I'm just hosting a personal blog, I want to stay within the free tier as much as possible. I also set up budget alerts just in case (How to Achieve Safe Cloud Operations with Google Cloud (GCP) Budget Alerts).
I referenced the following sites for configuration:
- How to Run Google App Engine for Free (2018 Edition)
- Google App Engine Auto Scaling Settings to Stay Within the Free Tier
- Running Next.js on GAE (Auto Deploy from Cloud Build)
app.yaml
Deploy via gcloud first to test. A .gcloudignore for Node will be auto-generated. You'll want to add unnecessary files like coverage to it.
At this point, I needed to set up permissions. I ultimately enabled the following permissions:
- AppEngine (required for deploying to GAE)
- SecretManager (required for creating webhook secrets)
- Service Accounts (required for deploying via Cloud Build)
Cloud Build Configuration
Configuration File
cloudbuild.yaml
Cloud Build has a feature that automatically substitutes variables. This time I used $PROJECT_ID to automatically substitute the deployment target.
For details, see Substituting variable values.
I also specified the Node version using the node:${version} format, just to be safe.
Connecting Cloud Build with GitHub
Connect the Google Cloud Build GitHub App.
After that, regardless of the project's region, create a trigger in the "global" region and connect it to the relevant GitHub repository.
I thought it would work in the same region, but I got the error FAILED_PRECONDITION: generic::failed_precondition: no concurrent builds quota available to create builds. (reference).
Then push or manually trigger the build to check if it works. Also, it will error here without Service Accounts permissions.
Creating a Webhook Trigger
Just select webhook. You'll need to create a secret key, so SecretManager permissions are required. You'll get an error if you don't specify the body with -d.