Vom frischen Ubuntu Server
bis zu ERPNext mit Portainer
Eine zusammenhängende Anleitung für Docker-Grundlagen, Portainer, Testcontainer, Docker Compose und anschließend ERPNext.
Eine zusammenhängende Anleitung für Docker-Grundlagen, Portainer, Testcontainer, Docker Compose und anschließend ERPNext.
Portainer ist eine Verwaltungsoberfläche für Docker. Deshalb kommt zuerst Docker, dann Portainer und erst danach eine größere Anwendung wie ERPNext.
hello-world und grundlegende CLI-Befehle.sudo apt update sudo apt full-upgrade -y
sudo apt install -y ca-certificates curl wget dnsutils
sudo timedatectl set-timezone Europe/Berlin timedatectl
cat /etc/os-release uname -a
Docker unterstützt Ubuntu 26.04 LTS offiziell. Für einen Server ist Docker Engine die passende Variante – nicht Docker Desktop.
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt updatesudo apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin
sudo systemctl status docker --no-pager sudo docker run --rm hello-world sudo docker version sudo docker compose version
hello-world lädt ein kleines Testimage, startet daraus einen Container und beendet ihn wieder. Wenn die Bestätigung erscheint, funktioniert die Docker-Basis.Für Lern- und Einzelbenutzersysteme ist es bequem, den eigenen Benutzer zur Gruppe docker hinzuzufügen.
sudo usermod -aG docker "$USER"
Danach vollständig ab- und wieder anmelden – oder für die aktuelle Shell:
newgrp docker
docker run --rm hello-world
docker gewährt praktisch Root-Rechte über den Docker-Daemon. Nur vertrauenswürdige Benutzer aufnehmen.Portainer CE läuft selbst als Docker-Container und verwendet den Docker-Socket, um den lokalen Docker-Daemon zu verwalten.
docker volume create portainer_data
docker run -d \ -p 127.0.0.1:9443:9443 \ --name portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:sts
Damit ist Portainer nicht direkt im LAN oder Internet erreichbar. Vom eigenen Rechner kannst du einen SSH-Tunnel öffnen:
ssh -L 9443:127.0.0.1:9443 BENUTZER@SERVER-IP
Danach im Browser:
https://127.0.0.1:9443
docker ps docker logs portainer --tail=50
/var/run/docker.sock sehr weitreichende Kontrolle über den Host. Portainer sollte deshalb wie eine Administrationsoberfläche behandelt und nicht ungeschützt öffentlich freigegeben werden.| Portainer-Bereich | Was du dort lernst |
|---|---|
| Containers | laufende und gestoppte Container, Ports, Status, Logs und Console. |
| Images | lokal vorhandene Container-Images und deren Größe. |
| Volumes | persistente Daten, die einen Containerneustart überleben. |
| Networks | virtuelle Docker-Netze und Kommunikation zwischen Containern. |
| Stacks | Docker-Compose-Anwendungen aus mehreren Diensten. |
| Stats | CPU-, RAM- und Netzwerkverbrauch eines Containers. |
NGINX eignet sich als erster Test, weil du sofort siehst, was ein Image, Container und veröffentlichter Port bedeuten.
docker run -d \ --name nginx-test \ -p 127.0.0.1:8080:80 \ nginx:alpine
docker ps curl http://127.0.0.1:8080 docker logs nginx-test
docker rm -f nginx-test
ERPNext besteht aus mehreren Containern. Deshalb solltest du vor ERPNext mindestens einmal einen kleinen Compose-Stack selbst starten.
mkdir -p ~/docker-lab/nginx/html cd ~/docker-lab/nginx
cat > html/index.html <<'EOF' <!doctype html> <html lang="de"> <head><meta charset="utf-8"><title>Docker-Test</title></head> <body> <h1>Docker Compose funktioniert!</h1> </body> </html> EOF
cat > compose.yml <<'EOF'
services:
web:
image: nginx:alpine
container_name: nginx-compose-test
ports:
- "127.0.0.1:8081:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
EOF
docker compose up -d docker compose ps curl http://127.0.0.1:8081
docker compose logs docker compose down
| Begriff | Bedeutung |
|---|---|
| Image | Unveränderliche Vorlage, aus der Container gestartet werden. |
| Container | Laufende Instanz eines Images mit eigener Prozess- und Dateisystemumgebung. |
| Volume | Von Docker verwalteter persistenter Speicher. |
| Bind Mount | Ein konkreter Host-Pfad wird in einen Container eingebunden. |
| Network | Virtuelles Netz, über das Container miteinander kommunizieren. |
| Port-Mapping | Host-Port wird auf einen Container-Port veröffentlicht. |
| Compose | Beschreibung einer Multi-Container-Anwendung in YAML. |
| Stack | Zusammengehörige Container und Ressourcen einer Anwendung. |
ERPNext Easy Install nutzt dein bereits installiertes Docker. Für die Standard-HTTPS-Variante brauchst du zusätzlich einen gültigen DNS-Namen und erreichbare Ports 80/443.
| Voraussetzung | Beispiel |
|---|---|
| Site-Name / FQDN | erp.firma.de |
| A-Record | zeigt auf deine öffentliche IPv4-Adresse |
| AAAA-Record | nur wenn IPv6 wirklich erreichbar ist |
| Router | 80/TCP und 443/TCP zum Ubuntu-Server weiterleiten |
für Let's Encrypt, z. B. admin@firma.de |
getent ahosts erp.firma.de dig +short A erp.firma.de dig +short AAAA erp.firma.de
127.0.0.1:9443 gebunden. Dadurch kollidiert es nicht mit ERPNext auf 80/443 und bleibt als Adminoberfläche getrennt.Das Easy-Install-Skript erkennt, dass Docker bereits vorhanden ist, lädt frappe_docker, erzeugt Compose-Dateien und richtet die Produktionsumgebung ein.
mkdir -p ~/erpnext-install cd ~/erpnext-install wget https://raw.githubusercontent.com/frappe/bench/develop/easy-install.py python3 easy-install.py deploy --help
python3 easy-install.py deploy \ --project=erpnext-prod \ --email=admin@firma.de \ --sitename=erp.firma.de \ --app=erpnext
| Datei | Funktion |
|---|---|
~/erpnext-prod-compose.yml | generierte Compose-Konfiguration. |
~/erpnext-prod.env | Umgebungswerte wie Site-Regel, Datenbankpasswort und ERPNext-Version. |
~/erpnext-prod-passwords.txt | Administrator- und MariaDB-root-Passwort. |
~/erpnext-install/easy-install.log | Installationslog für die Fehlersuche. |
chmod 600 ~/erpnext-prod-passwords.txt cat ~/erpnext-prod-passwords.txt
https://erp.firma.de erreichbar sein.Nach der Installation siehst du in Portainer mehrere ERPNext-Container. Genau hier zahlt sich der vorherige Lernschritt aus.
docker ps docker image ls docker volume ls docker network ls docker stats
docker compose -p erpnext-prod \ -f ~/erpnext-prod-compose.yml ps
docker compose -p erpnext-prod \ -f ~/erpnext-prod-compose.yml logs --tail=200
docker compose -p erpnext-prod \ -f ~/erpnext-prod-compose.yml restart
docker compose -p erpnext-prod \ -f ~/erpnext-prod-compose.yml exec backend \ bench --site erp.firma.de backup --with-files --compress
cd ~/erpnext-install wget -O easy-install.py \ https://raw.githubusercontent.com/frappe/bench/develop/easy-install.py python3 easy-install.py upgrade --project=erpnext-prod
docker compose -p erpnext-prod \ -f ~/erpnext-prod-compose.yml ps
-p 0.0.0.0:PORT:PORT veröffentlichten Dienst automatisch abschirmt.docker besitzen faktisch Root-nahe Rechte über den Docker-Daemon./var/run/docker.sock. Deshalb darf ein kompromittiertes Portainer-Konto nicht als „nur Web-GUI“ betrachtet werden – es kann den Docker-Host kontrollieren.| Ebene | Prüfung | Befehl / Hinweis |
|---|---|---|
| Host | Ubuntu / Ressourcen | uptime, free -h, df -h |
| Docker | Dienst läuft? | systemctl status docker |
| Container | Status / Restart-Loops | docker ps -a |
| Logs | Fehlermeldungen | docker logs NAME |
| Compose | gesamter ERPNext-Stack | docker compose ... ps |
| DNS | Name zeigt auf richtige IP? | getent ahosts erp.firma.de |
| Netz | Router / 80 / 443 | Portweiterleitung und Provider prüfen |
docker ps --filter name=portainer docker logs portainer --tail=100
docker compose -p erpnext-prod \ -f ~/erpnext-prod-compose.yml logs --tail=200
hello-world ausführen.Die Befehle und Hinweise wurden für den Stand 16.09.2026 anhand der aktuellen offiziellen Docker-, Portainer-, Frappe- und Ubuntu-Dokumentation aufgebaut.