Letzte Aktualisierung am 21. März 2025


Ich gehe davon aus, dass du die grundlegende Funktionen von Docker sowie die grundlegenden Docker-Kommandos kennst. Eine gute Quelle dafür ist die Docker-Dokumentation selbst. Ebenso gehe ich davon aus, dass du keine Scheu hast mit der Linux-Konsole deines Pi zu arbeiten und die wichtigsten Linux-Kommandos kennst. Zum Nachschlagen gibt es z.B. diese Übersicht, oder die in Linux eingebaute Hilfe, die du mit <Kommando> --help in der Konsole aufrufst.


Portainer als Docker-Container

Portainer ist eine Web-GUI für die Administrierung deiner Docker-Umgebung. Da wir sie vor Verwendung erst installieren müssen, setzt die nachfolgende Beschreibung vollständig auf die Verwendung der Konsole deines Pi über eine eingerichtete SSH-Verbindung. Weitere Voraussetzung ist eine eingerichtete Datenablage. Ich verwende dafür stellvertretend immer /share/MyContainer/dk1. Diese Angabe musst du bitte deinen Gegebenheiten anpassen!

Wenn du dich auf deinem Pi eingeloggt hast und das Konsolenprompt siehst, kann es los gehen.

Zunächst legst du das Datenverzeichnis für deinen Portainer-Container an.

cd /share/MyContainer/dk1
mkdir portainer

Anschließend benötigst du zwei Dateien: .env für die Definition von Umgebungsvariablen für deinen Portainer-Container und docker-compose.yml für die Definition des Containers an sich.

cd portainer
touch .env
touch docker-compose.yml

Mit nano docker-compose.yml öffnest du die gleichnamige Datei und fügst folgendem Inhalt ein

services:
  portainer:
    container_name: portainer
    image: portainer/portainer-ce:latest
    privileged: true
    restart: always
    ports:
      - 9002:9000
    volumes:
      - ${DATA_ROOT}/portainer/data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - com.centurylinklabs.watchtower.enable=true
    networks:
      - nw-dekayone-admin

networks:
  nw-dekayone-admin:
    external: true

Mit Strg+O, Return und Strg+X speicherst du die Datei und beendest nano.

Analog öffnest du mit nano .env die gleichnamige Datei und fügst dort folgendes ein, speicherst und beendest nano wie zuvor.

# timezone
TIMEZONE=Europe/Berlin

# mountpoint of persistent data storage on NAS
DATA_ROOT=<dein_datenablage_share>

Welche Bedeutung haben nun diese beiden Dateien?

docker-compose.yml

Die Datei docker-compose.yml definiert allgemein eine Anzahl von Services (Docker-Container), die mit einem einzigen Aufruf von docker-compose gestartet werden.

Im Bereich services beginnend in der ersten Zeile werden die Services im docker-compose.yml spezifiziert. In Zeile 2 ist es der Service portainer mit dem Namen portainer in Zeile 3. Für den Container wird das Image portainer/portainer-ce:latest aus Zeile 4 genutzt.

Das restart: always in Zeile 6 sorgt dafür, dass bei einem Neustart des Pi der Docker-Container automatisch neu gestartet wird.
Der Abschnitt ports in den Zeilen 7 und 8 definiert den HTTP-Port, über den der Portainer-Container von außerhalb der Docker-Umgebung aufgerufen wird (hier: 9002). Der zweite Port hinter dem Doppelpunkt sorgt dafür, dass innerhalb der Docker-Umgebung der Port 9000 verwendet wird. Als IP-Adresse wird dabei diejenigen deines Docker-Hosts, also deines Pi genutzt. Welche Ports ein Container benutzt ist in der Image-Dokumentation angegeben. Ein guter Ausgangspunkt für die Dokumentation sind die Image-Verzeichnisse im Docker Hub oder Git Hub. Ansonsten hilft eine Suche nach dem Image im Internet bei Google, Bing oder anderen Suchdiensten.

