Skip to content

Day 4 - Building your first container

Published:Β atΒ 12:00 AM

It is finally time to build your first container! Today we will go through the process of dockerizing a simple application.

We will use a simple Go application that prints β€œHello, World!” to the console. I purposefully chose Go because it is a very simple language and you probably don’t have it installed yet. This will show you one of the benefits of dockerizing your applications, you can use any language you want without actually needing to install it on your machine!

To get started create a new directory for your project and navigate into it. Then create a new file called main.go and add the following code:

package main

import "fmt"

func main() {
	fmt.Println("Hello, World!")
}

As you can probably see, this is only going to print β€œHello, World!” to the console and the exit. Baby steps! Now if you have go installed you can just execute the code with:

$ go run main.go
Hello, World!

I don’t expect you to actually run this on your machine, we will just use docker to build and run it!

Now that we have our application, we can start to dockerize it. To do this we will create a file called Dockerfile that will define how to build and run our application.

FROM golang

COPY . .

RUN go build -o main main.go

CMD ["./main"]

A dockerfile is a simple text file that contains a set of instructions for docker on how to build and run your application. It is executed in order from top to bottom. Each instruction generally adds a new layer to the image, or in other words, it adds an additional set of files to your final image.

The first instruction FROM golang tells docker to use the official golang image as a base image. This image already contains the golang compiler and other dependencies we need to build our application. This is basically the same as if you would manually install golang.

FROM golang

The next instruction COPY . . copies all files from the current directory into the image.

COPY . .

The next instruction RUN go build -o main main.go builds our application and names the output file main.

RUN go build -o main main.go

The last instruction CMD ["./main"] tells docker to run the main executable when the container starts.

CMD ["./main"]

The Dockerfile itself does not do anything. To create an image from it, we will need to run the docker build command.

$ docker build -t hello-world-go .

This will create a new image with the name hello-world-go. The dot at the end tells Docker which directory to use as the root for the build.

The first time you run this command, Docker will start to download the golang base image from Docker Hub. This might take a while if you don’t have it yet! Subsequent runs will be faster because Docker is quite good at caching steps that do not change.

If the build was successful, you should be able to see it when you list all images with docker images.

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED
hello-world-go      latest              <image-id>          <timestamp>

If you don’t see the image, please let me know and I will help you out :)

Great job! You just built your first docker image! πŸŽ‰

Now that we have our image, we can run it with the docker run command.

$ docker run hello-world-go
Hello, World!

This will start a new container from our image and execute the main executable, because that is what we defined with the CMD instruction in our Dockerfile.

As you can see, the container exits immediately because that is what our application does.

If you run docker ps --all, you should see that the container exited immediately.

$ docker ps -a
CONTAINER ID     IMAGE            COMMAND     CREATED          STATUS
<container-id>   hello-world-go   "/main"     <timestamp>      Exited (0)

Make sure to run docker ps --all and not docker ps because docker ps only shows running containers by default. The --all flag is used to show all containers, including the ones that have already exited.

Now its your turn to play around with this small setup! Change some lines in the Dockerfile and see what happens. Here are some ideas:

If you get stuck, feel free to ask me for help! You can reach me on dev.to/code42cate or on X/Twitter or by email

Anyway, that’s it for today. Tomorrow we will take a deeper look at what exactly happend when we built our image and learn some more ways to interact with containers. If you want to have a headstart, checkout the docker exec command and what you can do with it!

Until then, happy hacking! πŸš€

Jonas


Previous Post
Day 3 - What is Docker and why should I care?
Sponsor logo

Sliplane

Deploy your Docker Apps straight from your Github repository in less than 2 minutes with sliplane.io

Learn More β†’