为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我的 Go Web 服务器在 Docker 容器内运行时会返回“找不到 404 页面”?

为什么我的 Go Web 服务器在 Docker 容器内运行时会返回“找不到 404 页面”?

Go
海绵宝宝撒 2022-08-15 10:04:35
我正在Go中构建一个小型的基本Web服务器。如果我在本地编译并运行它,它工作得很好 - 没有问题。页面显示,可以从本地主机访问,样式完好无损 - 一切都很好。如果我在Docker容器中执行此操作,则它不起作用。它返回“404 页未找到”。就像它没有任何静态资产一样...但这肯定不可能 - 静态资产有意嵌入到二进制文件中,使用“//go:embed”...正如我所说,如果你在本地构建和运行,它工作正常。我已经尝试了我能想到的一切...下面列出的一些步骤:各种不同的 docker 映像(alpine、ubuntu、golang、golang alpine 等)使用go:以不同的方式嵌入,即不同的模式我把一些基本的登录到服务器代码...但它似乎没有返回任何错误,所以没有帮助更改的端口/地址这只是我尝试过的一些东西,没有运气。我已经排除了下面的css,它并不真正相关,因为索引页面甚至没有显示任何样式。代码: 服务器代码DOCKERFILE:FROM golang:1.16.0-alpine3.13 AS buildWORKDIR /appCOPY . .RUN go build -o server .FROM golang:1.16.0-alpine3.13WORKDIR /appCOPY --from=build /app/server .EXPOSE 8080CMD ["./server"]网页:<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>GOOO</title>    <link rel="stylesheet" href="/assets/static/css/style.css"></head><body>    <h1>GO!!!</h1></body></html>目录结构:├── Dockerfile├── go.mod├── go.sum├── server.go├── server_test.go├── static│   ├── css│   │   └── style.css│   └── index.html
查看完整描述

1 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

根据评论,您遇到的主要问题是您正在从文件系统(而不是嵌入式文件系统)提供服务,并且该文件不存在于其中。index.html


第二个问题是嵌入式文件系统将包含单个目录,因此您需要使用类似的东西才能工作(否则您将需要 - 这适用于您的以及提供索引时.html)。statics, err := fs.Sub(static, "static")s.Open("index.html")static.Open("static/index.html")http.FileServer


注意:您可能不需要以下内容,因为您可以只为路径运行(因此它提供服务以及子目录中的文件)。 如果 url 中未提供文件名,则会自动提供服务。http.FileServer/index.htmlhttp.FileServerindex.html


要从嵌入式文件系统中提供服务,您可以将函数重写为(未经测试!index.html


// default/root handler which serves the index page and associated styling

func indexHandler(w http.ResponseWriter, r *http.Request) {

    f, err := s.Open("index.html") // Using `s` from above and assumes its global; better to use handlerfunc and pass filesystem in


    if err != nil {

        // Send whatever error you want (as file is embedded open should never fail)

        return

    }

    defer f.Close()


    w.Header().Set("Content-Type", "text/html")

    if _, err := io.Copy(w, f); err != nil { // Write out the file

        // Handle error

    }

}

上面依赖于一个全局变量(我不热衷于它),所以我会把它转换成这样的东西:


func IndexHandlerFunc(fs fs.FS, h http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        f, err := fs.Open("index.html")


        if err != nil {

            // Send whatever error you want (as file is embedded open should never fail)

            return

        }

        defer f.Close()


        w.Header().Set("Content-Type", "text/html")

        if _, err := io.Copy(w, f); err != nil { // Write out the file

            // Handle error

        }

    })

}


查看完整回答
反对 回复 2022-08-15
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信