How to run go server on docker from binary - docker

I have been trying to make a Dockerfile, that would let me build my go server as binary and then run it either from the scratch image or alpine. The server works fine locally, on macOS 10.13.5, and I made it work when it wasn't from binary on Docker.
I keep getting this error:
standard_init_linux.go:190: exec user process caused "exec format error"
I have been googling around and found something about system architecture. I am not sure how to check if that is the error and/or how to fix it.
Any hints for debugging or possible fix are much appreciated.
My Dockerfile:
FROM golang:1.10.3 as builder
WORKDIR /go/src/gitlab.com/main/server
COPY . .
RUN go get -d -v ./...
RUN CGO_ENABLED=0 GOOS=linux go build -a -o main .
FROM scratch
ADD main /
CMD ["/main"]
The output:
Building go
Step 1/9 : FROM golang:1.10.3 as builder
---> 4e611157870f
Step 2/9 : WORKDIR /go/src/gitlab.com/main/server
Removing intermediate container 20cd4d66008b
---> 621d9fc02dde
Step 3/9 : COPY . .
---> cab639571baf
Step 4/9 : RUN go get -d -v ./...
---> Running in 7681f9adc7b2
Removing intermediate container 7681f9adc7b2
---> 767a4c9dfb94
Step 5/9 : RUN go build -a -installsuffix cgo -o main .
---> Running in a6ec73121163
Removing intermediate container a6ec73121163
---> b9d7d1c0d2f9
Step 6/9 : FROM alpine:latest
---> 11cd0b38bc3c
Step 7/9 : WORKDIR /app
---> Using cache
---> 6d321d334b8f
Step 8/9 : COPY . .
---> 048a59fcdd8f
Step 9/9 : CMD ["/app/main"]
---> Running in d50d174644ff
Removing intermediate container d50d174644ff
---> 68f8f3c6cdf7
Successfully built 68f8f3c6cdf7
Successfully tagged main_go:latest
Creating go ... done
Attaching to go
go | standard_init_linux.go:190: exec user process caused "exec format error"
go exited with code 1

As #tgogos pointed out did I need to use what I build in the first step.
My final Dockerfile ended like this with a few further improvements: The important part is second last line though:
FROM golang:1.10.3 AS build
WORKDIR /go/src/gitlab.com/main/server
COPY . .
RUN go get github.com/golang/dep/cmd/dep && \
dep ensure && \
rm -f schema/bindata.go && \
go generate ./schema
RUN CGO_ENABLED=0 GOOS=linux go build -a -o main .
FROM alpine
RUN apk add --no-cache ca-certificates
COPY --from=build /go/src/gitlab.com/main/server/main .
CMD ["/main"]

Related

Docker build not using cache

When I run
docker build -f docker/webpack.docker services/webpack --build-arg env=production
twice in a row, Docker builds my image each time, starting from the first RUN (the COPY uses the cache).
FROM node:lts
ARG env=production
ENV NODE_ENV=$env
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --production=false --non-interactive
COPY . .
RUN node --max-old-space-size=20000 node_modules/.bin/svg2fonts icons -o assets/markons -b mrkn -f markons -n Markons
RUN node --max-old-space-size=20000 node_modules/.bin/webpack --progress
How can I get it to cache those RUNs?
Output looks like:
Sending build context to Docker daemon 3.37MB
Step 1/9 : FROM node:lts
---> 0c601cba9f11
Step 2/9 : ARG env=production
---> Using cache
---> dd38b2167c75
Step 3/9 : ENV NODE_ENV=$env
---> Using cache
---> 800f5afd416c
Step 4/9 : WORKDIR /app
---> Using cache
---> d15b93dce11d
Step 5/9 : COPY package.json yarn.lock ./
---> Using cache
---> a049dd1609a8
Step 6/9 : RUN yarn install --frozen-lockfile --production=false --non-interactive
---> Using cache
---> d5e51b0d556c
Step 7/9 : COPY . .
---> 92990e326d4b
Step 8/9 : RUN node --max-old-space-size=20000 node_modules/.bin/svg2fonts icons -o assets/markons -b mrkn -f markons -n Markons
---> Running in a23878db7b0e
Wrote assets/markons/markons.css
Wrote assets/markons/markons.js
Wrote assets/markons/markons.html
Wrote assets/markons/markons-chars.json
Wrote assets/markons/markons.svg
Wrote assets/markons/markons.ttf
Wrote assets/markons/markons.woff
Wrote assets/markons/markons.woff2
Wrote assets/markons/markons.eot
Removing intermediate container a23878db7b0e
---> 3bce79d0ecf0
Step 9/9 : RUN node --max-old-space-size=20000 node_modules/.bin/webpack --progress
---> Running in b6d460488950
<s> [webpack.Progress] 0% compiling
...
See the description:
If the contents of all external files on the first COPY command are
the same, the layer cache will be used and all subsequent commands
until the next ADD or COPY command will use the layer cache.
However, if the contents of one or more external files are different,
then all subsequent commands will be executed without using the layer
cache.
So every time the content is changed two last RUN will be executed with no cache. There is no way to control caching yet. Maybe it's a better option to specify volumes?

