exec /main:构建Go应用程序的docker镜像时没有这样的文件或目录

问题描述 投票:0回答:1

我有一个 golang 应用程序,我想对其进行 dockerize 并在 AWS Lambda 上运行。这是我的 Dockerfile:

FROM golang:1.21 as build
WORKDIR /app
RUN apt-get update
RUN apt-get install -y libvips libvips-dev
COPY go.mod go.sum ./
COPY main.go .
RUN GOOS=linux GOARCH=amd64 go build -o main main.go

FROM alpine:3.19
COPY --from=build /app/main /main
ENTRYPOINT [ "/main" ]

我安装 libvips 因为我使用 bimg 库进行图像压缩。

这是我的缩小版 Go 应用程序:

package main

import (
    "context"
    "log"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/h2non/bimg"
)

var (
    s3Client *s3.Client
)

func init() {
    cfg, err := config.LoadDefaultConfig(context.Background())
    if err != nil {
        log.Fatalf("failed to load AWS config: %v", err)
    }

    s3Client = s3.NewFromConfig(cfg)
}

func main() {
    lambda.Start(Handler)
}

func Handler(ctx context.Context, event events.S3Event) error {
    // compress and upload and do stuff
    return nil
}

当我尝试从 aws 仪表板测试 lambda 时,我不仅收到错误

exec /main: no such file or directory
,而且当我尝试使用以下命令在本地计算机上运行图像时,它也会给我同样的错误:

docker run --rm -it  s3-image-compressor-lambda:latest

我知道 lambda 无法在我的本地计算机上运行,但我相信它不应该说文件未找到,而是我期望出现运行时错误。

更新:我向 Dockerfile 添加了一些命令来尝试调试以查看发生了什么。

我在复制主文件之后添加了

RUN ls -l /
,这是输出:

#16 [stage-1 4/7] RUN ls -l /
#16 0.354 total 18668
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 bin
#16 0.354 drwxr-xr-x    5 root     root           340 Apr  4 22:28 dev
#16 0.354 drwxr-xr-x    1 root     root          4096 Apr  4 22:28 etc
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 home
#16 0.354 drwxr-xr-x    7 root     root          4096 Jan 26 17:53 lib
#16 0.354 -rwxr-xr-x    1 root     root      19055376 Apr  4 22:06 main
#16 0.354 drwxr-xr-x    5 root     root          4096 Jan 26 17:53 media
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 mnt
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 opt
#16 0.354 dr-xr-xr-x  459 root     root             0 Apr  4 22:28 proc
#16 0.354 drwx------    2 root     root          4096 Jan 26 17:53 root
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 run
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 sbin
#16 0.354 drwxr-xr-x    2 root     root          4096 Jan 26 17:53 srv
#16 0.354 dr-xr-xr-x   13 root     root             0 Apr  4 22:28 sys
#16 0.354 drwxrwxrwt    2 root     root          4096 Jan 26 17:53 tmp
#16 0.354 drwxr-xr-x    7 root     root          4096 Jan 26 17:53 usr
#16 0.354 drwxr-xr-x   12 root     root          4096 Jan 26 17:53 var
#16 DONE 0.4s

所以根目录下其实有一个main文件。

之后我添加了

RUN /main
看看会发生什么,这是输出:

 > [stage-1 8/8] RUN /main:
0.258 /bin/sh: /main: not found
docker go aws-lambda
1个回答
0
投票

我不认为

libvips
是问题所在。我怀疑你只需要制作一个完全独立的可执行文件(静态链接)。

FROM golang:1.21 as build

WORKDIR /app

RUN apt-get update
RUN apt-get install -y libvips libvips-dev

COPY go.mod go.sum main.go .

RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build \
        -tags netgo \
        -ldflags '-w -extldflags "-static"' \
        -o main main.go

FROM alpine:3.19


RUN apk add --no-cache ca-certificates

COPY --from=build /app/main /main

ENTRYPOINT [ "/main" ]

go build
的各种标志和参数将确保

  • 没有基于 C 的库是动态链接的;
  • 该二进制文件是为 Linux/AMD64 架构构建的;
  • Go net 包使用纯 Go 解析器;
  • 调试信息被剥离;和
  • 与静态系统库链接的可执行文件。
© www.soinside.com 2019 - 2024. All rights reserved.