Docker Basics – Docker Compose -Portainer Stacks
Eigentlich 3 Themen, welche separate Blogbeiträge sein könnten, aber kurz hier die Einleitung
Docker Basics und Docker Compose
(Ich bin auf einem Windows System und habe dafür Docker Desktop installiert, hier die Dokumentation der Installation für Linux)
docker run hello-word -> wenn das funktioniert, perfekt! Jetzt nur noch alles über Docker Compose machen (zum testen vielleicht die normalen Befehle…)
Datei wie folgt nennen: docker-compose.yaml (kann natürlich auch sonst wie heißen, jedoch ist es einfacher)
Hier ein schneller Aufbau, wie man eine Docker Compose Datei erstellt (Beispiel mit Postgres):
services:
postgres:
image: postgres:16
container_name: postgres
environment:
POSTGRES_DB: test123
POSTGRES_USER: root
POSTGRES_PASSWORD: postgrepassword
TZ: Europe/Berlin
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U root -d test123"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- network-sql
volumes:
postgres_data:
networks:
network-sql:
driver: bridge
Wichtige Bestandteile (kurz erklärt)
- services: Hier definierst du deine Container (z. B.
postgres). - image: Welches Image genutzt wird (
postgres:16). - container_name: Fester Name für den Container (praktisch für
docker exec). - environment: Variablen wie DB-Name, User, Passwort, Zeitzone.
- volumes: Persistente Datenablage →
/var/lib/postgresql/datableibt erhalten. - healthcheck: Prüft, ob der Dienst „gesund“ ist (
pg_isready …). - restart: Neustart-Verhalten (
unless-stopped). - networks: Gemeinsames Netz, damit sich Container finden.
DAS WICHTIGSTE
- Ohne Volume sind Daten weg, sobald der Container entfernt wird.
- Networks: Jeder Container, der irgendwie mit anderen Containern kommunizieren muss, in ein Network zusammenwerfen. Dann lösen sich auch die Servicenamen auf.
Bedeutet: Alle Container in diesem Docker Compose (natürlich auch im gleichen Netzwerk) können nun mitpostgresden SQL-Host erreichen und müssen nicht die interne IP-Adresse nutzen.
Crashkurs in Docker
Networks ansehen:docker network ls
Starten (im Ordner mit docker-compose.yaml):docker compose up -d
Stoppen & entfernen (Container + Network, Volumes bleiben):docker compose down
Logs checken:docker compose logs -f postgres
In den Container springen:docker exec -it postgres bash
(Auch wichtig, docker EXECUTE -Parameter Containername (Was ausgeführt werden soll))
Laufende Container anzeigen:docker ps
Volumes ansehen/löschen (Vorsicht!):docker volume ls / docker volume rm NAME
Portainer Magie
Portainer ein sehr mächtiges Tool zum managen von Containern auf einem oder sogar mehreren Hosts.
Beispiel: Ihr habe einen Linux Server irgendwo bei euch stehen und wollt nicht jedes Mal über ssh und vim nano oder vi docker-compose.yaml Dateien bearbeiten. Perfekt, dafür ist Portainer:
Portainer erstellen mit docker-compose:
services:
portainer:
image: portainer/portainer-ce:latest
ports:
- 9443:9443
volumes:
- data:/data
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
volumes:
data:

Unter Stacks Add stacks den Inhalt von Docker-Compose hinzufügen
Einfaches Beispiel mit WordPress:
services:
db:
# We use a mariadb image which supports both amd64 & arm64 architecture
image: mariadb:10.6.4-focal
# If you really want to use MySQL, uncomment the following line
#image: mysql:8.0.27
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
Hier „veröffentlichen“ wir den Port 80 AUF 80. Das bedeutet, das was links steht, ist das, was wir im Browser oder sonst wo eintragen müssen und rechts, steht der Port, der von WordPress genutzt wird.
Expose ist nur für den internen gebrauch von dem Docker-Compose (Stack). Bedeutet, wir können mehrere Expose 3306 oder 33060 in Docker-Compose Dateien nutzen, sofern diese natürlich in verschiedenen Netzwerken sind.

Jetzt nur noch deployen und das Resultat sich ansehen

Wichtige Hinweise:
Bitte NIEMALS einfach so Docker-Compose Inhalte aus dem Internet ausführen, ohne diese überprüft zu haben, da auch Schadsoftware oder veraltete Software genutzt werden kann.
Mini-Checkliste vor dem Start:
- Quelle prüfen (offizielles/verified Image), Tag/ Digest pinnen.
- Compose auf Risikofelder scannen:
privileged,cap_add,devices, Host-Mounts (/,/proc,/sys, Docker-Socket),network_mode: host, breiteports. - Secrets nicht hardcoden → Docker Secrets/.env nutzen; Passwörter rotieren.
- Image scannen (z. B. Trivy, Docker Scout).
- Wenn möglich non-root laufen lassen, Capabilities droppen, Root-FS read-only.
- Erst isoliert testen (eigenes Network, keine sensiblen Mounts).
Für Dev Environments ist natürlich die Nutzung von Passwörten in Docker-Compose Dateien einfacher, jedoch nicht empfehlenswert. Hier ein Beispiel, wir ihr mit einer .env Datei in einem Stack arbeiten könnt
# --- Images ---
MARIADB_IMAGE=mariadb:10.6.4-focal
WORDPRESS_IMAGE=wordpress:latest
# --- MariaDB ---
MYSQL_ROOT_PASSWORD=somewordpress
MYSQL_DATABASE=wordpress
MYSQL_USER=wordpress
MYSQL_PASSWORD=wordpress
# --- WordPress DB Config ---
WORDPRESS_DB_HOST=db
WORDPRESS_DB_USER=${MYSQL_USER}
WORDPRESS_DB_PASSWORD=${MYSQL_PASSWORD}
WORDPRESS_DB_NAME=${MYSQL_DATABASE}
# --- Host Ports ---
HTTP_PORT=80
services:
db:
image: ${MARIADB_IMAGE}
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
expose:
- "3306"
- "33060"
wordpress:
image: ${WORDPRESS_IMAGE}
ports:
- "${HTTP_PORT}:80"
restart: always
environment:
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST}
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
volumes:
db_data:
Hier dann die entsprechende .env Datei hochladen und schon seid ihr fertig

Share this content:
Kommentar abschicken