.NET Core web app won't run in Docker container

I have a vanilla .NET Core 2 web app that I setup in JetBrains Rider and I immediately started working on a Docker environment for it. I followed this guide to get started:
https://docs.docker.com/engine/examples/dotnetcore/
I altered it slightly to come up with this:
FROM microsoft/dotnet:latest AS packager
RUN mkdir -p /opt/build
WORKDIR /opt/build
# Copy csproj and restore as distinct layers
COPY *.csproj .
RUN dotnet restore
# Copy everything else and build
COPY . .
RUN dotnet publish -c Release -o bin
# --
# Build runtime image
FROM microsoft/dotnet:runtime AS runtime
RUN mkdir -p /opt/app
WORKDIR /opt/app
COPY --from=packager /opt/build/bin/. .
ENTRYPOINT ["dotnet", "/opt/app/aspnetapp.dll"]
The image builds and when I go to run the container I get the following output:
dan#mycomputer ~/Desktop/coreapi (master)
$ docker build -t myapp .
Sending build context to Docker daemon 25.09kB
Step 1/12 : FROM microsoft/dotnet:latest AS packager
---> e1a56dca783e
Step 2/12 : RUN mkdir -p /opt/build
---> Using cache
---> 95f9c936d0d1
Step 3/12 : WORKDIR /opt/build
---> Using cache
---> 64f26c356fd7
Step 4/12 : COPY *.csproj .
---> Using cache
---> 38a2fb7ca6bb
Step 5/12 : RUN dotnet restore
---> Using cache
---> 70dbc44d98ae
Step 6/12 : COPY . .
---> Using cache
---> b1019d53a861
Step 7/12 : RUN dotnet publish -c Release -o bin
---> Using cache
---> 8e112606633a
Step 8/12 : FROM microsoft/dotnet:runtime AS runtime
---> cc240a7fd027
Step 9/12 : RUN mkdir -p /opt/app
---> Using cache
---> 954f494febc4
Step 10/12 : WORKDIR /opt/app
---> Using cache
---> b74be941e7dc
Step 11/12 : COPY --from=packager /opt/build/bin/. .
---> Using cache
---> 4c229192d99b
Step 12/12 : ENTRYPOINT ["dotnet", "/opt/app/aspnetapp.dll"]
---> Using cache
---> fb6ef4015fba
Successfully built fb6ef4015fba
Successfully tagged myapp:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
dan#mycomputer ~/Desktop/coreapi (master)
$ docker run -p 5001:5001 myapp:latest
Did you mean to run dotnet SDK commands? Please install dotnet SDK from:
http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
The app doesn't run and I get a message that says I need to install the SDK. What's up with that? Shouldn't the runtime Docker image have everything neede to run the app?
I was able to find the solution by modifying the ENTRYPOINT to run tail -f /dev/null. From there, I entered the container and saw that the name of the binary adjusts based on your project name which the Docker documentation didn't make clear to me.
I also updated my base images and this solved my problem. Here is my latest Dockerfile below:
FROM microsoft/dotnet:2.1-sdk AS packager
RUN mkdir -p /opt/build
WORKDIR /opt/build
# Copy csproj and restore as distinct layers
COPY *.csproj .
RUN dotnet restore
# Copy everything else and build
COPY . .
RUN dotnet publish -c Release -o bin
# --
# Build runtime image
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime
RUN mkdir -p /opt/app
WORKDIR /opt/app
COPY --from=packager /opt/build/bin/. .
EXPOSE 80
ENTRYPOINT ["dotnet", "/opt/app/coreapi.dll"]

When build beego docker image with default docker file, show error: `godep: No Godeps found (or in any parent directory)`

I'm new to Go & Beego.
When I build docker image with beego's default docker file, it shows this error :
godep: No Godeps found (or in any parent directory)
The build info is:
Sending build context to Docker daemon 13.6MB
Step 1/9 : FROM library/golang
---> 138bd936fa29
Step 2/9 : RUN go get github.com/tools/godep
---> Running in 9003355d967f
---> bae9e4289f9b
Removing intermediate container 9003355d967f
Step 3/9 : RUN CGO_ENABLED=0 go install -a std
---> Running in 63d367bd487e
---> 3ce0b2d47c0a
Removing intermediate container 63d367bd487e
Step 4/9 : ENV APP_DIR $GOPATH/src/TestProject
---> Running in 53ddc4661a07
---> 528794352eb0
Removing intermediate container 53ddc4661a07
Step 5/9 : RUN mkdir -p $APP_DIR
---> Running in 37718f358f5c
---> ef9332ca086c
Removing intermediate container 37718f358f5c
Step 6/9 : ENTRYPOINT (cd $APP_DIR && ./TestProject)
---> Running in 059c06321914
---> 8538ea070871
Removing intermediate container 059c06321914
Step 7/9 : ADD . $APP_DIR
---> df129482c662
Step 8/9 : RUN cd $APP_DIR && CGO_ENABLED=0 godep go build -ldflags '-d -w -s'
---> Running in 50b29d1307b5
godep: No Godeps found (or in any parent directory)
The command '/bin/sh -c cd $APP_DIR && CGO_ENABLED=0 godep go build -ldflags '-d -w -s'' returned a non-zero code: 1
The solution is very simple: run godep save in your project locally, and you will go a new folder Godeps in your project. it contains file:Godeps.json. After this, run docker build . again, you will got your docker image.

