
Dockerizing a Golang application can be a straightforward process if you follow a few simple steps. The first step is to create a new file named Dockerfile in the root of your project directory.
This file will contain the instructions for building your Docker image. You can start by specifying the base image for your application, such as the official Golang image. In the article section "Choosing the Base Image", we discussed the benefits of using the official Golang image.
The FROM instruction is used to specify the base image. For example, you can use the following instruction to use the official Golang image: FROM golang:alpine. This will ensure that your application has the necessary dependencies and tools to run.
In the "Writing the Dockerfile" section, we went over the different instructions that can be used in a Dockerfile. One of the most important instructions is the WORKDIR instruction, which is used to set the working directory for your application.
For more insights, see: Golang Use .env File
Setting Up Our Environment
To set up our environment for working with Go and Docker, we need to install the following: Go version ≥ 1.16, Docker running locally, and an IDE or text editor.
We'll be using macOS, so let's download and install Go first by clicking the .pkg file and extracting the Go package on our system path.
To confirm the Go version, we can run the command `go version` in our terminal.
Next, we'll proceed to download and install the Docker desktop on our local machine.
To confirm we have Docker installed on our system, we can run the command `docker --version` in our terminal.
Now that we have Go and Docker set up, let's create a new folder and name it go-demo on any path on our local machine.
We'll navigate into the directory and run the command `go mod init` to spin up a new Go module.
Inside our project folder, we'll create a file named main.go and paste the following code into it.
To test that the code runs as expected, we can run the command `go run .` or `go run main.go` from the terminal.
See what others are reading: Add Golang to Path
Building Docker Image
Building a Docker image is a crucial step in deploying your Golang application. You can build a Docker image from a Dockerfile using the `docker build` command.
The build command optionally takes a `--tag` flag, which is used to label the image with a string value, making it easier for humans to read and recognize. If you don't pass a `--tag`, Docker will use `latest` as the default value.
To build your Docker image, run the `docker build` command from the root directory of your project. This will create a Docker image for your backend.
Here are the basic steps to build a Docker image:
- Use the `docker build` command
- Optionally specify a `--tag` flag to label the image
- Run the command from the root directory of your project
- Docker will create a Docker image for your backend
A Docker image contains configuration for a Docker container, such as environment variables, a default command to run, and other metadata. An image should also have everything you need to run an application, including the code or binary, runtime, dependencies, and any other file system objects required.
If this caught your attention, see: Docker and Golang
To build an image, you can use the `docker build` command with the `-t` flag to specify a tag for the image. For example: `docker build -t myimage .`
This will create a Docker image with the tag `myimage` in the current directory. You can verify that the image has been created by running `docker images`, which will list all the images on your system, including the one you just created.
Here are the common options used with the `docker build` command:
- `-t`: Specify a tag for the image
- `-f`: Specify the path to the Dockerfile
- `.`: Specify the context for the build process
These options can be used to customize the build process and create Docker images that meet your specific needs.
Multi-Stage Builds
Multi-Stage Builds are a game-changer for GoLang applications. They let you define multiple stages inside one Dockerfile, which means you can throw away everything that isn’t needed to run your app.
One stage contains the full build environment, including compilers, Git, and the Go toolchain. This is useful for complex builds that require a lot of dependencies.
By splitting the build process into multiple stages, Docker can leverage its caching mechanism effectively. This can dramatically speed up the build process, especially for iterative development.
Here are the benefits of Multi-Stage Builds in GoLang:
- Smaller Docker Images: By leveraging multi-stage builds, we can create a minimalistic final image that only contains the necessary runtime dependencies for our GoLang application.
- Improved Security: In multi-stage builds, the final stage can exclude all the build-time tools and dependencies, leaving only the runtime components required to run the application.
- Faster Builds: By splitting the build process into multiple stages, Docker can leverage its caching mechanism effectively.
Dockerizing Application
Dockerizing a Golang application is a straightforward process. You start by creating a simple Golang application that acts as a REST API.
To create a Dockerfile for development, you'll need to create a new file named Dockerfile.dev. In this file, you'll paste a series of commands that will help you build and run your application.
A Dockerfile for development typically includes commands such as `RUN go get` and `CMD ["go", "run", "./main.go"]`. These commands ensure that your application is built and run correctly within the container.
To build a Docker image, you'll use the `docker build` command. This command takes several options, including `-f` (path to the Dockerfile), `-t` (name and tag for the image), and `.` (context for the build process).
For another approach, see: Golang Build
Here are the basic options you'll need to build a Docker image:
- -f: Path to the Dockerfile
- -t: Name and tag for the image
- .: Context for the build process
Once you've built your Docker image, you can create a container from it using the `docker run` command. This command takes several options, including `-d` (run container in background and print container ID), `-it` (create an interactive container), `-p` (map host port to container port), `--name` (assign a name to the container), and `--rm` (remove the container when it exits).
Here are the basic options you'll need to create a container:
- -d: Run container in background and print container ID
- -it: Create an interactive container
- -p: Map host port to container port
- --name: Assign a name to the container
- --rm: Remove the container when it exits
To verify whether the container has been created successfully, you can run the `docker ps` command. This command will list all the running containers on your system.
Finally, to access your application, you'll need to navigate to the URL specified in the Dockerfile, such as `http://localhost:5001/`.
Build and Final Stages
Building a Docker image for your GoLang application requires careful planning, especially when it comes to the build and final stages.
To create a minimalistic final image, you can use multi-stage builds, which let you define multiple stages inside one Dockerfile. This approach is particularly useful for GoLang applications, as it allows you to create a smaller Docker image that only contains the necessary runtime dependencies.
In a multi-stage build, you can have one stage contain the full build environment and another stage contain only the final binary and runtime dependencies. By leveraging this approach, you can reduce the image size, leading to faster and more efficient deployments.
Here are the key steps to follow in the build stage:
- Use the official Go image with Alpine Linux as the base: `FROM golang:1.25-alpine`
- Set the working directory inside the container to `/app`: `WORKDIR /app`
- Ensure the binary is built for Linux with CGO disabled: `ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64`
- Copy only the dependency files first: `COPY go.mod go.sum ./`
- Copy the entire application source code into the container: `COPY . .`
- Compile the Go application and produce a binary named `myapp`: `RUN go build -trimpath -ldflags="-s -w" -o myapp .`
In the final stage, you can create a fresh, minimal Alpine Linux image and install only the runtime dependencies needed for your Go app. This includes installing `ca-certificates` and `tzdata` using `apk add --no-cache`. You can also create a dedicated non-root user for running the app using `adduser` and `addgroup`.
Here are the key steps to follow in the final stage:
- Start a fresh, minimal Alpine Linux image: `FROM alpine:latest`
- Install only the runtime dependencies needed for your Go app: `RUN apk add --no-cache ca-certificates tzdata`
- Create a dedicated non-root user for running the app: `RUN addgroup -S appuser && adduser -S -G appuser -H -s /sbin/nologin appuser`
- Copy the built binary from the builder stage into the final image: `COPY --from=builder --chown=appuser:appuser /app/myapp /app/myapp`
- Ensure the app runs as a non-root user inside the container: `USER appuser`
- Define the binary as the container's entrypoint: `ENTRYPOINT ["/app/myapp"]`
Featured Images: pexels.com


