我正在try 包装一个在端口8000上提供静态文件的Go应用程序.我看过关于这个话题的其他帖子,很多人似乎都说用router.Run("0.0.0.0:8000")router.Run(":8000").我两个都试过了,但还是不成功.我的main.go如下所示:

package main

// required packages
import (

    "fmt"
    "log"
    "os"

    "github.com/gin-gonic/gin"
    "github.com/gin-contrib/cors
    "net/http"
)

func main() {
    // start the server
    serveApplication()

}

func serveApplication() {
    corsConfig := cors.Config {
        AllowOrigins: []string{"*"},
        AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
        AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
        AllowCredentials: true,
    }

    router := gin.Default()
    router.Use(cors.New(corsConfig))

    router.StaticFS("/static", http.Dir("./frontend/build/static"))
    router.StaticFile("/", "./frontend/build/index.html")
    router.Run(":8000")
    fmt.Println("Server running on port 8000")
}

和以下Dockerfile:

FROM node:16-alpine3.11 as build-node

WORKDIR /workdir
COPY frontend/ .
RUN yarn install
RUN yarn build

COPY .env /workdir/

FROM golang:1.21-rc-alpine3.18 as build-go
#FROM golang:1.17rc2-alpine3.14 as build-go

ENV GOPATH ""
RUN go env -w GOPROXY=direct
RUN apk add git

ADD go.mod go.sum ./
RUN go mod download
ADD . .
COPY --from=build-node /workdir/build ./frontend/build
RUN go build -o /main

FROM alpine:3.13
COPY --from=build-go /main /main
COPY --from=build-node /workdir/.env .env
EXPOSE 8000
ENTRYPOINT [ "/main" ]

我的文件夹 struct 如下所示;

portal
- frontend (here the react app is stored)
- backend (all my backend logic)
- Dockerfile
- main.go
- go.mod

当我在本地运行go run main.go时,前端在端口8000上被正确地服务,并且加载http://localhost:8000工作得很好.当我用docker build -t portal .构建docker映像,然后用docker run -p 8000:8000 --name portal portal运行它时,我可以在终端中看到服务器启动,并说它在端口8000上运行,但我总是得到404页未找到错误.

我试过用router.run("0.0.0.0:8000")router.run("localhost:8000")docker run --network host --name portal portal.

我有什么遗漏的吗?我是否将前端构建复制到了错误的位置?

推荐答案

最终图像中唯一的内容是最后FROM行之后的COPY内容;即main二进制文件和.env文件.您正在try 提供./frontend/...个文件中的文件,但这不在最终图像中.只需将相关的COPY行移动到最后阶段就可以了.

FROM alpine:3.13
COPY --from=build-go /main /main
COPY --from=build-node /workdir/.env .env
COPY --from=build-node /workdir/build ./frontend/build # <-- move from above
...

相反,因为您没有使用类似于embed包的东西来直接将构建的前端代码嵌入到二进制文件中,所以在(GO)构建阶段不需要它.

它也可以使用embed,而不是重新排列您的Dockerfile.这大概看起来像是

//go:embed frontend/build/*
var content embed.FS

router.StaticFS("/static", http.FS(fs.Sub(content, "frontend/build/static"))
router.StaticFileFS("/", "frontend/build/index.html", http.FS(content))

有了这个设置,前端确实需要成为Go构建步骤的一部分,但现在它完全包含在二进制文件中,不需要单独复制到最终映像中.

Node.js相关问答推荐

赫斯基添加命令已弃用?

@nuxtjs/站点 map 错误提示:找不到包';NitroPack';

如何从shell脚本中计算ecmascript模块?

Puppeteer 的 BrowserFetcher 发生了什么?

Mongodb - 在数组数组中查找()

在 Docker 容器内创建一个 cron 作业(job)来执行 run.js 文件中的函数

无法将示例 Node.js 应用程序部署到 AWS Elastic Beanstalk

在 linux mint 上部署 node 应用程序的最简单方法是什么?

将 express js app.use() 移动到另一个文件

图像存储在后端文件夹中,但使用 multer 和 react.js 在前端找不到

使用 Node.JS,如何按时间顺序获取文件列表?

密码的 Node.js 散列

如何使用 Node.js、Express 和 Mongoose 进行身份验证?

Nodejs续集批量更新

如何解决 Socket.io 404(未找到)错误?

Node.js 17.0.1 Gatsby 错误-数字信封 routine ::不支持 ... ERR_OSSL_EVP_UNSUPPORTED

Mongoose - 保存字符串数组

node.js 在控制台上显示未定义

Google Firebase 错误(函数返回未定义、预期的 Promise 或值)

promise 回调返回promise