Der Abschnitt volumes in den Zeilen 9 bis 11 sorgt für das Mapping bereits vorhandener Verzeichnisse außerhalb eines Docker-Containers (der Teil links vom Doppelpunkt) auf ein Verzeichnis innerhalb des Docker-Containers (der Teil rechts vom Doppelpunkt). Die Verzeichnisse im Docker-Container sind i.d.R. Container-spezifisch festgelegt und in der Dokumentation für das jeweilige Docker-Image zu finden. Für Portainer ist in diesem Fall das Verzeichnis /data für die Datenablage der Portainer-Daten festgelegt. Da wir diese Daten in unserer Datenablage auf dem NAS speichern möchte, sorgt die Angabe von ${DATA_ROOT}/portainer/data genau dafür. ${DATA_ROOT} ist dabei eine Umgebungsvariable, die in der Datei .env in Zeile 5 definiert ist. Hier wird das Verzeichnis eingetragen, dass du bei der Einrichtung der Docker-Umgebung angelegt hast. Das Verzeichnis data unter ${DATA_ROOT}/portainer existiert beim Starten des Containers nicht, es wird automatisch angelegt.
Das Verzeichnismapping in Zeile 11 sorgt dafür, dass Portainer mitbekommt, wenn neue Container gestartet werden, sodass diese in der Portainer-GUI aufgelistet werden.

Der Abschnitt labels in den Zeilen 12 und 13 ist die Vorbereitung dafür, dass Watchtower später den Portainer-Container automatisch aktualisiert, sofern Updates vorhanden sind. Im Zusammenspiel mit dem angegebenen Image in Zeile 4 ist mit Watchtower etwas Vorsicht geboten: Watchtower benutzt das angegebene Release-Tag, hier latest für die Updateprüfung. Dies sorgt dafür, dass immer das aktuellste freigegebene Release von Portainer genutzt und automatisch installiert wird. Dieses Vorgehen muss nicht immer sinnvoll sein, wenn z.B. nur bestimmte Versionen oder Release-Zweige verschiedener Container miteinander funktionieren. In diesem Fall ist das entsprechende Release-Tag zu verwenden. Als Beispiel sei hier ioBroker angeführt, der pro Releasezweig ein latest-Tag definiert. So zeigt latest-v10 auf das aktuellste freigegebene Release für Releasezweig v10. Hier ist es empfehlenswert die Dokumentation des entsprechenden Container-Images zu Rate zu ziehen.

Der nächste Abschnitt networks in den Zeilen 14 und 15 definiert ein oder mehrere Netzwerke innerhalb deiner Docker-Umgebung, in dem/ denen der Container läuft. Die Netzwerke innerhalb der Docker-Umgebung nutzen einen anderen IP-Adressbereich als dein lokales Netzwerk und sind somit davon getrennt. Zeile 14 bestimmt nun, dass Portainer im Netzwerk nw-dekayone-admin laufen soll. Du kannst hier einen beliebigen, für dich passenden Namen verwenden. Wichtig ist jedoch, dass du diesen Namen auch im folgenden Abschnitt in Zeile 17 verwendest.

Der Bereich networks auf oberster Ebene definiert schließlich alle Netzwerke, die von den Services in der docker-compose.yml verwendet werden. In diesem Fall ist es nur das Netzwerk nw-dekayone-admin. Die Angabe von external: true in Zeile 18 besagt, dass das Netzwerk nw-dekayone-admin außerhalb dieses docker-compose.yml erstellt wurde.

.env

In der Datei .env werden die Umgebungsvariablen definiert, die in docker-compose.yml verwendet werden.

In diesem Fall sind es die Zeitzone, die ich standardmäßig in allen meiner .env-Dateien aufnehme, für Portainer allerdings nicht verwendet wird.

Wichtiger ist die Umgebungsvariable DATA_ROOT, denn musst du den Pfad zu deiner Datenablage eintragen, den du bei Einrichten des Pi vergeben hast.

Starten des Containers

