How to install Go in alpine linux - docker

I am trying to install Go inside an Alpine Docker image. For that I downloaded tar file from here inside my alpine docker image, untar it using following command:
tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
exported PATH to have go binary as:
export PATH=$PATH:/usr/local/go/bin
However, when I say go version then it says that sh: go: not found. I am quite new to alpine. Does anyone know, what I am missing here?
Steps to reproduce-
$ docker run -it alpine sh
$ wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
$ tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
$ export PATH=$PATH:/usr/local/go/bin
$ go version

I just copied it over using multi stage builds, seems to be ok so far
FROM XXX
COPY --from=golang:1.13-alpine /usr/local/go/ /usr/local/go/
ENV PATH="/usr/local/go/bin:${PATH}"

The following Dockerfile worked for me. Simpler and more abstract.
FROM alpine:latest
RUN apk add --no-cache git make musl-dev go
# Configure Go
ENV GOROOT /usr/lib/go
ENV GOPATH /go
ENV PATH /go/bin:$PATH
RUN mkdir -p ${GOPATH}/src ${GOPATH}/bin
# Install Glide
RUN go get -u github.com/Masterminds/glide/...
WORKDIR $GOPATH
CMD ["make"]
source: https://raw.githubusercontent.com/mickep76/alpine-golang/master/Dockerfile

Thanks BMitch.
I compiled the go source code and performed the below steps inside alpine image container.
echo "installing go version 1.10.3..."
apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go
wget -O go.tgz https://dl.google.com/go/go1.10.3.src.tar.gz
tar -C /usr/local -xzf go.tgz
cd /usr/local/go/src/
./make.bash
export PATH="/usr/local/go/bin:$PATH"
export GOPATH=/opt/go/
export PATH=$PATH:$GOPATH/bin
apk del .build-deps
go version

With Alpine, you have libmusl instead of glibc. Alpine's libmusl is not a 1 for 1 replacement. Code linked against glibc will show a not found error which is actually from the dynamic linker. You can see what libraries are linked to the binary with ldd:
/ # ldd /usr/local/go/bin/go
/lib64/ld-linux-x86-64.so.2 (0x7f63ceed1000)
libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f63ceed1000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f63ceed1000)
There are two options. The preferred option, and one used by docker's go images on Alpine, is to compile the go binaries on Alpine. You can see this in the Dockerfile for the golang image: https://github.com/docker-library/golang/blob/69f2d2a132565bf60afc91813801a3bdcc981526/1.10/alpine3.8/Dockerfile
The other option is to install glibc on Alpine, but once you start doing things like that, I'd question why use Alpine at all, and whether Debian or CentOS would be a more appropriate base image for you. Alpine has a wiki topic on this and there are third parties that have created glibc packages for alpine.

I found the best way to get golang up running in alpine linux is to install it from source. This is also way followed in the official alpine go docker images.
FROM alpine:3.12
ARG GOLANG_VERSION=1.14.3
#we need the go version installed from apk to bootstrap the custom version built from source
RUN apk update && apk add go gcc bash musl-dev openssl-dev ca-certificates && update-ca-certificates
RUN wget https://dl.google.com/go/go$GOLANG_VERSION.src.tar.gz && tar -C /usr/local -xzf go$GOLANG_VERSION.src.tar.gz
RUN cd /usr/local/go/src && ./make.bash
ENV PATH=$PATH:/usr/local/go/bin
RUN rm go$GOLANG_VERSION.src.tar.gz
#we delete the apk installed version to avoid conflict
RUN apk del go
RUN go version

If the basic requirement is to have specific go version installed inside alpine based docker image then refer these images available on official golang dockerhub account.
docker pull golang:1.12-alpine
docker pull golang:1.11-alpine

Just in case someone encounters the same issue with me.
I was able to install the golang1.17.6 ion Alpine3.15 by following #Yogesh Jilhawar 's answer.
When I ran the command apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go, I got
ERROR: unable to select packages:
go (no such packages):
required by: world[go]
Then I tried to install the "gcc-go", it installs. After that, I can build the golang from the source successfully.

There Is the Alpine package, with the latest versione of golang:
pkg --update add go

Related

qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory

