durch Anlegen eines Dockerfiles automatisch den entsprechenden Container bauen

Datum

Ich möchte hier nur mal kurz zeigen, wie sich ein entsprechender (Ansible)Container mithilfe der Gitlab-CI recht flexibel durch das pushen des Dockerfiles bauen lässt.
Kurzfassung:
Hierbei wird der für einen Ordner im Repo vergebene Name als Name für den entsprechenden Container automatisch ausgelsen und verwendet.
Es wird auch nur das geänderte Dockerfile verwendet und alle übrigen werden nicht neu gebaut.

die Ordnerstruktur des Repos

$ tree
.
└── Dockerfiles
    ├── 2.10
    │   ├── Dockerfile
    │   └── requirements.txt
    ├── 3.4
    │   ├── Dockerfile
    │   └── requirements.txt

Schritte in der Gitlab-CI

Die „magischen“ Schritte sind recht übersichtlich und können natürlich nach belieben erweitert und/oder angepasst werden.


stages:
  - build

build:
  image: registry.redhat.io/rhel8/podman:8.3-64
  before_script:
    - podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  tags:
    - container_build
  stage: build
  variables:
    DOCKERFILES_DIR: 'Dockerfiles/'
  script:
    - dnf install -y git
    - export ANSIBLE_VERSION=$(git whatchanged -n 1 | grep Dockerfile | cut -d '/' -f2 | uniq)
    - echo $ANSIBLE_VERSION
    - echo "Baue Ansible $ANSIBLE_VERSION Container"
    - podman build --pull --no-cache -t "$CI_REGISTRY_IMAGE:$ANSIBLE_VERSION" Dockerfiles/$ANSIBLE_VERSION/
    - echo "pushing container"
    - podman push "$CI_REGISTRY_IMAGE:$ANSIBLE_VERSION" 

Ich werde mich bei den Erläuterungen nur auf den script beschränken, da der Teil darüber jedem selber überlassen ist.
Wichtig ist das angeben der Ordners der Dockerfiles durch variables:.

- dnf install -y git —> installieren von git im Container, in welchem der neue Container gebaut wird. Dies ist für den nächsten Schritt notwendig
export ANSIBLE_VERSION=$(git whatchanged -n 1 | grep Dockerfile | cut -d '/' -f2 | uniq) —> hier wird der Ordner, in welchem etwas angepasst/geändert wurde aus dem Git-Log ausgelesen und in eine Variable gepackt
Bsp.:

$ git whatchanged -n 1 | grep Dockerfile | cut -d '/' -f2 | uniq
4.9

echo "Baue Ansible $ANSIBLE_VERSION Container" —> das dient eher zum debuggen, da man hier schauen kann ob die bisherigen Schritte erfolgreich waren
podman build --pull --no-cache -t "$CI_REGISTRY_IMAGE:$ANSIBLE_VERSION" Dockerfiles/$ANSIBLE_VERSION/ —> das eigentliche bauen des Containers durch Angabe des Dockerfiles aus dem Git-Log

Der entscheidene Vorteil ist hierbei einfach, dass nicht ständig sämtliche Container im Repo bei einer Änderung neugebaut werden.

Anschließend wird der neue Container einfach in die entsprechende Registry geschoben.

Erstellen eines neuen Containers

Um nun einen neuen Container anzulegen, erstellt man unterhalb von Dockerfiles einen entsprechenden Ordner mit dem Namen z.B. 4.9.
Darin wird das Dockerfile angelegt welches die Info und die notwendige Installalationsroutine für den Container enthält.
Nach dem puschen erledigt die Gitlab-CI den Rest:


...
$ export ANSIBLE_VERSION=$(git whatchanged -n 1 | grep Dockerfile | cut -d '/' -f2 | uniq)
$ echo $ANSIBLE_VERSION
4.9
$ echo "Baue Ansible $ANSIBLE_VERSION Container"
Baue Ansible 4.9 Container
...
$ echo "pushing container"
pushing container
$ podman push "$CI_REGISTRY_IMAGE:$ANSIBLE_VERSION"
Getting image source signatures
Copying blob sha256:e39c3abf0df93fca44921f3548fcf6e139afdcb2ac9b7baa6c47b39f87113b32
Copying blob sha256:383db43d39c39d1af68fdaa2021659e31ce1735300abf33043ba5bb633efa05d
...
Job succeeded

Autor
Kategorien container, gitlab-CI

PRTG Map