Strapi Automatic Scaling on Google App Engine

System Information
  • Strapi Version: 4.1.8
  • Operating System: OS X
  • Database: PostgreSQL
  • Node Version: 16.13.0
  • NPM Version: 8.1.0
  • Yarn Version: 1.22.17

Hi, everyone! I’m new to Strapi and Google App Engine. According to the app engine documentation, automatic scaling using min_idle_instances or min_instances elements is required to have a warmup request handler on the applications.

https://cloud.google.com/appengine/docs/standard/nodejs/configuring-warmup-requests

How to make a custom handler and route path to /_ah/warmup?
I’ve tried to make a custom plugin for this but turns out the custom plugin name must be in kebab case. Any other ideas? Thanks :smiley:

1 Like

It’s solved for now, but I don’t think this is the best approach. What I’ve done is create a custom middleware to check the ctx.path

 async (ctx, next) => {
    if (ctx.path !== '/_ah/warmup') return await next()

    // Handle warmup logic here

    ctx.status = 200;
    ctx.body = 'OK';
};

@abimnyud Did you find an alternate option for this? And if not is this solution still working for you?

I have tried your solution but it isn’t working for me. I end up in a redirect loop where App Engine just issues a series of 302 redirects back to the same page over and over until the browser steps in and errors with “The page isn’t redirecting properly”.

I am running Strapi as a microservice in my multi-service GCP project, it isn’t the default service so the routing is via the -dot- notation e.g. https://cms-dot-.appspot.com/_ah/warmup. Is this similar to what you are doing or are you running on the default service?

In my search I also came across this but can’t make that work either.

Any tips/pointers?

For anyone else reading this in future. The code the OP posted above does work just don’t expect to be able to access /_ah/warmup from your browser to check to see if it works.

Instead, depend on the GCP Logs. You can use protoPayload.wasLoadingRequest="true" as a log filter to see your cold start requests, as long as /_ah/warmup is returning 200 responses on there it kind of doesn’t matter if you can reach it from your browser or not.

I think the issue in the browser may be related to the HSTS header that Strapi sets for you by default. Either that or the secure: optional directive that is the default for app.yaml.

I had some success with altering my app.yaml to secure: never in order to see the warmup request in the browser but I don’t want to suggest that for anything other than dev work, certainly not production.

Changing it to secure:always and deploying again means I can’t see /_ah/warmup in my browser (I get that aforementioned redirect issue) but I do see it being successful in the GCP logs.

Just for completeness here is my typescript version of the OP’s handler.

import type { Strapi } from "@strapi/strapi";
import type { Context, Next } from "koa";

export default (
    config: Record<string, unknown>,
    { strapi }: { strapi: Strapi }
) => {
    return async (ctx: Context, next: Next) => {
        if (ctx.path === "/_ah/warmup") {
            ctx.send({ success: true }, 200);
        }
        await next();
    };
};

Thanks jgale for the solution. I added a file under /src/middlewares and then update /config/middleware.js but when google sends warm up requests they end up in redirect & look, what is the solution here do you know?

Please see my earlier posts above (#3 and #4).

I end up in a redirect loop where App Engine just issues a series of 302 redirects back to the same page over and over until the browser steps in and errors with “The page isn’t redirecting properly”.

just don’t expect to be able to access /_ah/warmup from your browser to check to see if it works.

Instead, depend on the GCP Logs. You can use protoPayload.wasLoadingRequest="true" as a log filter to see your cold start requests, as long as /_ah/warmup is returning 200 responses on there it kind of doesn’t matter if you can reach it from your browser or not.

You may also have to update config/env/production/middlewares.ts if you have different files for production.