I have a Rancher Deskop(dockerd) on M1 MacOS and when I am trying to build below dockerfile I am getting an error such as below. Here is the command how I am trying to build the image docker build -t te-grafana-dashboards-toolchain --no-cache .
I tried to change the platforms but nonae of them worked for me. I am a bit lost about this platform issue for M1 but any help will be appreciated, What I am doing wrong? What might the root cause of this?
Removing intermediate container 70af516d5d6b
---> a69229847153
Step 5/6 : RUN GO111MODULE="on" go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb; ln -s $(go env GOPATH)/bin/jb /usr/bin/jb
---> Running in 13545862fffe
qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
Removing intermediate container 13545862fffe
Dockerfile
FROM --platform=linux/amd64 ubuntu:focal
RUN apt update; apt install -y curl jq build-essential python3.8 python3-pip docker-compose jsonnet bison mercurial
RUN ln -s /usr/bin/python3.8 /usr/bin/python
RUN curl -OL https://golang.org/dl/go1.17.linux-amd64.tar.gz; mkdir /etc/golang; tar -xvzf go1.17.linux-amd64.tar.gz -C /etc/golang; ln -s /etc/golang/go/bin/go /usr/bin/go; rm -f go1.17.linux-amd64.tar.gz
RUN GO111MODULE="on" go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb; ln -s $(go env GOPATH)/bin/jb /usr/bin/jb
WORKDIR /workspace
Incidentally, in case it's helpful to another who lands here, I have the same issue on an M1 Max MacBook Pro laptop attempting to do a docker build from a company repo that should be a pretty well traveled path, but I might be the only one (it's a small company) that has an ARM64 M1 "Apple Silicon" Mac. However I found the solution (well, a solution) to my situation was exactly the opposite of the solution to the OP's, and that was to add --platform=linux/amd64 to the FROM line of the docker file.
Otherwise it was using an ARM64 image to start from without me being the wiser but then later in the Dockerfile the build attempts to install and execute code compiled for x86_64. Starting the build process by requesting the base image be linux/amd64 ends up with then the base image having /lib64/ld-linux-x86-64.so.2. This probably means everything is being emulated as x86_64 on the ARM64 CPU via qemu-x86_64 and so if you have the option to start from an ARM64 image and can compile within the container during build time any software you can't install as ARM64 binaries, it'll probably go faster when you later run the container on the M1 based Mac. I'm not able to try that myself just yet for this case.
Modifying Dockerfile seems to be the most popular answer but you can also set the DOCKER_DEFAULT_PLATFORM environment variable to linux/amd64.
export DOCKER_DEFAULT_PLATFORM=linux/amd64
The cause seems to reside in the AArch64 image.
this resolved my issue.
FROM ubuntu:focal
RUN apt update; apt install -y curl jq build-essential python3.8 python3-pip docker-compose jsonnet bison mercurial
RUN ln -s /usr/bin/python3.8 /usr/bin/python
RUN curl -OL https://golang.org/dl/go1.17.linux-arm64.tar.gz; mkdir /etc/golang; tar -xvzf go1.17.linux-arm64.tar.gz -C /etc/golang; ln -s /etc/golang/go/bin/go /usr/bin/go; rm -f go1.17.linux-arm64.tar.gz
RUN GO111MODULE="on" go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb#latest; ln -s /root/go/bin/jb /usr/bin/jb
WORKDIR /workspace
Instead of editing the Dockerfile, as suggested in this answer, or setting an environment variable, as suggested in this answer, I prefer to pass the platform as an argument to the docker build command, with the --platform flag. The command used by the OP would then be:
docker build --platform linux/amd64 -t te-grafana-dashboards-toolchain --no-cache .
Passing following flag to C preprocessor as CPPFLAGS solved similar issue in my M1
-DPNG_ARM_NEON_OPT=0
Pass the value as env var with key CPPFLAGS to relevant service.
Provided the base image includes the target architecture, another option that might work in your case is using Docker's built-in TARGETARCH build arg. This works for me on macOS M1.
FROM ubuntu:focal
ARG TARGETARCH
RUN apt update; apt install -y curl jq build-essential python3.8 python3-pip docker-compose jsonnet bison mercurial
RUN ln -s /usr/bin/python3.8 /usr/bin/python
RUN curl -OL https://golang.org/dl/go1.17.linux-${TARGETARCH}.tar.gz; mkdir /etc/golang; tar -xvzf go1.17.linux-${TARGETARCH}.tar.gz -C /etc/golang; ln -s /etc/golang/go/bin/go /usr/bin/go; rm -f go1.17.linux-${TARGETARCH}.tar.gz
RUN GO111MODULE="on" go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb; ln -s $(go env GOPATH)/bin/jb /usr/bin/jb
WORKDIR /workspace

