Docker Basics
Docker is a platform that allows developers to build, ship, and run applications in containers. Containers are lightweight and contain everything needed to run the application, making it easy to deploy and run applications consistently across different environments.
In this guide, we will cover the basics of Docker and how it can be used with Go applications. We will learn how to:
- Create a Dockerfile for a Go application
- Build and run a Go image as a container
- Use multi-stage builds for building small images efficiently
- Use Docker Compose to orchestrate running of multiple related containers together
Prerequisites
To follow this guide, you will need:
- Docker installed on your system
- A basic understanding of Go programming language
Dockerfile
A Dockerfile is a script that contains instructions for building a Docker image. It is used to specify the base image, dependencies, and build steps for the application.
Here is an example of a Dockerfile for a Go application:
# Use an official Golang runtime as a parent image
FROM golang:1.17-alpine AS build-env
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in go.mod
RUN go mod download
# Compile the Go application
RUN go build -o main .
# Use an Alpine Linux runtime as a parent image
FROM alpine:latest
# Copy the Go application from the previous stage
COPY --from=build-env /app/main /usr/local/bin/
# Change the working directory to /app
WORKDIR /app
# Remove any unnecessary packages
RUN apk --no-cache add curl
# Expose port 8080 for the application
EXPOSE 8080
# Run the Go application when the container starts
CMD ["/usr/local/bin/main"]
This Dockerfile uses a multi-stage build to build the Go application in a separate stage from the final image. This allows us to keep the final image small and efficient.
Build Stage
The first stage of the Dockerfile uses the official Golang image as the base image. It sets the working directory to /app and copies the current directory contents into the container. It then installs any needed packages specified in go.mod and compiles the Go application.
Run Stage
The second stage of the Dockerfile uses the Alpine Linux image as the base image. It copies the compiled Go application from the previous stage and sets the working directory to /app. It removes any unnecessary packages and exposes port 8080 for the application. Finally, it sets the CMD to run the Go application when the container starts.
Build and Run the Go Image
Once the Dockerfile is created, we can build the Docker image using the following command:
docker build -t myapp .
This command builds the Docker image using the Dockerfile in the current directory and tags it with the name “myapp”.
Once the image is built, we can run it as a container using the following command:
docker run -p 8080:8080 myapp
This command runs the “myapp” image as a container and maps port 8080 on the host to port 8080 in the container.
Multi-Stage Builds
Multi-stage builds allow us to use multiple stages in a Dockerfile to build the final image. This can help keep the final image small and efficient by only including the necessary files and dependencies.
Here is an example of a Dockerfile using multi-stage builds:
# Use an official Golang runtime as a parent image
FROM golang:1.17-alpine AS build-env
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in go.mod
RUN go mod download
# Compile the Go application
RUN go build -o main .
# Use an Alpine Linux runtime as a parent image
FROM alpine:latest
# Copy the Go application from the previous stage
COPY --from=build-env /app/main /usr/local/bin/
# Change the working directory to /app
WORKDIR /app
# Remove any unnecessary packages
RUN apk --no-cache add curl
# Expose port 8080 for the application
EXPOSE 8080
# Run the Go application when the container starts
CMD ["/usr/local/bin/main"]
This Dockerfile uses two stages: a build stage and a run stage. The build stage compiles the Go application and the run stage copies the compiled application from the build stage. This allows us to keep the final image small and efficient.
Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. It allows us to define the services, networks, and volumes needed for our application in a YAML file.
Here is an example of a Docker Compose file for a Go application:
version: '3'
services:
app:
build: .
ports:
- "8080:8080"
volumes:
- .:/app
This Docker Compose file defines a single service named “app” that builds the Docker image using the Dockerfile in the current directory, maps port 8080 on the host to port 8080 in the container, and mounts the current directory as a volume at /app in the container.
Conclusion
In this guide, we learned the basics of Docker and how it can be used with Go applications. We covered how to create a Dockerfile, build and run a Go image as a container, use multi-stage builds for building small images efficiently, and use Docker Compose to orchestrate running of multiple related containers together.
For more information, you can refer to the following resources:
- Docker Docs: Golang
- Docker + Golang = ❤️
- How to Rapidly Build Multi-Architecture Images with Buildx | Docker
- How to Build and Deploy a Task Management Application Using Go | Docker
- Build Your “Hello World” Container Using Go | Red Hat Developer
- Building tiny container images | Opensource.com
- Run your image as a container | Docker Docs
- Writing Docker Files for Different Technology Stacks – Sweetcode.io
- Build your Go image | Docker Docs
- Go samples | Docker Docs
- Build secure container images with RHEL UBI | Red Hat Developer