Проблема с многоэтапными сборками Docker

У меня проблема с многоступенчатой ​​сборкой, когда двоичный файл, который создается на первом этапе, правильно копируется на этап 2, но когда вы пытаетесь запустить его, исполняемый файл не может быть найден.

Dockerfile:

FROM golang as goimage
ENV SRC=/go/src/
RUN mkdir -p /go/src/
WORKDIR /go/src/go_docker
RUN git clone https://github.com/bryonbaker/simple-microservice.git /go/src/go_docker/ \
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64
RUN go get github.com/gorilla/mux
RUN go build -o bin/go_docker

FROM alpine:latest AS microservice
RUN apk --no-cache add bash
ENV WORK_DIR=/docker/bin
WORKDIR $WORK_DIR
COPY --from=goimage /go/src/go_docker/bin/ ./

# Put a container-image version identifier in the root directory.
ARG VERSION=1.0
RUN echo $VERSION > image_version

EXPOSE 10000
#CMD ["go_docker"]

Результат:

$ docker run -ti -p 80: 10000 go-docker: последняя версия
/ docker / bin # ls

go_docker версия_образа
/ docker / bin # ./go_docker / bin / sh: ./go_docker: not found
/ docker / bin #

Если я запустил двоичный файл из созданного промежуточного контейнера goimage, он будет работать нормально. Размеры файлов совпадают ...

ПРИМЕЧАНИЕ. В этом файле докеров я закомментировал CMD и тестирую через оболочку. Если вы раскомментируете CMD, вы получите ту же проблему:

docker run go-docker: последний докер: ответ об ошибке от демона: сбой при создании среды выполнения OCI: container_linux.go: 344: запуск процесса контейнера вызвал "exec: \" go_docker \ ": исполняемый файл не найден в $ PATH": неизвестно. ERRO [0001] ошибка ожидания контейнера: контекст отменен

Я сделал тестовый код в репозитории git общедоступным, если вы хотите его посмотреть.

заранее спасибо


person Bryon    schedule 09.05.2019    source источник
comment
Не возражаете, включая команду, которую вы используете для создания этого изображения?   -  person ctt    schedule 09.05.2019
comment
Могу я предложить более конкретное название? например программа go отсутствует в многоэтапной сборке файла dockerfile   -  person kristianp    schedule 06.08.2019


Ответы (1)


Вы получите эту ошибку почти повсеместно в Linux, если общие библиотеки двоичного файла недоступны. (В оболочке отладки попробуйте запустить ldd /docker/bin/go_docker.)

Вы, вероятно, не ожидаете динамически связанного двоичного файла, но вы его получаете, потому что переменные оболочки и среды не передаются между RUN командами. Если вы устанавливаете CGO_ENABLED=0 в конце RUN шага, это значение теряется, когда фактическое go build выполняется двумя шагами позже.

(Я бы также немного очистил Dockerfile: такие вещи, как пути внутри контейнеров, не обязательно должны быть переменными, и вполне нормально использовать системные пути для вещей.)

Это оставляет нам:

FROM golang as goimage

# Use standard $GOPATH layout?
# WORKDIR /go/src/github.com/byronbaker/simple-microservice
# COPY . .
# RUN go get .
# RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install .

# !!! Docker layer caching will not repeat this step if the repo changes
# !!! You won't be able to build a test copy of your uncommitted code
RUN git clone https://github.com/bryonbaker/simple-microservice.git /go/src/go_docker
RUN go get github.com/gorilla/mux

# vvv Put magic environment variables in this line
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install go_docker
# ^^^

# Runtime image
FROM alpine:latest
COPY --from=goimage /go/bin/go_docker /bin/go_docker
ARG VERSION=1.0
RUN echo $VERSION > /image_version
EXPOSE 10000
CMD ["go_docker"]
person David Maze    schedule 09.05.2019
comment
Хороший! Я совершенно забыл об установке. Можете ли вы объяснить, почему установка переменных среды теряется позже? Я думал, что эта проблема возникла только после FROM. - person Bryon; 09.05.2019
comment
Каждая команда RUN выполняется в новой оболочке в новом контейнере. Вы можете поиграть с такими вещами, как RUN export ..., и убедиться, что это не действует. ENV будет сохраняться на разных уровнях и отображаться в RUN командных средах (и сбрасываться при запуске FROM нового изображения). - person David Maze; 09.05.2019