The ultimate guide to writing dockerfiles for Go Web-apps

Source: Internet
Author: User
Tags docker run
This is a creation in Article, where the information may have evolved or changed. You might want to use Go in Docker for the following reasons: 1. If you want to run on Kubernetes, packaging for mirroring is a must (just like me) 2. You have to run a different Go version 3 on the same machine. Development and production require accurate, replicable, shareable, and defined environments 4. You need a quick and easy way to build and deploy a compiled binary file in 5. You want to get started fast (anyone with Docker can start writing code directly without having to set other dependencies or ' Gopath ' environment variables) Congratulations, you've come to the right place. We will gradually build a basic Dockerfile, including * * real-time Reload * * and * * Package management * *, and then expand to create a highly * * * * production version of the image, its size is reduced by 100 times times. If you use the CI/CD system, the image size may not matter, but a thin image will certainly help when ' Docker push ' and ' Docker pull '. If you only want the final code, see [GitHub] (https://github.com/shahidhk/go-docker/blob/master/src/main.go). "' Bashfrom Golang:1.8.5-jessie as builder# install xzrun apt-get update && apt-get install-y \ xz-utils \&&A mp rm-rf/var/lib/apt/lists/*# Install Upxadd https://github.com/upx/upx/releases/download/v3.94/upx-3.94-amd64_ Linux.tar.xz/usr/localrun xz-d-c/usr/local/upx-3.94-amd64_linux.tar.xz | \ tar-xof-upx-3.94-amd64_linux/upx >/bin/upx && \ chmod a+x/bin/upx# install gliderun go get github.com/ma sterminds/glide# setup the working directoryworkdir/go/src/appadd glide.Yaml glide.yamladd glide.lock glide.lock# Install dependenciesrun glide install# Add source codeadd src src# Build the Sou Rcerun Go build src/main.gorun cgo_enabled=0 goos=linux go build-a-installsuffix cgo-o main src/main.go# strip and comp Ress the Binaryrun strip--strip-unneeded mainrun upx main# use a minimal alpine imagefrom alpine:3.7# add ca-certificates Need Themrun apk add--no-cache ca-certificates# set working directoryworkdir/root# copy the binary from Bui Ldercopy--from=builder/go/src/app/main. # Run the Binarycmd ["./main"] "If our application is called ' Go-docker ', the following is the structure of the project. All the source code is in the ' src ' directory, ' Dockerfile ' with it in the same level directory. ' Main.go ' defines a web-app and listens on port 8080. "Go-docker├──dockerfile└──src└──main.go" # # simplest version of ' Bashfrom golang:1.8.5-jessie# create a working directoryworkdir/go/src/app# Add source codeadd src src# run main.gocmd ["Go", "Run", "Src/main.go"] "' We use ' Debian Jessi E ' version of the Golang image, because commands like ' go get ' need to have tools such as ' Git ' installed. For the production version, we will use a lighter version, such as ' Alpine '. Build and run the image: "' bash$ CD go-docker$ Docker build-t Go-docker-dev. $ docker Run--rm-it-p 8080:8080 Go-docker-dev "" After success can be through ' http://localhost:8 080 ' to access. Press ' CTRL + C ' to interrupt the service. But that doesn't make much sense, because we have to build and run the Docker image every time we modify the code. A better version is to mount the source code in a Docker container and use the shell inside the container to stop and start ' go run '. "' bash$ CD go-docker$ Docker build-t Go-docker-dev. $ docker Run--rm-it-p 8080:8080-v $ (pwd):/go/src/app \ Go-docker -dev bashroot@id:/go/src/app# Go run src/main.go "This command will provide a shell where we can execute ' go run src/main.go ' to start the service. We can edit ' Main.go ' on the host and rerun the command to see the changes because the source code is now mounted directly into the container. But how do you manage the package? # # Package Management and Mirroring tiering [Go Package Management] (Https://github.com/golang/go/wiki/PackageManagementTools) is still in the experimental phase. There are many tools to choose from, but my favorite is [Glide] (https://glide.sh/). We will install Glide in the container and use it. Create two new files in ' Go-docker ' project ' Glide.yaml ' and ' glide.lock ': ' bash$ CD go-docker$ touch glide.yaml$ Touch glide.lock ' modify D as shown below Ockerfile and build a new Image: "Bashfrom golang:1.8.5-jessie# install gliderun go get github.com/masterminds/glide# Create a Working directoryworkdir/go/src/app# add Glide.yaml and Glide.lockadd Glide.yaml glide.yamladd glide.lock glide.lock# Install packagesrun glide install# Add source codeadd src src# run main.g ocmd ["Go", "Run", "Src/main.go"] "" If you observe more carefully, you will find that ' glide.yaml ' and ' glide.lock ' are added separately (and do not use ' Add. . '), which causes separate layers to be separated. Separating package management into a separate layer allows you to take advantage of the cache of the Docker layer and only cause recompilation if the corresponding file changes, such as adding or removing a package. Therefore, ' glide install ' will not be executed after each modification of the code. Let's go into the shell of the container to install a package: "' bash$ CD go-docker$ Docker build-t go-docker-dev." Docker run--rm-it-v $ (PWD):/go/src/app go- Docker-dev bashroot@id:/go/src/app# Glide Get Github.com/golang/glog ' glide will install all packages into ' vendor ' directory, which can be ' gitignored ' and ' Dockerignored '. Use ' Glide.lock ' to lock the version of a package. To install (or reinstall) all the packages mentioned in ' Glide.yaml ', execute: ' bash$ CD go-docker$ Docker run--rm-it-p 8080:8080-v $ (pwd):/go/src/app \ Go-docke R-dev bashroot@id:/go/src/app# Glide Install ' Now ' go-docker ' directory has grown: '. ├──dockerfile├──glide.lock├──glide.yaml├── src│└──main.go└──vendor/' # # Real-time Reload [Codegangsta/gin] (Https://github.com/codegangsta/gin) is my favorite real-time reload tool. It's simply a Go Web service. We use ' Go ge 'T ' to install gin: ' bashfrom golang:1.8.5-jessie# install gliderun go get github.com/masterminds/glide# install ginrun go get GI thub.com/codegangsta/gin# Create a working directoryworkdir/go/src/app# add Glide.yaml and Glide.lockadd Glide.yaml glid E.yamladd glide.lock glide.lock# Install packagesrun glide install# Add source codeadd src src# run main.gocmd ["Go", "run "," Src/main.go "]" "builds the image and runs gin so that we can automatically recompile when we modify the source code in ' src ': ' bash$ cd go-docker$ Docker build-t Go-docker-dev. $ dock Er run--rm-it-p 8080:8080-v $ (pwd):/go/src/app \ Go-docker-dev bashroot@id:/go/src/app# gin--path src--port 8080 run Main.go ' Note that Web-server needs a ' port ' environment variable to listen, because gin will randomly set the ' port ' variable and proxy the connection to that port. Now, modifying the contents of the ' src ' directory will trigger recompilation, and all updated content can be accessed in real time on ' http://localhost:8080 '. Once the development is complete, we can build the binaries and run it without the need to use the ' Go Run ' command. You can use the same image to build, or you can use Docker's multi-stage build, which uses the ' Golang ' image to build and run the service using a mini Linux container such as ' Alpine '. # # Single Stage production build ' Bashfrom golang:1.8.5-jessie# install gliderun go get github.com/masterminds/glide# create a working directoryworkdir/go/src/app# add Glide.yaml and Glide.lockadd glide.yaml glide.yamladd glide.lock glide.lock# Install Packag Esrun Glide install# Add source codeadd src src# build main.gorun Go build src/main.go# run the Binarycmd ["./main"] "' Build and Run the integrated Image: ' bash$ cd go-docker$ Docker build-t Go-docker-prod. ' Docker run--rm-it-p 8080:8080 Go-docker-prod ' ' because the underlying makes With a Debian image, the image will reach about the size of about a half MB (depending on your source code). Let's see how to reduce the volume. # # Multi-stage production build multi-stage build allows you to build in a full OS environment, but the built-in binaries run through a very slim image that is only slightly larger than the built binaries. "' Bashfrom Golang:1.8.5-jessie as builder# install gliderun go get github.com/masterminds/glide# setup the working direct Oryworkdir/go/src/appadd glide.yaml glide.yamladd glide.lock glide.lock# Install dependenciesrun glide install# Add sour Ce codeadd src src# build the Sourcerun go build src/main.gorun cgo_enabled=0 goos=linux go build-a-installsuffix cgo-o Main src/main.go# use a minimal alpine Imagefrom alpine:3.7# add Ca-certificates in case you need themrun apk update &amp ;& apkAdd Ca-certificates && rm-rf/var/cache/apk/*# set working directoryworkdir/root# copy the binary from Builderco PY--from=builder/go/src/app/main. # Run the Binarycmd ["./main"] "Now the binary file is about MB, and the Docker image is about MB. Thanks to the ' Alpine '. Want to reduce the volume of the binary file? Keep looking. # # Benefits: Using UPX to compress binaries in [Hasura] (https://hasura.io/), we are already using [UPX] (https://upx.github.io/) everywhere, compressed our CLI binary files from about two MB To about 8 MB, greatly speeding up the download speed. The UPX can be decompressed in place very quickly, without the need for additional tools because it embeds the decompressor inside the binary file. "' Bashfrom Golang:1.8.5-jessie as builder# install xzrun apt-get update && apt-get install-y \ xz-utils \&&A mp rm-rf/var/lib/apt/lists/*# Install Upxadd https://github.com/upx/upx/releases/download/v3.94/upx-3.94-amd64_ Linux.tar.xz/usr/localrun xz-d-c/usr/local/upx-3.94-amd64_linux.tar.xz | \ tar-xof-upx-3.94-amd64_linux/upx >/bin/upx && \ chmod a+x/bin/upx# install gliderun go get github.com/ma sterminds/glide# setup The Working directoryworkdir/go/src/appadd Glide.yaml glide.yamladd Glide.lock glide.lock# Install Dependenciesrun Glide install# Add source codeadd src src# Build the Sourcerun go build src/main.gorun cgo_enabled=0 go Os=linux go build-a-installsuffix cgo-o main src/main.go# strip and compress the Binaryrun strip--strip-unneeded Mainr UN UPX main# Use a minimal alpine Imagefrom alpine:3.7# add Ca-certificates in case you need themrun apk update && APK add ca-certificates && rm-rf/var/cache/apk/*# set working directoryworkdir/root# copy the binary from Buil Dercopy--from=builder/go/src/app/main. # Run the Binarycmd ["./main"] "UPX the compressed binary file is about 3 MB and the Docker image is about 6 MB. * * reduced by 100 times times compared to the initial image * * If you have a better suggestion or if you need other usage scenarios, please leave a comment in the comments section or go to [hackernews] (https://news.ycombinator.com/item?id=16308391 ) and [Reddit] (https://www.reddit.com/r/golang/comments/7vexdl/the_ultimate_guide_to_writing_dockerfiles_for_go/) For discussion. # # Advertising Amount ... Have you tried to deploy Go Web-app on Hasura? This is really the fastest way to deploy go apps to the HTTPS domain (just ' git push ' is enough). Use the project template here to get started quickly: Https://hasura.io/hub/go-frameworks. Hasura all project templates are equipped with DOckerfile and Kubernetes spec, allows you to customize it in your way.

via:https://blog.hasura.io/the-ultimate-guide-to-writing-dockerfiles-for-go-web-apps-336efad7012c

Author: Shahidh K Muhammed Translator: Paradeto proofreading: polaris1119

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

625 Reads
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.