Локально, когда я пытаюсь создать приложение Go (main.go
), я использую go build -o run-app -v main.go
для создания run-app
исполняемого файла. Если я попытаюсь изменить команду на go build -o /run-app -v main.go
, на моем Mac появится следующее сообщение об ошибке:
command-line-arguments: go build command-line-arguments: copying /var/folders/pp/rtf2ttw90bg5k2t1mw_ylcq00000gn/T/go-build1574791546/b001/exe/a.out: open /run-app: read-only file system
Я использую следующий файл Dockerfile для развертывания своего приложения:
ARG GO_VERSION=1
# Specifies a parent image
FROM golang:${GO_VERSION}-bookworm as builder
# Creates an app directory to hold your app’s source code
WORKDIR /usr/src/app
# Copies everything from your root directory into /app
COPY . .
# Installs Go dependencies
RUN go mod download && go mod verify
# Builds your app with optional configuration
RUN CGO_ENABLED=0 go build -o /run-app -v main.go
# Specifies a parent image
FROM debian:bookworm
# Tells Docker which network port your container listens on
EXPOSE 8080
# Specifies the executable command that runs when the container starts
COPY --from=builder /run-app /usr/local/bin/
CMD ["run-app", "serve", "--http=0.0.0.0:8080"]
Это работает, только если я использую /run-app
в команде сборки. В противном случае команда COPY
ниже не сработает: COPY --from=builder /run-app /usr/local/bin/
— даже если я попытаюсь ее адаптировать.
Мне интересно, в чем разница между /run-app
и run-app
. Папку создать? Почему это не работает локально?
Ни один из них не создает папку.
/run-app
пытается записать исполняемый файл в корневой путь файловой системы; на Mac, который доступен только для чтения, но в контейнере — нет.
Без косой черты он создает двоичный файл в текущем каталоге.
Если вы исключите косую черту в Dockerfile, вам понадобится COPY --from=builder /usr/src/app/run-app
, так как это WORKDIR
.