在Google App Engine中托管Go项目时,应该如何处理文件路径? 打开templates / index.html:没有这样的文件或目录
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.
So... I tested this deployment in 3 different ways and what I found was that:
-
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.
-
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.
-
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.