Masalah dengan build multi-tahap Docker

Saya memiliki masalah dengan pembangunan multi-tahap di mana biner yang sedang dibangun pada tahap pertama disalin dengan benar ke tahap 2, tetapi ketika Anda mencoba dan menjalankannya, file yang dapat dieksekusi tidak dapat ditemukan.

File buruh pelabuhannya adalah:

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"]

Hasilnya adalah:

$ docker run -ti -p 80:10000 go-docker:terbaru
/docker/bin # ls

go_docker image_version
/docker/bin # ./go_docker /bin/sh: ./go_docker: tidak ditemukan
/docker/bin #

Jika saya menjalankan biner dari wadah goimage perantara yang dibuat maka itu berjalan dengan baik. Ukuran filenya cocok...

CATATAN: Di dockerfile ini saya telah mengomentari CMD dan menguji melalui shell. Jika Anda menghapus komentar pada CMD, Anda mendapatkan masalah yang sama:

docker run go-docker:latest docker: Respons kesalahan dari daemon: Pembuatan runtime OCI gagal: container_linux.go:344: memulai proses container menyebabkan "exec: \"go_docker\": file yang dapat dieksekusi tidak ditemukan di $PATH": tidak diketahui. Kesalahan ERRO[0001] menunggu penampung: konteks dibatalkan

Saya telah membuat kode pengujian di git repo publik jika Anda ingin melihatnya.

Terima kasih sebelumnya


person Bryon    schedule 09.05.2019    source sumber
comment
Bolehkah menyertakan perintah yang Anda gunakan untuk membuat gambar ini?   -  person ctt    schedule 09.05.2019
comment
Bolehkah saya menyarankan judul yang lebih spesifik? misalnya program go hilang dalam pembuatan dockerfile multi-tahap   -  person kristianp    schedule 06.08.2019


Jawaban (1)


Anda akan mendapatkan kesalahan ini secara universal di Linux jika perpustakaan bersama biner tidak tersedia. (Di shell debug Anda, coba jalankan ldd /docker/bin/go_docker.)

Anda mungkin tidak mengharapkan biner yang tertaut secara dinamis, tetapi Anda mendapatkannya karena variabel shell dan lingkungan tidak berpindah di antara perintah RUN. Jika Anda menetapkan CGO_ENABLED=0 di akhir langkah RUN, nilai tersebut akan hilang ketika go build sebenarnya dijalankan dua langkah kemudian.

(Saya juga akan membersihkan Dockerfile sedikit: hal-hal seperti jalur di dalam container tidak perlu berupa variabel, dan tidak masalah menggunakan jalur sistem untuk berbagai hal.)

Ini memberi kita:

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
Bagus sekali! Saya benar-benar lupa tentang instalasi. Bisakah Anda menjelaskan mengapa pengaturan variabel lingkungan kemudian hilang? Saya pikir masalah itu hanya terjadi setelah FROM. - person Bryon; 09.05.2019
comment
Setiap perintah RUN dijalankan di shell baru dalam wadah baru. Anda dapat bermain-main dengan hal-hal seperti RUN export ... dan melihat bahwa itu tidak berpengaruh. ENV akan dipertahankan di seluruh lapisan dan muncul di lingkungan perintah RUN (dan akan diatur ulang saat Anda memulai FROM gambar baru). - person David Maze; 09.05.2019