Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git executable not found in golang:alpine image #209

Closed
MatthewEdge opened this issue Feb 25, 2018 · 7 comments
Closed

git executable not found in golang:alpine image #209

MatthewEdge opened this issue Feb 25, 2018 · 7 comments

Comments

@MatthewEdge
Copy link

Attempting to run go get in the current golang:alpine image to grab the dep command and running into the following error:

github.com/golang/dep (download)
go: missing Git command. See https://golang.org/s/gogetcmd
package github.com/golang/dep/cmd/dep: exec: "git": executable file not found in $PATH
The command '/bin/sh -c go get -d -v github.com/golang/dep/cmd/dep' returned a non-zero code: 1

Issue persists after complete container and image wipe.

Dockerfile to reproduce (for me at least :D ) :

FROM golang:alpine

WORKDIR /go/src/github.com/MatthewEdge/web
COPY . .

# Dependency install
RUN go get -u github.com/golang/dep/cmd/dep
RUN $GOPATH/bin/dep ensure -vendor-only

RUN go install

CMD ["web"]

The application being run is the hello world HTTP server for Go. I'm currently getting around this by doing an apk update && apk install git at the top of this file but it seemed odd that this image wouldn't have git installed by default?

Thoughts?

Thanks!

@tianon
Copy link
Member

tianon commented Mar 2, 2018

Duplicate of #157 (see also #119).

In short, git is not included in the Alpine variants on purpose (as described in #119 and the image description).

golang:alpine

This image is based on the popular Alpine Linux project, available in the alpine official image. Alpine Linux is much smaller than most distribution base images (~5MB), and thus leads to much slimmer images in general.

This variant is highly recommended when final image size being as small as possible is desired. The main caveat to note is that it does use musl libc instead of glibc and friends, so certain software might run into issues depending on the depth of their libc requirements. However, most software doesn't have an issue with this, so this variant is usually a very safe choice. See this Hacker News comment thread for more discussion of the issues that might arise and some pro/con comparisons of using Alpine-based images.

To minimize image size, it's uncommon for additional related tools (such as git or bash) to be included in Alpine-based images. Using this image as a base, add the things you need in your own Dockerfile (see the alpine image description for examples of how to install packages if you are unfamiliar).

@sethyates
Copy link

@tianon sorry, but without git, go is mostly broken, as seen on a multitude of issues here referencing go get and almost every Dockerfile I've seen that utilizes golang:alpine first installs git (to make go usable). It doesn't seem like too much of a stretch to include git in golang:alpine as the main use case is typically to build binaries which are then run on a bare alpine.

@TylerReid
Copy link

@sethyates you can use multi stage docker builds to have a build container and a runtime container to get around this. This ends up in a smaller image.

FROM golang:1.12 AS build
COPY . /app
WORKDIR /app
RUN go get -d
RUN go build -o your-thing
# or FROM golang:alpine or some other base depending on need
FROM alpine:latest AS runtime
#this seems dumb, but the libc from the build stage is not the same as the alpine libc
#create a symlink to where it expects it since they are compatable. https://stackoverflow.com/a/35613430/3105368
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
WORKDIR /app
COPY --from=build /app/your-thing ./

This way your image is around 10mb+your binary

@pmoorani
Copy link

pmoorani commented Sep 11, 2019

Maybe this can help you.

FROM golang:1.12 as builder

# Set Environment Variables
ENV HOME /app
ENV CGO_ENABLED 0
ENV GOOS linux

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .

# Build app
RUN go build -a -installsuffix cgo -o main .

FROM alpine:latest

RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy the pre-built binary file from the previous stage
COPY --from=builder /app/main .

EXPOSE 8080

CMD [ "./main" ]

@tikhoplav

This comment has been minimized.

@farhanroy

This comment has been minimized.

@SOF3
Copy link

SOF3 commented May 12, 2023

The point is that the Go compiler itself requires the git executable file in order to fetch modules properly. The argument for multi-stage containers is precisely why git should be installed in the golang:alpine image — the output binary is copied to the runtime stage anyway, and installing git in the compile stage does not matter. The golang:alpine image is pretty useless without apk add git, because it is a dependency of the Go toolchain itself.

If the argument goes that you should just use alpine in the runtime stage, then what is the point of distributing the golang:alpine image? I am using the alpine image for compile stage because I want to reduce the image size to pull for building the runtime image, which is orthogonal to reducing the image size for the runtime stage (which should be separated anyway because the Go toolchain is also huge).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants