Docker环境下Go+Fiber应用上传大文件报502 Bad Gateway问题
问题描述
本地运行Go+Fiber后端应用时,大文件上传(超过16MB)正常,但部署到Docker后,上传大于15MB的文件会触发502 Bad Gateway错误,小文件上传无异常。已在Fiber配置中设置BodyLimit为520MB,排除应用自身配置问题,推测是Docker相关限制导致。
相关代码
Dockerfile
FROM golang:1.22.4 AS builder WORKDIR /build COPY . . WORKDIR /build/apps/Myapp/backend RUN go mod download ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 RUN go build -ldflags='-s -w -extldflags "-static"' -o myapp-api . FROM alpine as certs RUN apk --no-cache add ca-certificates FROM scratch COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=builder ["/build/apps/Myapp/backend/myapp-api", "/build/apps/Myapp/backend/.env.production", "/"] COPY --from=builder ["/build/apps/Myapp/backend/templates", "/templates"] EXPOSE 4000 ENTRYPOINT ["/myapp-api"] CMD ["--mode", "prod"]
Fiber配置代码
app := fiber.New(fiber.Config{ ErrorHandler: utils.ErrorHandler, BodyLimit: 520 * 1024 * 1024, JSONEncoder: json.Marshal, JSONDecoder: json.Unmarshal, })
排查方向与解决方法
检查前端反向代理的请求体限制
如果Docker容器前端部署了Nginx、Traefik等反向代理服务,这类工具通常默认有请求体大小限制(比如Nginx默认1MB,部分网关默认16MB)。需要修改代理配置,例如Nginx中添加client_max_body_size 520M;到server或http块中,确保允许的请求体大小与Fiber配置一致。验证Docker容器的资源分配
检查是否给容器设置了过严的内存/CPU限制,大文件上传时可能因内存不足导致应用进程崩溃,进而返回502。可以通过docker stats命令查看容器运行时的资源占用情况,或在启动容器时增加资源分配,例如:docker run --memory 2g --cpus 1 your-image-name替换Scratch镜像为Alpine镜像
Scratch镜像过于精简,可能缺少某些隐性依赖,导致大文件处理时出现异常。尝试将最终镜像替换为Alpine镜像,修改Dockerfile的最终阶段:FROM alpine:latest COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=builder ["/build/apps/Myapp/backend/myapp-api", "/build/apps/Myapp/backend/.env.production", "/"] COPY --from=builder ["/build/apps/Myapp/backend/templates", "/templates"] EXPOSE 4000 ENTRYPOINT ["/myapp-api"] CMD ["--mode", "prod"]确认Fiber Prod模式的配置生效
启动时使用--mode prod参数,需验证Fiber的BodyLimit配置是否在Prod模式下正常生效。可以在应用中添加日志打印实际生效的BodyLimit值,例如:log.Printf("Current BodyLimit: %d bytes", app.Config().BodyLimit)确保配置没有被Prod模式的默认值覆盖。
内容的提问来源于stack exchange,提问作者Andrew Rusinas

