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:
- ca.pem
- cert.pem
- 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
- Portainer
https://www.portainer.io
https://docs.portainer.io - c’t Die 20 wichtigsten Linux-Kommandos
https://www.heise.de/tipps-tricks/Linux-Befehle-Die-20-wichtigsten-Kommandos-3843388.html - Docker-Dokumentation
https://docs.docker.com/manuals/ - Docker Hub für Image-Dokumentation
https://hub.docker.com - Git Hub für Image-Dokumentation
https://github.com