gogoogle-cloud-platformapp.yamlgflags

Unable to specify gflag in GCP


I have a Go server program which needs to be passed a particular gflag value at runtime, but I am unable to specify that in GCP's app.yaml file. I am pretty new to GCP, so this might be an uninitiated query.

Here's my Go code structure:

project_root
   |
   |___cmd
        |___ main
                |___ main.go
                |___ foo_handlers.go (defines FooHandler(w, r))
                |___ bar_handlers.go (defines BarHandler(w, r))

main.go is your typical Golang HTTP server program roughly having this structure:

func main() {
    // Flags
    flag.StringVar(
        &SomeFlagVar, 
        "some_flag", // flag name
        "dev_value", // default value
        "Some Flag")
    flag.Parse()

    // Foo
    http.HandleFunc("/foo", FooHandler)

    // Bar
    http.HandleFunc("/bar/", BarHandler)

    // Server starting boiler plate code
    http.ListenAndServe(..)

My GCP app.yaml file roughly looks like this:

runtime: go114

main: ./cmd/main

handlers:
- url: /.*
  script: auto

This works fine but as you would note, I am unable to pass any custom value to the some_flag flag. For now, I just hardcode the default flag value to the value preferred for deployment in GCP and I don't check that change in, which is obviously a very crude way of achieving the goal.

I have tried setting the entrypoint configuration to thus: entrypoint: ./cmd/main/main --some_flag=gcp or entrypoint: .bin/main --some_flag=gcp

But for both these cases, GCP errors out with errors of the form /bin/sh: 1: exec: bin/main: not found.

I could achieve the same very easily in Heroku by specifying a web dyno like so: bin/main --some_flag=heroku

How do I set the same in a GCP app? I am using GCP Standard Environment. And I do not want to use environment variables for the same.

Thanks!


Solution

  • You can't pass flags to your main function with App Engine. You have 3 solutions:

    1. Stay with App Engine standard and use environment variable instead of flags
    2. Use App Engine Flexible, with a custom runtime. Like that, you have to provide a Dockerfile and therefore you can specify the entrypoint that you wish. But, App Engine flexible doesn't scale to 0 and thus is quite expensive for a small and low traffic app
    3. As App Engine Flexible, define a Dockerfile but this time deploy it on Cloud Run.

    Personally, I recommend to use Environment variables, because, if you want to change the values, you don't have to rebuild your container, only to change the value and deploy a new revision (same container, but different context)