In this lab, you will:

Prerequisites

In this step, you will check out the repository, open it in your IDE and create a very simple Dockerfile.

Clone the Repository

Create a Dockerfile

Before we start creating Dockerfiles, we should be familiar with the syntax. Therefore, we will create a very simple Dockerfile, which will just print "Hello World" when run and simply run it

FROM docker.io/library/debian:bookworm-slim

RUN apt-get update && apt-get install -y curl

CMD ["curl", "https://www.fh-burgenland.at"]

This Dockerfile will use the official Debian Bookworm image, install curl and run curl against the website of the University of Applied Sciences Burgenland.

Build and run the Dockerfile

Now it's time to build and run the Dockerfile. This can be done with the following commands:

This will build the Dockerfile and tag it with the name hello-world and the tag latest. The . at the end of the command tells Docker to use the current directory as build context.

Note that this command won't push the image to a registry. It will just build it locally.

Nevertheless, as docker stores the images in a local cache, you can run the image with the following command:

The last example was very easy, but it didn't really show the power of Docker. Therefore, we will create a simple application in Go, which will run in a container.

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %q", r.URL.Path)
    })
    http.ListenAndServe(":8080", nil)
}

This application is a very simple webserver, which will return the URL path of the request.

Probably, you are not a Go Developer and you don't have a Go environment installed. Therefore, we will use a Dockerfile to build the application.

FROM docker.io/library/golang:1.21.3-alpine3.18

COPY src /src
WORKDIR /src

RUN go mod init hello-world \
    && go build -o /app .

CMD /app

This Dockerfile will use the official Go image, copy the source code to the image, build the application and run it.

Now it's time to build and run the Dockerfile. This can be done with the following commands:

This will build the Dockerfile and tag it with the name hello-world and the tag latest. The . at the end of the command tells Docker to use the current directory as build context.

Now we can simply run the image with the following command:

By using -p 8080:8080 you tell Docker to map the port 8080 of the container to the port 8080 of your local machine, therefore you should be able to access the application via localhost:8080 when it's running.

Automating the build

As you can see, the build process is quite simple, but it might only work on your machine. To make this reproducible and running on every push, we will automate the build process with GitHub Actions.

Push the current state to GitHub

To have the code available on GitHub, please push the current state to GitHub:

When you now open your repository on GitHub, you should see the new files, but nothing is happening yet.

To start developing your new feature now, check out a new branch:

Now, we will create a new GitHub Action, which will build the application and push it to the GitHub Container Registry. To do this, we will create a new file called .github/workflows/build.yml with the following content:

name: Build

on:
  pull_request:
    branches:
      - 'main'

jobs:
  build_image:
    name: Build Container Image
    runs-on: ubuntu-22.04

    steps:
      - name: Check out code
        uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4

      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3

      - name: Build Docker Image
        uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5
        with:
          context: .
          platforms: linux/amd64
          file: ./Dockerfile.build
          tags:
            hello-fhb:dev
          push: false

You can temporarily change the trigger to on push to your branch to test it.

This GitHub Action will run on every pull-request to the main branch and will build the Dockerfile. It will also tag the image with hello-fhb:dev, but don't push it to the registry.

Finally, push the changes to GitHub.

Now, we will create a new GitHub Action, which will build the application and push it to the GitHub Container Registry. To do this, we will create a new file called .github/workflows/push.yml with the following content:

name: Build

on:
  push:
    branches:
      - 'main'

jobs:
  build_image:
    name: Build Container Image
    runs-on: ubuntu-22.04

    permissions: 
      contents: read
      packages: write

    steps:
    - name: Check out code
      uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4

    
    - name: 'Login to GitHub Container Registry'
      uses: docker/login-action@v1
      with:
        registry: ghcr.io
        username: ${{github.actor}}
        password: ${{secrets.GITHUB_TOKEN}}
    
    - name: Set up Docker Buildx
      id: buildx
      uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3
    
    - name: Build Docker Image
      uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5
      with:
        context: .
        platforms: linux/amd64
        file: ./Dockerfile.build
        tags: 
          ghcr.io/${{github.repository}}/hello-fhb:${{ github.sha }}
        push: true

This GitHub Action will run on every push to the main branch and will build the Dockerfile. It will also tag the image with ghcr.io/${{github.repository}}/hello-fhb:${{ github.sha }} and push it to the registry.

Also push the changes to GitHub, try to make some changes, create a pull-request and merge it. You should now see the image in the GitHub Container Registry.

Finally, we will run the container on your machine. To do this, we will use the following command:

If you can access the application via http://localhost:8080/hello-fhb, you have successfully completed the workshop. Congratulations!