douweidao3882
douweidao3882
2019-08-24 12:43

在Google App Engine中托管Go项目时,应该如何处理文件路径? 打开templates / index.html:没有这样的文件或目录

  • deployment
已采纳

I am trying to deploy a simple go language code on Google's app engine. This is the code I am trying to deploy. https://github.com/GoogleCloudPlatform/golang-samples/tree/master/appengine/go11x/static

main.go

package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "os"
    "path/filepath"
    "time"
)

var (
    indexTmpl = template.Must(
        template.ParseFiles(filepath.Join("templates", "index.html")),
    )
)

func main() {
    http.HandleFunc("/", indexHandler)

    // Serve static files out of the public directory.
    // By configuring a static handler in app.yaml, App Engine serves all the
    // static content itself. As a result, the following two lines are in
    // effect for development only.
    public := http.StripPrefix("/public", http.FileServer(http.Dir("public")))
    http.Handle("/public/", public)

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
        log.Printf("Defaulting to port %s", port)
    }

    log.Printf("Listening on port %s", port)
    log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}

// indexHandler uses a template to create an index.html.
func indexHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }
    type indexData struct {
        Logo        string
        Style       string
        RequestTime string
    }
    data := indexData{
        Logo:        "/public/gcp-gopher.svg",
        Style:       "/public/style.css",
        RequestTime: time.Now().Format(time.RFC822),
    }
    if err := indexTmpl.Execute(w, data); err != nil {
        log.Printf("Error executing template: %v", err)
        http.Error(w, "Internal server error", http.StatusInternalServerError)
    }
}

When I deploy this code using gcloud app deploy and use the browser to load the webpage, I see error

2019-08-24 06:32:19 default[]  "GET / HTTP/1.1" 500
2019-08-24 06:32:20 default[]  panic: open templates/index.html: no such file or directory    goroutine 1 [running]:  html/template.Must(0x0, 0x800800, 0xc000078f90, 0
x0)     /usr/local/go/src/html/template/template.go:372 +0x54

My app.yaml file looks like this. It has static mentioned but nothing about templates.

runtime: go111
handlers:
# Configure App Engine to serve any static assets.
- url: /public
  static_dir: public
# Use HTTPS for all requests.
- url: /.*
  secure: always
  redirect_http_response_code: 301
  script: auto

Question: How do I handle templates and other small files that I want the application to read? Mine is a toy application so I do not need cloud storage or any such solution. I just want to read from a (local) directory.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dqxhit3376 dqxhit3376 2年前

    So... I tested this deployment in 3 different ways and what I found was that:

    1. Directly cloning the repo with git clone, cd to the static folder, and deploying from there, reproduced the issue, but only if I did it from my Google Cloud Shell.

      a. I later found out that the Go version I had in the Cloud Shell was the Go 1.12.

      b. I created a new VM instance to test it from a fresh Go 1.11 environment and the same process worked like a treat.

    2. The same process as the above, but instead of deploying from the static, I moved its content to a different directory and then I deployed it from there.

      a. This worked in the VM instance and in the Cloud Shell.

    3. As suggested in the Quickstart for Go 1.11 in the App Engine Standard Environment, I downloaded the sample code using the go get command, cd to the static folder and deployed from there.

      a. This also worked in both environments.

    My suggestion is to always try to download Google's golang samples using the go get command, as it is suggested in the guides and it did not mess with the App Engine deployment in the tests I made.

    It is also important to mention that both environments had the same Cloud SDK version, which is the 259.

    点赞 评论 复制链接分享