Docker : Dockerfile can't execute COPY

I ve to build a docker images .
Inside my repositiory , i ve those files :
Dockerfile
docker-prompt
My Dockerfile is :
FROM fortio/fortio:1.3.1 as fortiobuild
FROM docker:stable-dind
RUN apk add --no-cache tcpdump apache2-utils lynx git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh openssl tree python python-dev py-pip libffi-dev openssl-dev libgcc nfs-utils
ENV COMPOSE_VERSION=1.24.1
RUN pip install docker-compose==${COMPOSE_VERSION}
RUN mkdir /etc/bash_completion.d \
&& curl https://raw.githubusercontent.com/docker/cli/master/contrib/completion/bash/docker -o /etc/bash_completion.d/docker \
&& sed -i "s/ash/bash/" /etc/passwd
RUN rm /sbin/modprobe && echo '#!/bin/true' >/sbin/modprobe && chmod +x /sbin/modprobe
COPY ["docker-prompt", "sudo", "/usr/local/bin/"]
I ve run this cmd :
docker build -t "myImage"
but if fails throwing this :
Step 8/8: COPY ["docker-prompt", "sudo", "/usr/local/bin/"] COPY
failed: stat /var/lib/docker/tmp/docker-builder273771066/sudo: no such
file or directory
Since it's not clear what is the problem ,
Suggestions ?
COPY command work with source and destination only, if you want to own file to sudo then you need to use --chown. otherwise the copy command will consider the Sudo as the source path.
COPY
COPY has two forms:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
Note:
The --chown feature is only supported on Dockerfiles used to build
Linux containers, and will not work on Windows containers. Since user
and group ownership concepts do not translate between Linux and
Windows, the use of /etc/passwd and /etc/group for translating user
and group names to IDs restricts this feature to only be viable for
Linux OS-based containers.
I assume that you are looking for a way like
COPY --chown=root:root docker-prompt /usr/local/bin/

Setting up NSCA in Docker Alpine image for passive nagios check

In the Alpine linux package site https://pkgs.alpinelinux.org/packages
NSCA packages are yet to get added. Is there an alternative to setup NSCA in Alpine Linux for passive-check?
If there is no package for it, you can always build it yourself.
FROM alpine AS builder
ARG NSCA_VERSION=2.9.2
RUN apk update && apk add build-base build-base gcc wget git
RUN wget http://prdownloads.sourceforge.net/nagios/nsca-$NSCA_VERSION.tar.gz
RUN tar xzf nsca-$NSCA_VERSION.tar.gz
RUN cd nsca-$NSCA_VERSION&& ./configure && make all
RUN ls -lah nsca-$NSCA_VERSION/src
RUN mkdir -p /dist/bin && cp nsca-$NSCA_VERSION/src/nsca /dist/bin
RUN mkdir -p /dist/etc && cp nsca-$NSCA_VERSION/sample-config/nsca.cfg /dist/etc
FROM alpine
COPY --from=builder /dist/bin/nsca /bin/
COPY --from=builder /dist/etc/nsca.cfg /etc/
Since this is using multiple stages, your resulting image will not contain development files and will still be small.

Unable to use make in alpine image

