Docker-Image erzeugen

Nachdem Sie ein einfaches Image selbst ausgeführt haben, stellt sich die Frage, wie Sie selbst ein Docker-Image für Ihre Anwendung erzeugen können.

Manuelles Erzeugen eines Image

Für das manuelle Erzeugen eines Image wird auf das Ubuntu-Image aus dem Docker Hub zurückgegriffen.

Durch folgende Eingabe wird das Image im Docker Hub gesucht und ausgeführt, was bedeutet, dass ein Container gestartet wird. Die rm-Flag bewirkt, dass der Container gelöscht wird, sobald man ihn stoppt. Die name-Flag gibt dem Container einen Namen, der bei Aufruf der Container-Übersicht angezeigt wird.

docker run -it --name mein_container --rm ubuntu:latest

Nun erscheint als Prompt eine Anzeige, die ähnlich aussieht wie die Folgende:

root@02567caf84f:/#

Sie befinden sich nun innerhalb des eben auf Basis des Ubuntu-Images gestarteten Containers. Installieren Sie nun git im Container:

apt-get update
apt-get install git

Überprüfen Sie, dass git installiert wurde:

git --version

Verlassen Sie den Container über den exit-Befehl. Starten Sie daraufhin eine neue Container-Instanz basierend auf dem Ubuntu-Image.

docker run -it --name mein_container --rm ubuntu:latest

Wenn Sie git eingeben, werden Sie sehen, dass git nicht installiert ist. Dies liegt daran, dass ein neuer Container gestartet wurde, der unabhängig vom zuvor erstellten Container ist. Somit sind alle Änderungen, die wir innerhalb des Containers vorgenommen haben, verworfen worden.

git
Zustand des Containers als Image speichern

Damit die Änderungen nicht verworfen werden, muss der Container als Image gespeichert werden. Starten Sie erneut einen Container, diesmal jedoch ohne die rm-Flag, sodass der Container nach Beendigung nicht entfernt wird.

docker run -it --name mein_container ubuntu:latest

Installieren Sie erneut git innerhalb des Containers und beenden dann den Container über den exit-Befehl.

Lassen Sie sich alle Container anzeigen. Der eben erzeugte Container mein_container wird in der Liste aufgeführt.

docker ps --all

Erstellen Sie nun mit dem commit-Befehl ein Image des eben ausgeführten Containers. Als Repository geben Sie scm.cms.hu-berlin.de:4567/<namespace>/<projekt> an. Sie können auch einen Tag angeben; wenn Sie dies nicht tun, wird der Standard-Tag latest vergeben.

