Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create a static binary in go and put it in a from scratch docker container
FROM golang:1.9
WORKDIR /go/src/github.com/purplebooth/example
COPY . .
RUN go build -ldflags "-linkmode external -extldflags -static" -a main.go
FROM scratch
COPY --from=0 /go/src/github.com/purplebooth/example/main /main
CMD ["/main"]
@PurpleBooth
Copy link
Author

PurpleBooth commented Sep 14, 2017

$ docker images --format "{{ .Size }} {{ .Repository }}:{{ .Tag }}" test
3.54MB test:latest

Pretty neat!

@janekolszak
Copy link

janekolszak commented Jan 23, 2018

Thank you soooo much for this!
It's just beautiful, I had to build separate containers and make a mess to do the same thing.

@emmiep
Copy link

emmiep commented May 15, 2018

I think I understand -ldflags, it seems like it's used to make use of gnu ld which can use the -static flag to build a static library, but I don't understand why -a is needed (other examples use it as well).

According to the docs it "force(s) rebuilding of packages that are already up-to-date.".
Is it because some built packages aren't built in a way that works when linking statically?

@ChristianKniep
Copy link

ChristianKniep commented Jun 3, 2018

Just stole this nice little dockerfile for a pet-project. Thanks for putting it out.
Btw: you do not need the first RUN to create the directory. WORKDIR will do that for you if it does not exist. :)

@whatever
Copy link

whatever commented Dec 17, 2018

💯 this is really useful to know (especially when first messing with docker)

@liampulles
Copy link

liampulles commented Jun 17, 2019

Really useful!

@MajorWalrus
Copy link

MajorWalrus commented Jul 27, 2019

This is exactly what I needed. Thank you!

@PurpleBooth
Copy link
Author

PurpleBooth commented Aug 7, 2019

@ChristianKniep wrote:

Just stole this nice little dockerfile for a pet-project. Thanks for putting it out.
Btw: you do not need the first RUN to create the directory. WORKDIR will do that for you if it does not exist. :)

Ooh! Didn't know that! Updated 👍

@liao02x
Copy link

liao02x commented Nov 16, 2019

Got this error when trying to run the container. Any idea? docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"./main\": permission denied": unknown.

@PurpleBooth
Copy link
Author

PurpleBooth commented Nov 16, 2019

Does main exist? The example copies to /main from the build container rather than ./main

Here's another similar example

@liao02x
Copy link

liao02x commented Nov 17, 2019

Does main exist? The example copies to /main from the build container rather than ./main

Here's another similar example

Thanks for your help. Sorry it was a mistake when I was messing up with WORKDIR. I put my app in the directory /main, so actually I have to run /main/main.

But there's also a lesson I learned and want to share: docker would not tell you main is a directory like bash do when you try to execute a directory, so if you got the permission denied error, you know there's another thing to check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment