I’ve always wanted to have my own little Kubernetes cluster somewhere and I finally decided to create one with Civo. But I had no idea what to run on it. So, this little post is about how I went about creating a hello-world application to run on my cluster!
If you only want to see the code, here you go.
The application itself is a simple C# file inspired by Jess Frazelle’s much cooler party-clippy:
1const string CLIPPY = @"
2
3 __
4 / \ _____________
5 | | / \
6 @ @ | It looks |
7 || || | like you |
8 || || CLIPPY);
9app.Run();
main.cs
Next, I put together a Dockerfile. After some googling around, I decided to use the ubuntu chiseled docker image ubuntu/dotnet-deps. I’ve only ever used alpine or debian for C# applications, so this was a first!
1FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
2WORKDIR /app
3
4COPY ./src ./src
5RUN dotnet publish -c Release -r linux-x64 --self-contained -o /app/out ./src/clippy.csproj
6
7FROM ubuntu/dotnet-deps:7.0_edge AS final
8
9LABEL org.opencontainers.image.source="https://github.com/gldraphael/clippy"
10LABEL org.opencontainers.image.description="A simple hello world application."
11
12ENV \
13 # Configure web servers to bind to port 80 when present
14 ASPNETCORE_URLS=http://+:80 \
15 # Enable detection of running in a container
16 DOTNET_RUNNING_IN_CONTAINER=true \
17 # Disable globalization
18 DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
19
20EXPOSE 80
21
22WORKDIR /app
23COPY --from=build-env /app/out .
24ENTRYPOINT ["./clippy"]
Dockerfile At this point, I had something I could run in a container.
Now that I had a working docker image, I wanted to be able to publish this to GitHub packages using GitHub actions. This bit was actually the easiest. I literally just pasted this example from the documentation, and it just worked!
1# pull the latest image
2docker pull ghcr.io/gldraphael/clippy:main
3
4# run it in the background
5docker run -it -d -p 8080:80 --name clippy --rm ghcr.io/gldraphael/clippy:main
6
7# curl it
8curl localhost:8080
9
10# once you're done, stop it to delete it
11docker stop clippy
This also happens to be the first time I’ve ever used GitHub packages. Another first. Yay!
Next, I wanted a helm chart. Creating the chart itself was easy. helm create chart did it. I only had to go in and update a few things (like change the app name from chart to clippy, update the image to use, and so on).
Trouble was, I wasn’t even sure if GitHub container registry supported OCI artifacts yet. Lucky for me, Niklas Metje documented this on his blog. I just had to figure out the workflow file. I ended up using Stefan Prodan’s podinfo project as an example and decided to go with something like this:
1name: Push helm chart
2
3on:
4 push:
5 branches: ['main']
6
7env:
8 REGISTRY: ghcr.io
9
10jobs:
11 build-and-push-image:
12 runs-on: ubuntu-latest
13 permissions:
14 contents: read
15 packages: write
16
17 steps:
18 - name: Checkout repository
19 uses: actions/checkout@v3
20
21 - name: Setup Helm
22 uses: azure/setup-helm@v3
23 with:
24 version: v3.11.3
25
26 - name: Log in to the Container registry
27 uses: docker/login-action@v2
28 with:
29 registry: ${{ env.REGISTRY }}
30 username: ${{ github.actor }}
31 password: ${{ secrets.GITHUB_TOKEN }}
32
33 - name: Publish Helm chart to GHCR
34 run: |
35 helm package chart
36 export CHART_VERSION=$(grep 'version:' ./chart/Chart.yaml | tail -n1 | awk '{ print $2 }')
37 helm push clippy-$CHART_VERSION.tgz oci://${{ env.REGISTRY }}/gldraphael/charts
38 rm clippy-$CHART_VERSION.tgz
The action seems to push a chart ok, but I’m yet to actually run this on a cluster. Next weekend!