#+DATE:  2024-10-12
#+OPTIONS: toc:nil
#+macro: issue [[https://code.252.no/tommy/containers/issues/$1][issue #$1]]
#+macro: pr [[https://code.252.no/tommy/containers/pulls/$1][PR #$1]]
#+export_file_name: kagi
#+property: header-args:elisp :results none :exports code

#+BEGIN_EXPORT html
<div align="center">
<h1>Container Collection</h1>
<h4>Images for Kubernetes deployments</h4>
<img src="https://code.252.no/tommy/containers/raw/branch/main/assets/macchiato-palette.png" width="600" align="center"/>
<p></p>
    <a href="https://nixos.wiki/wiki/Flakes" target="_blank">
        <img alt="Nix Flakes Ready" src="https://img.shields.io/static/v1?logo=nixos&logoColor=d8dee9&label=Nix%20Flakes&labelColor=5e81ac&message=Ready&color=d8dee9&style=for-the-badge">
    </a>
 <p></p>
</div>
<hr/>
#+END_EXPORT

** Available Images

| Container                                 | Channel             | Image                                          |
|-------------------------------------------+---------------------+------------------------------------------------|
{% for image in app_images | sort(attribute="name") -%}
|[[{{ image.html_url }}][{{ image.name }}]] | {{ image.channel }} | code.252.no/{{ image.owner }}/{{ image.name }} |
{% endfor %}

** Container Rules

Containers in this project should be useful in Kubernetes. They will be:

- [[https://semver.org/][semantically versioned]]
- [[https://rootlesscontaine.rs/][rootless]]
- logging to stdout in JSON format if possible
- using [[https://testdriven.io/tips/59de3279-4a2d-4556-9cd0-b444249ed31e/][one process per container]]
- having no [[https://github.com/just-containers/s6-overlay][s6-overlay]]
- built on [[https://hub.docker.com/_/alpine][Alpine]]
- [[https://glossary.cncf.io/immutable-infrastructure/][immutable]]
- do no monkey business after deployed

Additionally I may in the future support:

- [[https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/][multiple architecture]]. For now containers are
  generated for amd64


## Tag immutability

Instead of using immutable version tags as seen on e.g. [[https://fleet.linuxserver.io/][linuxserver.io]] we
use [[https://www.letsdebug.it/post/41-calendar-versioning/][calver]] and sha256-digests.

If pinning an image to the sha256 digest, tools like [Renovate](https://github.com/renovatebot/renovate) support 
updating the container on a digest or application version change.

The schema used is: =YYYY.MM.Minor@sha256:digest=. This is not as pretty, but functional and immutable. Examples:

| Container                                                              | Immutable |
|------------------------------------------------------------------------+-----------|
| =code.252.no/tommy/containers/forgejo-runner:v24.10.1=                 | ❌        |
| =code.252.no/tommy/containers/forgejo-runner:v24.10.1@sha256:1234...= | ✅        |



** Kubernetes Pod Security Standard

In Kubernetes we assume that you have pod-security.kubernetes.io/enforce set to 
[[https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted][restricted]]. There may be 
some exceptions to this if the container actually requires more privileges.

E.g. for the =forgejo-runner=, which runs as user ID =1000=, this means that the following settings should be
used for the pod (all containers in a pod):

#+begin_src yaml
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
#+end_src

For a container this means:

#+begin_src yaml
spec:
  [...]
  containers:
  - name: forgejo-runner
    [...]
    securityContext:
      runAsUser: 1001
      capabilities:
        drop: ["ALL"]
      privileged: false
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
#+end_src

** Configuration volume

For applications that need to have persistent configuration data the config volume is hardcoded to `/config` 
inside the container.


** Deprecations

Containers here can be **deprecated** at any point, this could be for any reason described below.

1. The upstream application is **no longer actively developed**
2. The upstream application has an **official upstream container** that follows closely to the mission statement described here
3. The upstream application has been **replaced with a better alternative**
4. The **maintenance burden** of keeping the container here **is too bothersome**


** Credits

The structure of this repo was inspired and partially ripped off from
[[https://github.com/buroa/containers/tree/master][Buroa@github]].