Docker glide not found

Docker is not able to find glide, which was installed successfully in steps 3 and 4 (below). I ran
docker build .
This is the first part of the Dockerfile:
FROM golang:latest as builder
# Set up workdir
WORKDIR /go/src/github.com/cayleygraph/cayley
# Restore vendored dependencies
RUN sh -c "curl https://glide.sh/get | sh"
COPY glide.* ./
RUN glide install
But it failed on step 5 with this error:
docker build .
Sending build context to Docker daemon 65.18MB
Step 1/29 : FROM golang:latest as builder
---> 1a34fad76b34
Step 2/29 : WORKDIR /go/src/github.com/cayleygraph/cayley
---> Using cache
---> dd9a295edeed
Step 3/29 : RUN sh -c "curl https://glide.sh/get | sh"
---> Using cache
---> b432efdb0630
Step 4/29 : COPY glide.* ./
---> Using cache
---> 936b9f7837eb
Step 5/29 : RUN glide install
---> Running in b244dcff6576
/bin/sh: 1: glide: not found
The command '/bin/sh -c glide install' returned a non-zero code: 127
Installing glide worked, not sure why it's not finding the actual executable though. Any ideas?
Make glide executable as well, in the Dockerfile. And skip the / in your COPY statement. Try to add this before you try to run it.
RUN chmod +x <file>
Seems like the install process only download the executable

Dockerfile not using cache in RUN composer install command

I thought i understand Docker already, but today i found some problem about utilizing docker cache.
Here is my dockerfile
FROM quay.io/my_company/phpjenkins
WORKDIR /usr/src/my_project
ADD composer.json composer.json
ADD composer.lock composer.lock
RUN composer install -o
ADD . .
RUN mkdir -p temp/unittest/cache log
RUN cp app/config/config.unittest.template.neon app/config/config.unittest.neon
CMD ["tail", "-f", "/dev/null"]
I expect docker to use the cache until ADD . .
However, every build, look like docker try to do composer install every time.
Here is some output
+ docker-compose -f docker-compose.yml run app vendor/bin/phpunit -d memory_limit=2048M
Creating network "xxx_default" with the default driver
Creating xxx_rabbitmq_1
Creating xxx_mysql_1
Building app
Step 1/9 : FROM quay.io/my_company/phpjenkins
---> f10ea65fb7df
Step 2/9 : WORKDIR /usr/src/my_project
---> Using cache
---> 07ad76770cd2
Step 3/9 : ADD composer.json composer.json
---> Using cache
---> 0d22314b81af
Step 4/9 : ADD composer.lock composer.lock
---> Using cache
---> 3d41825efcb3
Step 5/9 : RUN composer install -o
---> Running in 38de5f08eb46
Warning: This development build of composer is over 60 days old. It is recommended to update it by running "/usr/local/bin/composer self-update" to get the latest version.
Do not run Composer as root/super user! See https://getcomposer.org/root for details ....
...
---> aa05dc9ddc5f
Removing intermediate container 581aa7e4b00f
Step 6/9 : ADD . .
---> 8796a9235b9a
Removing intermediate container b7354231fbd7
I run out of lead, what could be possible thing that dockerfile didn't use cache for RUN composer install command
I'm using Docker version 17.05.0-ce, build 89658be on Debian, if this help for investigation.
Please advise.
As a work-around you could create two Dockerfiles. One that creates an image at the point where you would like to cache. The second Dockerfile can then use the first image as its base and make modifications as required.
FROM quay.io/my_company/phpjenkins
WORKDIR /usr/src/my_project
ADD composer.json composer.json
ADD composer.lock composer.lock
RUN composer install -o
CMD ["tail", "-f", "/dev/null"]
Build this file to mycomposerimage using
docker build -t mycomposerimage .
Then second dockerfile picks up from there
FROM mycomposerimage
WORKDIR /usr/src/my_project
ADD . .
RUN mkdir -p temp/unittest/cache log
RUN cp app/config/config.unittest.template.neon app/config/config.unittest.neon
CMD ["tail", "-f", "/dev/null"]

Resources