Dockerize-Go-Application-Easily
When you become a parent, one thing becomes really clear.
And that's that you want to make sure your children feel safe.
There are some ways to deploy your Golang code, especially when you are using Docker to run your executable file of your Go Project. We can create our image from our project, and we can simply run it on your local computer, or even on the deployment by pulling your image from the registry.
Requirement
- docker
- Basic of Go Programming
Repository: https://github.com/david-yappeter/go-dockerfile-example
Getting Started
First, you need to start your docker daemon by using systemctl start docker
or service docker start
, use sudo
if needed.
Then we will create our simple go HTTP code.
Then we will create our simple go HTTP code.
1 | $ mkdir go-dockerfile && cd go-dockerfile |
server.go:
1 | package main |
Our server.go
will contain a simple gin
router and optional godotenv
.
/
path will return “Hello World” and /env
path will return “Hello ${NAME}”.
Dockerfile
there are several ways to write Dockerfile
, but I will make 3 examples with different base images: official golang, alpine, and scratch.
FROM Official Image
1 | FROM golang:1.16-alpine |
In this Dockerfile , we will split it into some sections:
FROM golang:1.16-alpine
, we will use golang:1.16-alpine as the base image of this Docker build.WORKDIR
, will be our working directory of our command/path of our next commands.COPY go.* ./
, we will copygo.mod
&go.sum
file from our project to the working directory.RUN go mod download
, download the project dependencies from go modules.COPY . .
, copy all things from our project into the working directory.RUN go build -o /project/go-docker/build/myapp .
, build our project in the working directory and output it inproject/go-docker/build/myapp
as a binary file.EXPOSE 8080
, telling docker that our code will expose port 8080 .ENTRYPOINT ["/project/go-docker/build/myapp"]
, when we run the container of this image, it will start from our build binary.
Any of these duplicate explanations won’t be explained twice. After this we need to run this command:
1 | docker build -f Dockerfile -t test-go-docker:latest . |
-f
flag is the filename of our Dockerfile .-t
flag is the name of the image later on..
at the end of the command is the directory of the Dockerfile .
Alpine Base Image
1 | FROM golang:1.16-alpine as builder |
The difference from the first one:
FROM golang:1.16-alpine as builder
, we will use golang:1.16-alpine and tag it as builder that later on will be used.FROM alpine:latest
, we will create a new base image from alpine .COPY --from=builder /project/go-docker/build/myapp /project/go-docker/build/myapp
, copy the build binary file into the new alpine image and run it later on.
The image size of thisDockerfile
is way smaller than the previous image.
FROM Scratch
1 | FROM golang:1.16-alpine as builder |
And for the last Dockerfile, we only change the alpine base image into scratch . Scratch is an empty image, so once the container running, we can’t exec into the container because it doesn’t even have a shell command.
The image is slightly smaller than the alpine base image.
try to run the image by using docker run -d -p 8080:8080 test-go-docker:latest
, it will forward port 8080
from the container to our 8080
port and access the http://localhost:8080
.
Conclusions
Personally, I will choose the second Dockerfile . Why? because the size is small and it still has several commands and a shell command so we can docker exec into the container and access it. If we use the scratch base image, it will be hard for us to debug our running container because we can’t exec into it.
That’s all for this article about Docker with Go Programming, hope you have a nice day :).