iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🙆

Running Next.js on GAE: Automated Deployment via Cloud Build

に公開
2022/05/17

I will summarize how to deploy a Next.js app to the Google App Engine (GAE) standard environment. I will also introduce how to automate deployment from Google Cloud Build to enable CI/CD from GitHub and other sources.

I will start the explanation assuming that the Next.js app has already been created.

1. app.yaml Settings

First, create an app.yaml file in the root of your project. Most of the deployment settings for GAE are done here. For this example, we will set it as follows:

app.yaml
env: standard # Standard environment (optional)

runtime: nodejs14 # Use Node.js 14 (Update: nodejs16 is now also available)

instance_class: F4

service: default # The name of the GAE service. "frontend" might also be good

handlers:
  - url: /_next/static
    static_dir: .next/static
  - url: /(.*\.(gif|png|jpg|ico|txt|svg))$
    static_files: public/\1
    upload: public/.*\.(gif|png|jpg|ico|txt|svg)$
  - url: /.*
    script: auto
    secure: always

default_expiration: "12h" # Cache duration for static files

env_variables:
  NODE_ENV: "production"

automatic_scaling:
  min_instances: 0 # Set instances to 0 when not running

Here is a brief explanation:

  • With instance_class: F4, the limit will be 1024 MB Memory / 2.4 GHz CPU. For other setting values, please see Instance classes.
  • In handlers, you set the processing for each URL pattern.
    • Files matching static_dir or static_files will be uploaded as static files (details).
    • In Next.js default settings, static files are output into the .next/static directory during build (reference).
    • In Next.js, you can place static files in the public directory. Since the actual URL to the file doesn't include /public and is referenced from the root, the specification becomes a bit tricky. Here, I specified it by referring to the Nuxt.js documentation.
  • The cache duration for static files can be specified with default_expiration. I set it to 12h (12 hours) this time.
  • In automatic_scaling, you can specify the minimum and maximum number of instances. I recommend making more detailed settings by referring to the documentation.

2. package.json Settings

package.json
{
   "scripts": {
     "dev": "next dev",
+    "build": "next build",
+    "start": "next start -p $PORT",  
   },
}

To run Next.js on GAE, you need to execute next start after building. In GAE, if the start script is written in package.json, it will be executed when the app starts.

By default, the runtime starts your application by running node server.js. If you specify a start script in your package.json file, the runtime runs the specified start script instead.
Starting your application

3. Setting up .gcloudignore

In .gcloudignore, you specify the files that should not be uploaded to GAE when deploying the service. The following article is helpful for detailed writing instructions.

https://zenn.dev/satohjohn/articles/11df180df878ac

For example, specify as follows:

.gcloudignore
.gcloudignore
.gitignore

node_modules/

In addition to this, source files that are no longer needed after the build, such as /components or /pages, can also be added to .gcloudignore. If these files are consolidated in the /src directory, simply adding /src is sufficient.

4. Try Deploying from Local

Once the settings up to this point are complete, you can build and deploy. To deploy from a local environment, the gcloud CLI setup must be finished.

$ npm run build
$ gcloud app deploy app.yaml --project your-gcp-project-name

You might want to add a script for deployment to package.json as follows.

package.json
{
   "scripts": {
+    "deploy:gae": "npm run build && gcloud app deploy app.yaml --project=your-project-name",  
   },
}

With this, you will be able to deploy from your local machine using npm run deploy:gae.

5. Deployment from Cloud Build

To deploy to GAE from Cloud Build, you need to configure IAM settings for the service account. This part is explained clearly in the documentation.

https://cloud.google.com/source-repositories/docs/quickstart-triggering-builds-with-source-repositories?hl=en

cloudbuild.yaml

In the steps, execute npm install and npm run build, and then run the GAE deployment command.

cloudbuild.yaml
steps:
  - name: node
    entrypoint: npm
    args: ["install"]
  - name: node
    entrypoint: npm
    args: ["run", "build"]
  - name: gcr.io/cloud-builders/gcloud
    args: ["app", "deploy", "app.yaml", "--project=foo", "--quiet"]

The --quiet flag is specified to skip confirmations like "Do you want to deploy?" that appear during deployment.

Using yarn in Cloud Build Steps

If you want to use yarn for package installation or building, set the entrypoint to yarn.

cloudbuild.yaml
steps:
  - name: node
    entrypoint: yarn
    args: ["install"]
  - name: node
    entrypoint: yarn
    args: ["build"]
  - name: gcr.io/cloud-builders/gcloud
    args: ["app", "deploy", "app.yaml", "--project=foo", "--quiet"]

Specifying a Node Version

If you want to specify a Node.js version, set the name value to node:version.

cloudbuild.yaml
  - id: install-packages
    name: node:14
    entrypoint: yarn
    args: ["install"]

If all the above settings are in place, you should be able to deploy to GAE from Cloud Build.

Discussion