Building a Minimalist (CGO enabled) Scratch Docker Container đŗ with Alpine Linux đ§ and GoLang đ
In the world of containerization, Docker has emerged as a powerful tool for packaging applications and their dependencies into lightweight, isolated environments. With Docker, you can create portable and reproducible containers that can run on any platform with Docker support. In this article, we will walk through the process of building a mini Docker container using Alpine Linux and the Go programming language.
Getting Started đ
To begin, we need to have Docker installed on our machine. If you haven’t installed Docker yet, head over to the official Docker website (đ https://www.docker.com) and follow the installation instructions for your operating system.
Once Docker is up and running, we can proceed with creating our minimalist Docker container.
Writing the Dockerfile đ
A Dockerfile is a text file that contains instructions for building a Docker image. We will start by creating a new file called Dockerfile
and opening it in your favorite text editor.
FROM golang:1-alpine AS builder
RUN apk add --no-cache build-base
WORKDIR /build
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags='-s -w' -trimpath -o /dist/app
RUN ldd /dist/app | tr -s [:blank:] '\n' | grep ^/ | xargs -I % install -D % /dist/%
RUN ln -s ld-musl-x86_64.so.1 /dist/lib/libc.musl-x86_64.so.1
FROM scratch
COPY --from=builder /dist /
USER 65534
ENTRYPOINT ["/app"]
Let’s break down the contents of this Dockerfile step by step:
-
Base Image: We start with the
golang:1-alpine
image as our base. Alpine Linux is a lightweight distribution commonly used in Docker containers. -
Builder Stage: We create a new stage named
builder
to build our Go application. We install thebuild-base
package, set the working directory to/build
, and copy the necessary Go module files. -
Dependency Management: We run
go mod download
to download the Go dependencies specified in thego.mod
file. -
Build Process: We copy the rest of the application source code, and then use the
go build
command to compile our Go code into an executable namedapp
. The resulting binary is placed in the/dist
directory. -
Dynamic Libraries: To ensure all dynamic libraries required by the executable are available, we use
ldd
to list the dependencies, filter out the library paths, and install them into the/dist
directory. -
Symbolic Link: We create a symbolic link from
/dist/lib/libc.musl-x86_64.so.1
told-musl-x86_64.so.1
. This is done to provide compatibility with certain Alpine Linux versions. -
Final Stage: In the final stage, we use the
scratch
base image, which is an empty image. We copy the/dist
directory from thebuilder
stage to the root of the final image. -
User Privileges: For security reasons, we switch the user to a non-root user with the UID
65534
(usually thenobody
user). -
Entry Point: We set the entry point of the container to
/app
, which is the path of the executable we built.
Building the Docker Image đī¸
Now that we have our Dockerfile ready, we can build the Docker image using the following command:
docker build -t minimalist-scratch-container .
Let’s break down the command:
docker build
: This command is used to build a Docker image.-t
: This flag is used to tag the image with a name (in this case,minimalist-scratch-container
)..
: This specifies the build context, which is the current directory (where the Dockerfile is located).
Once the command finishes executing, Docker will build the image based on the instructions in the Dockerfile. The resulting image will be tagged with the name minimalist-scratch-container
.
Running the Container đââī¸
To run a container based on our newly created image, use the following command:
docker run --rm -it minimalist-scratch-container
Let’s understand the command:
docker run
: This command is used to run a container based on an image.--rm
: This flag automatically removes the container once it exits.-it
: These flags allocate a pseudo-TTY and enable interactive mode, allowing us to interact with the container.minimalist-scratch-container
: This is the name of the image we want to run.
After executing the command, you should see the output of your Go application running inside the container.
Conclusion đ
Congratulations! You have successfully built a minimalist Docker container using Alpine Linux and GoLang. This container provides a lightweight and isolated environment for running your Go applications. Docker’s portability makes it easy to deploy and share your containerized applications across different platforms.
Feel free to explore further and customize the Dockerfile to suit your specific requirements. Happy containerizing! đŗđ§đ