In docker-compose.yml ist der verwendete Netzwerk als external deklariert. Daher ist es wichtig, vor dem Starten von Portainer genau dieses Netzwerk anzulegen. Das geschieht mit folgendem Kommando (bitte analog deinen Netzwerknamen aus der docker-compose.yml verwenden, wenn du ihn angepasst hast)

docker network create nw-dekayone-admin

Mit dem Kommando

docker network ls

kannst du dir die Liste der angelegte Netzwerke ausgeben lassen. Wenn das zuvor angelegt Netzwerk mit aufgelistet wird, hat alles geklappt und du kannst mit dem folgenden Befehl zunächst das Portainer-Image lokal abrufen, den Container erstellen, um diesen anschließend als Hintergrundprozess zu starten.

docker compose up -d

Nach erfolgreicher Ausführung sieht die Ausgabe in deiner Konsole ähnlich wie die folgende aus

Wenn alles funktioniert hat, kannst du nun in einem Browser durch Eingabe der IP-Adresse deines Pi gefolgt vom Port 9002 in der Adressleiste die Portainer-Oberfläche aufrufen und mit der Ersteinrichtung weiter machen.

Ersteinrichtung der GUI

Nach Eingabe der IP-Adresse deines Pi gefolgt vom Port 9002 (bei mir ist es http://192.168.1.221:9002 oder alternativ auch der vergebene Hostname mit Portangabe, bspw. http://raspi:9002) öffnet sich beim erstmaligen Aufruf eine Seite zur Vergabe des Admin-Kennwortes für deinen Portainer.

Sind beide eingegebenen Kennwörter identisch, kommst du über die Schaltfläche „Create user“ auf die nächste Seite „Quick Setup“ zur Einrichtung deines ersten Environment. Die Auswahl der Option „Get Started“ sorgt dafür, dass die Docker-Umgebung deines Pi als Environment angelegt und angezeigt wird.

Du kannst jetzt auf das Environment klicken und gelangst zu einem Dashboard, in dem allgemeine Informationen angezeigt werden. Da ich bereits einige weitere Container in meiner Umgebung laufen habe, werden hier mehr Stacks, Images, Containers etc. angezeigt. Bei dir wird wahrscheinlich nur ein laufender Container angezeigt, Portainer selbst.

Wenn du nun den Punkt Stacks auswählst, erhälst du eine Anzeige aller laufenden Docker-Stacks (=docker-compose.yml). Auch hier laufen in meiner Umgebung bereits mehrere Stacks. Du solltest bei dir nur einen Eintrag für Portainer sehen. Da Portainer außerhalb von Portainer mit docker compose gestartet wurde, siehst du in der Spalte Control die Angabe Limited. D.h. du kannst für diesen Stack nicht vollständig mit Portainer kontrollieren. Die Stacks, die im weiteren Verlauf angelegt werden, sind über Portainer gestartet, sodass es dafür mehr Kontrollmöglichkeiten gibt.

Ein Klick auf einen Stack öffnet die dazugehörige Detailseite, in der alle Container aufgelistet sind, die im Stack gestartet wurden. Für den Stack Portainer siehst du nur einen Container in den Details, den für deine Portainer-Instanz.

Über den Punkt „Networks“ in der linken Navigationsleiste öffnest du die Liste der angelegten Netzwerke innerhalb deiner Docker-Umgebung, insb. auch das Netzwerk nw-dekayone-admin, das wir weiter oben angelegt haben.
Wenn du auf einen Eintrag in der Netzwerkliste klickst, öffnet sich eine Detailseite. Dort siehst du u.a. welche Container im ausgewählten Netzwerk laufen.

An dieser Stelle ist die Installation von Portainer abgeschlossen und du kannst nun mit Portainer deine Docker-Umgebung administrieren. Was und wie zeigen die weiteren Kapitel, in denen es um die Installation von Gitea und weiteren Applikationen geht.

Einbindung weiterer Docker-Umgebungen

Portainer ist in der Lage, mehrere Docker-Umgebungen einzubinden und zu administrieren. Im Folgenden findest du die Schritte zum Einbinden einer Docker-Umgebung, die z.B. auf einem anderen Pi läuft und keinen Docker Swarm mit dieser Umgebung bildet. Der zweite Abschnitt zeigt am Beispiel der Container Station auf meiner QNAP wie du die Docker-Umgebung deines NAS in Portainer einbindest.

Docker-Agent auf einem weiteren Pi

Für das Hinzufügen einer neue Docker-Umgebung auf einem weiteren Pi wählst du im Abschnitt der Administration im linken Navigationsbereich den Punkt „Environment-related“ und anschließend „Environments“.

Über die Schaltfläche „Add environment“ in der rechten oberen Ecke gelangst du zur Auswahl für die Art der Docker-Umgebung, die du hinzufügen möchtest.

Dort wählst du die Option „Docker Standalone“ und mit der Schaltfläche „Start Wizard“ geht es weiter zur nächsten Seite, auf der du das Kommando zum Starten des notwendigen Docker-Agents findest. Dieser Kommando musst du auf dem hinzuzufügenden Pi ausführen. Danach vergibst du einen beliebigen Namen für die neue Umgebung und gibst die IP-Adresse samt Port in der Zeile darunter ein. Achte dabei darauf, dass der Port derjenige ist, den du beim Starten des Agents angegeben hast. In meinem Beispiel habe ich den Namen environment_test und die IP-Adresse 192.168.1.222:9001 verwendet.

Über die Schaltfläche „Connect“ stellst du die Verbindung her. Und wenn das geklappt hat, kannst du über die Schaltfläche „Close“ die Seite schließen. Zurück in der Übersicht der Environments solltest du dort jetzt das gerade hinzugefügte sehen.

Wenn du im Navigationsbereich auf „Home“ klickst, gelangst du zum Startbildschirm, in dem das Dashboard angezeigt wird. Auch hier findest du jetzt die gerade hinzugefügte neue Umgebung.

Docker-App eines NAS am Beispiel QNAP

Du kannst auch die Docker-App deines NAS in Portainer einbinden. Wie das funktioniert beschreibe ich hier am Beispiel meiner QNAP mit QTS 4.3.6. Bei dir wird es ähnliche Möglichkeiten in der GUI deiner NAS geben.

Zunächst loggst du dich auf deiner NAS ein und startest die Docker-App. Bei mir ist es die App Container Station.

Wichtig ist nun, die Zertifikate deines NAS für die Docker-Umgebung herunterzuladen. In der Container Station sind diese unter „Preferences“ und dann im Reiter „Docker Certificate“ zu finden. Mit einem Klick auf die Schaltfläche „Download“ kannst du ein Zipfile auf deinen lokalen Rechner herunterladen.

Das Zipfile enthält drei Dateien, die du an einen geeigneten Ort entpackst:

  1. ca.pem
  2. cert.pem
  3. key.pem

Neben den drei genannten Dateien benötigst du noch die IP-Adresse inkl. Port, die bei „Set Environment“ angegeben ist. In diesem Fall lautet sie 192.168.1.101:2376.

Zurück in Portainer navigierst wie oben bis zum Environment Wizard und wählst dort die Option „Docker Standalone“ und führst den Prozess über die Schaltfläche „Start Wizard“ fort. In der folgenden Seite zum Setup der Verbindung wählst die Option „API“, vergibst einen passenden Namen und trägst im Feld „Docker API URL“ die IP-Adresse inkl. Port deines NAS von zuvor ein. Anschließend aktivierst die Option „TLS“ und lädst die drei o.g. Dateien in der angezeigten Reihenfolge hoch.

Mit der Schaltfläche „Connect“ stellst du danach die Verbindung her und schließt den Wizard über die Schaltfläche „Close“. Zurück in der Übersicht der Environments wird hier nun auch die neu hinzugefügte Umgebung container station angezeigt, ebenso im Dashboard der Portainer-Startseite.


Quellen & Links

Schreibe einen Kommentar