php小編百草將為大家介紹如何解決在Docker容器中提供靜態ReactJS文件時出現的404頁面未找到的問題。在使用Docker部署應用程序時,有時會遇到這個問題,但不用擔心,我們可以通過一些簡單的步驟來解決。在本文中,我將分享如何正確配置Docker容器以提供靜態ReactJS文件,以及如何避免404頁面未找到的錯誤。讓我們一起來看看吧!
問題內容
我正在嘗試容器化一個在端口 8000 上提供靜態文件的 Go 應用程序。我查看了有關此主題的其他帖子,許多人似乎都說使用 router.Run("0.0.0.0:8000")
或 router .運行(“: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" ]
登錄后復制
我的文件夾結構如下所示;
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
文件。您正在嘗試從 ./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 構建步驟的一部分,但現在它完全包含在二進制文件中,不需要單獨復制到最終圖像中。