programa instalar ejecutar compilar como go docker busybox alpine

instalar - El binario compilado de Go no se ejecutará en un contenedor de ventana acoplable alpino en el host de Ubuntu



gcc linux (3)

De forma predeterminada, si utiliza el paquete de net , es probable que una compilación produzca un binario con algún enlace dinámico, por ejemplo, a libc. Puede inspeccionar el enlace dinámico vs. estático viendo el resultado de ldd output.bin

Hay dos soluciones que he encontrado:

  • Deshabilitar CGO, a través de CGO_ENABLED=0
  • Forzar el uso de la implementación de Go de las dependencias de red, netgo a través de go build -tags netgo -a -v , esto se implementa para ciertas plataformas

De https://golang.org/doc/go1.2 :

El paquete net requiere cgo de forma predeterminada porque el sistema operativo del host debe mediar en general en la configuración de llamadas de red. En algunos sistemas, sin embargo, es posible usar la red sin cgo, y es útil hacerlo, por ejemplo, para evitar la vinculación dinámica. La nueva etiqueta de compilación netgo (desactivada de forma predeterminada) permite la construcción de un paquete de red en Go puro en aquellos sistemas donde sea posible.

Lo anterior supone que la única dependencia de CGO es el paquete net la biblioteca estándar.

Dado un binario, compilado con Go usando GOOS=linux y GOARCH=amd64 , implementado en un contenedor docker basado en alpine:3.3 , el binario no se ejecutará si el host del motor del docker es Ubuntu (15.10):

sh: /bin/artisan: not found

Este mismo binario (compilado para el mismo sistema operativo y arco) se ejecutará bien si el host del motor de docker es busybox (que es la base para alpine ) implementado dentro de una VM VirtualBox en Mac OS X.

Este mismo binario también funcionará perfectamente si el contenedor está basado en una de las imágenes de Ubuntu.

¿Alguna idea de lo que falta este binario?

Esto es lo que he hecho para reproducir (ejecución exitosa en VirtualBox / busybox en OS X no se muestra):

Construir (construir explícitamente con banderas aunque el arco coincida):

➜ artisan git:(master) ✗ GOOS=linux GOARCH=amd64 go build

Compruebe que se puede ejecutar en el host:

➜ artisan git:(master) ✗ ./artisan 10:14:04.925 [ERROR] artisan: need a command, one of server, provision or build

Copiar a la ventana acoplable dir, construir, ejecutar:

➜ artisan git:(master) ✗ cp artisan docker/build/bin/ ➜ artisan git:(master) ✗ cd docker ➜ docker git:(master) ✗ cat Dockerfile FROM docker:1.10 COPY build/ / ➜ docker git:(master) ✗ docker build -t artisan . Sending build context to Docker daemon 10.15 MB Step 1 : FROM docker:1.10 ... ➜ docker git:(master) ✗ docker run -it artisan sh / # /bin/artisan sh: /bin/artisan: not found

Ahora cambiando la base de la imagen a phusion/baseimage :

➜ docker git:(master) ✗ cat Dockerfile #FROM docker:1.10 FROM phusion/baseimage COPY build/ / ➜ docker git:(master) ✗ docker build -t artisan . Sending build context to Docker daemon 10.15 MB Step 1 : FROM phusion/baseimage ... ➜ docker git:(master) ✗ docker run -it artisan sh # /bin/artisan 08:16:39.424 [ERROR] artisan: need a command, one of server, provision or build


El compilador Go de su máquina de compilación probablemente vincula su binario con bibliotecas en una ubicación diferente a la de Alpine. En mi caso, fue compilado con dependencias bajo / lib64 pero Alpine no usa esa carpeta.

FROM alpine:edge AS build RUN apk update RUN apk upgrade RUN apk add --update go=1.8.3-r0 gcc=6.3.0-r4 g++=6.3.0-r4 WORKDIR /app ENV GOPATH /app ADD src /app/src RUN go get server # server is name of our application RUN CGO_ENABLED=1 GOOS=linux go install -a server FROM alpine:edge WORKDIR /app RUN cd /app COPY --from=build /app/bin/server /app/bin/server CMD ["bin/server"]

Estoy trabajando en un artículo sobre este tema. Puede encontrar el borrador con esta solución aquí http://kefblog.com/2017-07-04/Golang-ang-docker .


Tuve el mismo problema con un binario go, y lo hice funcionar después de agregar esto a mi archivo docker:

RUN apk add --no-cache / libc6-compat