I cant get make to work in alpine
make update_tools works when I run it on my OSX, but when i run it in the alpine image i get the following error:
make: *** No rule to make target 'update_tools'. Stop.
Here is what my Dockerfile looks like now:
#Download base image Alpine-3.9 Golang 1.12
FROM golang:1.12-alpine3.9
# Set Working Directory is /usr/app
WORKDIR /usr/app
# Install Alpine Dependencies
RUN apk update && apk upgrade && apk add --update alpine-sdk && \
apk add --no-cache bash git openssh make cmake
COPY cosmos-sdk .
WORKDIR /usr/app/cosmos-sdk
RUN git checkout v0.33.0 && \
make update_tools && \
make vendor-deps && \
make install && \
gaiad init $(whoami) && \
rm .gaiad/config/genesis.json && \
curl https://raw.githubusercontent.com/cosmos/launch/master/genesis.json > $HOME/.gaiad/config/genesis.json
#Add persistent peer to config.toml file
RUN sed -i '' 's/persistent_peers = ""/persistent_peers = "89e4b72625c0a13d6f62e3cd9d40bfc444cbfa77#34.65.6.52:26656"/' $HOME/.gaiad/config/config.toml
#Start gaid daemon and set logging to info
CMD ["gaiad start --log_level="*:info""]
# Expose the ports
EXPOSE 26656 26657
Makefile: https://github.com/cosmos/cosmos-sdk/blob/develop/Makefile
I would appreciate any pointers on this
Am having this issue.
It seems something from the golang-alpine image itself.
** --- Solution --- **
just install the make in your image as following:
apk add --no-cache make
Direct clone and checkout v0.33.0 doesn't have mentioned problem. It looks like a problem with git checkout v0.33.0 command. Probably you have uncommitted changes. Please check/provide docker build output.
had a similar issue, make sure your Makefile is added to the docker image, mine Makefile was added to .dockerignore file, so it was not present in docker image and I got a similar error message

Perl installation issue using Docker

I am trying to build the docker image with perl installation.
Dockerfile:
FROM amazonlinux
WORKDIR /shared
RUN yum -y install gcc
ADD http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz /shared
RUN tar -xzf perl-5.22.1.tar.gz
WORKDIR /shared/perl-5.22.1
RUN ./Configure -des -Dprefix=/opt/perl-5.22.1/localperl
RUN make
RUN make test
RUN make install
all these steps are executed i am can see it executing the make, make test and make install commands but when i do :
docker run -it testsh /bin/bash
Error:
when I check perl -v it says command not found.
and I need to go the perl directory
'cd perl-5.22.1' and run 'make install' again then perl -v works
But I want the perl installation to work when I build it with docker image. can anyone tell me what is going wrong here?
perl was indeed installed, just wasn't added to the path.
export PATH=$PATH:/shared/perl-5.22.1 should do it -- but of course, you'd want to add a PATH update in the Dockerfile.
At first glance I thought that when you run make install second time, it adds perl's bin directory to PATH env, but when I compared output of env before and after make install it showed the same PATH variable content.
The reason you getting perl -v working after make install in running container is that make install puts perl binary to /usr/bin/perl. I don't know why it works such way, but it is just as it is. Also, it's almost useless to store sources inside of your image.
Anyway, I agree with #belwood suggestion about adding your perl's bin directiry to PATH environment variable. I just wanna correct the path: /opt/perl-5.22.1/localperl/bin
You need to add it in your Dockerfile (basically I've rewritten your file to make it produce more efficient image), for example:
FROM amazonlinux
RUN mkdir -p /shared/perl-5.22.1
WORKDIR /shared/perl-5.22.1
RUN yum -y install gcc \
&& curl -SL http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz -o perl-5.22.1.tar.gz \
&& tar --strip-components=1 -xzf perl-5.22.1.tar.gz \
&& rm perl-5.22.1.tar.gz \
&& ./Configure -des -Dprefix=/opt/perl-5.22.1/localperl \
&& make -j $(nproc) \
&& make -j $(nproc) test \
&& make install \
&& rm -fr /shared/perl-5.22.1 /tmp/*
ENV PATH="/opt/perl-5.22.1/localperl/bin:$PATH"
WORKDIR /root
CMD ["perl","-de0"]
When you simply run container with this image, you'll immediately get into perl's shell. If you need bash, then use docker run -it --rm amazon-perl /bin/bash
It would be also good to look at Environment replacement section in the Dockerfile reference documentation, just to figure out how things work. For example, it isn't a best pratice to have that many RUN lines in your Dockerfile because of the RUN instruction will execute commands in a new layer on top of the current image and commit the results. So you'll get many unnecessary layers.

Resources