docker commit [ContainerID] [Repository[:Tag]

Nun können Sie sich in der GitLab-Registry anmelden und das Image hochladen.

docker login scm.cms.hu-berlin.de:4567
docker push scm.cms.hu-berlin.de:4567/<namespace>/<projekt>

Wenn Sie über den pull-Befehl das Image aus dem GitLab-Repository herunterladen und ausführen, so ist git installiert. Die Änderungen, die im Container vorgenommen wurden, sind somit im Image gespeichert worden.

Erzeugen eines Image mithilfe eines Dockerfile

Um das Erzeugen eines Image zu automatisieren, kann ein Dockerfile verwendet werden. Ein Dockerfile ist eine Textdatei, in der sich die Anweisungen zur Erstellung eines Image finden.

Herunterladen eines Beispiel-Projekts

Laden Sie das Beispiel-Projekt von GitHub herunter und navigieren Sie zum Projekt.

https://github.com/do-community/hello_hapi.git
cd hello_hapi

Das Dockerfile ist hier schon angelegt und enthält die Anweisungen für die Umgebung, in der die App laufen wird.

# use the latest node release
FROM node:carbon
WORKDIR /usr/src/app

# copy package.json and package-lock.json and install packages. we will do this
# separate from the application code to better use docker's caching
# `npm install` will be cached on future builds if only the app code changed
COPY package*.json ./
RUN npm install

# copy the app
COPY . .

# expose port 3000 and start the app
EXPOSE 3000
CMD [ "npm", "start" ]

FROM: Es wird die aktuelle Version von Node verwendet.

WORKDIR: Es wird das Arbeitsverzeichnis im Container festgelegt, in dem die Instruktionen RUN, CMD, ENTRYPOINT, COPY und ADD im Dockerfile ausgeführt werden.

COPY: Kopiert Dateien oder Verzeichnisse in das als Ziel angegebene Verzeichnis im Container.

RUN: Führt die Anweisung in einer neuen Schicht aus und speichert diese Image-Schicht.

COPY: Kopiert die Anwendung in das Root-Verzeichnis des Containers.

EXPOSE: Informiert die Person, die den Container ausführt, welcher Port des Docker-Containers freigegeben wird. Der Port wird hier noch nicht an einen Port des Host-Systems gebunden, dies geschieht erst, wenn ein Image gestartet wird.

Details zu den Anweisungen, die in einem Dockerfile verwendet werden können, finden sich in der Docker-Dokumentation.

Bearbeiten der CI-Konfigurationsdatei

Im Projektverzeichnis finden Sie die .gitlab-ci.yml-Datei. Öffnen Sie diese und ersetzen den Code durch untenstehende Zeilen. Ersetzen Sie dabei bei den Variablen TEST_IMAGE, RELEASE_IMAGE sowie in der before_script-Anweisung den Pfad durch den Pfad zum GitLab-Projekt, in dem das Image der Anwendung abgelegt werden soll. Es werden drei Phasen festgelegt, build, test und release. In der build-Phase wird das Docker-Image mit dem Befehl docker build erzeugt. Anschließend wird das Image in das Projektverzeichnis hochgeladen.

image: docker:latest
services:
- docker:dind

stages:
- build
- test
- release

variables:
    TEST_IMAGE: scm.cms.hu-berlin.de:4567/<namespace>/<project>:$CI_COMMIT_REF_NAME
    RELEASE_IMAGE: scm.cms.hu-berlin.de:4567/<namespace>/<project:latest>

before_script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN scm.cms.hu-berlin.de:4567

build:
    stage: build
    script:
        - docker build --pull -t $TEST_IMAGE .
        - docker push $TEST_IMAGE

test:
    stage: test
    script:
        - docker pull $TEST_IMAGE
        - docker run $TEST_IMAGE npm test

release:
    stage: release
    script:
    - docker pull $TEST_IMAGE
    - docker tag $TEST_IMAGE $RELEASE_IMAGE
    - docker push $RELEASE_IMAGE
    only:
    - master
Hochladen der Änderungen

Führen Sie nun einen Commit der Änderungen durch und laden Sie alle Dateien in GitLab hoch.

git add .
git commit -m "Update der CI-Konfiguration"
git push

Aktivieren Sie den Shared Runner für das Projekt sofern noch nicht geschehen, sodass dieser Anweisungen in .gitlab-ci.yml-Dateien ausführt. Sie können im linken Seitenmenü auf CI / CD klicken und verfolgen, wie die yml-Datei ausgeführt wird.

dockerfile pending pipeline

Wenn alles geklappt hat, finden Sie das Image in der Registry des Projekts.

docker image in registry

Sie können das Image nun auch erneut herunterladen und testen. Mithilfe der p-Flag wird der Port 3000 des Containers an den Port 3000 der Host-Maschine gebunden. Der vom Container bereitgestellte Port wird im Dockerfile mithilfe des EXPOSE-Tags festgelegt.

docker pull scm.cms.hu-berlin.de&lt;<namespace&gt;/&lt;<projekt&gt;
docker run -p 3000:3000 <IMAGE-ID>

Rufen Sie nun im Browser folgenden Link auf, um das Ergebnis zu sehen:

http://localhost:3000/hello/Homer