Search code examples
gogoogle-cloud-functionsportgo-gin

How to deploy a gen2 cloud function made with gin gonic?


I am trying to deploy a cloud function made with gin/gonic using a zip file on gcp. But it's not being deployed I am facing an error.

My code files are

HelloHTTP.go:

package hello

import (
    "fmt"
    "html"
    "net/http"

    "github.com/gin-gonic/gin"
)

// helloHTTP is a Gin handler function.
func HelloHTTP(c *gin.Context) {
    var d struct {
        Name string `json:"name"`
    }

    if err := c.BindJSON(&d); err != nil {
        c.String(http.StatusOK, "Hello, World!")
        return
    }

    if d.Name == "" {
        c.String(http.StatusOK, "Hello, World!")
        return
    }

    c.String(http.StatusOK, fmt.Sprintf("Hello, %s!", html.EscapeString(d.Name)))
}

go.mod:

module github.com/cap

go 1.21.1

require github.com/gin-gonic/gin v1.9.1

require (
    github.com/bytedance/sonic v1.9.1 // indirect
    github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
    github.com/gabriel-vasile/mimetype v1.4.2 // indirect
    github.com/gin-contrib/sse v0.1.0 // indirect
    github.com/go-playground/locales v0.14.1 // indirect
    github.com/go-playground/universal-translator v0.18.1 // indirect
    github.com/go-playground/validator/v10 v10.14.0 // indirect
    github.com/goccy/go-json v0.10.2 // indirect
    github.com/json-iterator/go v1.1.12 // indirect
    github.com/klauspost/cpuid/v2 v2.2.4 // indirect
    github.com/leodido/go-urn v1.2.4 // indirect
    github.com/mattn/go-isatty v0.0.19 // indirect
    github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
    github.com/modern-go/reflect2 v1.0.2 // indirect
    github.com/pelletier/go-toml/v2 v2.0.8 // indirect
    github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
    github.com/ugorji/go/codec v1.2.11 // indirect
    golang.org/x/arch v0.3.0 // indirect
    golang.org/x/crypto v0.9.0 // indirect
    golang.org/x/net v0.10.0 // indirect
    golang.org/x/sys v0.8.0 // indirect
    golang.org/x/text v0.9.0 // indirect
    google.golang.org/protobuf v1.30.0 // indirect
    gopkg.in/yaml.v3 v3.0.1 // indirect
)

and Iam facing the errors as below.

Could not create or update Cloud Run service hello, Container Healthcheck failed. Revision 'hello-00001-gef' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information. Logs URL: https://console.cloud.google.com/logs/viewer?project=winter-vim-412404&resource=cloud_run_revision/service_name/hello/revision_name/hello-00001-gef&advancedFilter=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22hello%22%0Aresource.labels.revision_name%3D%22hello-00001-gef%22 For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start

Cloud Run service projects/winter-vim-412404/locations/us-central1/services/hello for the function was not found. The function will not work correctly. Please redeploy.

Please help me to resolve this issue.

I was trying to deploy this function but its not getting deplyed.


Solution

  • What you are trying to do is possible but you need to use github.com/GoogleCloudPlatform/functions-framework-go/functions as stated here in Google's documentation

    When you upload your zip file a Google Build is triggered and this package is crucial for establishing the linkage between your endpoint in your code AND the "Entry point" you set in your for this Google Function.

    I created this sample code based on a previous question asked: Initalizing a Go Gin server in Google Cloud Functions

    package hello
    
    import (
        "net/http"
    
        "github.com/gin-gonic/gin"
        "github.com/GoogleCloudPlatform/functions-framework-go/functions"
    )
    
    func init(){
        route := gin.Default()
        route.GET("/hi", HelloHTTP)
        route.GET("/bye", ByeHTTP)
        functions.HTTP("HelloHTTP", route.Handler().ServeHTTP)
    }
    
    
    // helloHTTP is a Gin handler function.
    func HelloHTTP(c *gin.Context) {
        c.String(http.StatusOK, "Hello, World!")
    }
    
    // ByeHTTP is a Gin handler function.
    func ByeHTTP(c *gin.Context) {
        c.String(http.StatusOK, "Bye Bye!")
    }
    

    ... now you have 1 main endpoint that your Google function connects to HelloHTTP and 2 sub-endpoints hi and bye. so your endpoints would look like https://.../HelloHTTP/hi or https://.../HelloHTTP/bye (I added 2 sub-endpoints to better illustrate how the routing is working here)