├── .gitignore ├── Dockerfile ├── Dockerfile.alpine ├── Dockerfile.scratch ├── LICENSE ├── Makefile ├── README.md └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | 26 | app 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # build stage 2 | FROM golang:alpine AS build-env 3 | ADD . /src 4 | RUN cd /src && go build -o app 5 | 6 | # final stage 7 | FROM alpine 8 | WORKDIR /app 9 | COPY --from=build-env /src/app /app/ 10 | ENTRYPOINT ./app 11 | -------------------------------------------------------------------------------- /Dockerfile.alpine: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | WORKDIR /app 3 | ADD . /app 4 | RUN cd /app && go build -o app 5 | ENTRYPOINT ./app 6 | -------------------------------------------------------------------------------- /Dockerfile.scratch: -------------------------------------------------------------------------------- 1 | FROM centurylink/ca-certs 2 | 3 | ADD app / 4 | 5 | ENTRYPOINT ["/app"] 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Bo-Yi Wu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: 3 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app 4 | 5 | scratch: build 6 | docker build -f Dockerfile.scratch -t appleboy/go-app . 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-multi-stage-build 2 | 3 | [Multi-Stage][1] Docker Builds for Creating Tiny Go Images 4 | 5 | [1]:https://github.com/moby/moby/pull/32063 6 | 7 | ## Single-stage build 8 | 9 | See the [Dockerfile.alpine](./Dockerfile.alpine) 10 | 11 | ```dockerfile 12 | FROM golang:alpine 13 | WORKDIR /app 14 | ADD . /app 15 | RUN cd /app && go build -o app 16 | ENTRYPOINT ./app 17 | ``` 18 | 19 | build and run as the following command. 20 | 21 | ```sh 22 | $ docker build -f Dockerfile.alpine -t appleboy/go-app . 23 | $ docker run --rm appleboy/go-app 24 | ``` 25 | 26 | **258 MB**, just for our single little Go binary. 27 | 28 | ## Multi-Stage build 29 | 30 | See the [Dockerfile.alpine](./Dockerfile.alpine) 31 | 32 | ```dockerfile 33 | # build stage 34 | FROM golang:alpine AS build-env 35 | ADD . /src 36 | RUN cd /src && go build -o app 37 | 38 | # final stage 39 | FROM alpine 40 | WORKDIR /app 41 | COPY --from=build-env /src/app /app/ 42 | ENTRYPOINT ./app 43 | ``` 44 | 45 | build and run as the following command. 46 | 47 | ```sh 48 | $ docker build -t appleboy/go-app . 49 | $ docker run --rm appleboy/go-app 50 | ``` 51 | 52 | **6.35 MB**. Much better. 53 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("Hello World!") 7 | } 8 | --------------------------------------------------------------------------------