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/data bleibt 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 mit postgres den 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:
image-7-1024x208 Docker Basics - Docker Compose -Portainer Stacks

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.

image-8 Docker Basics - Docker Compose -Portainer Stacks

Jetzt nur noch deployen und das Resultat sich ansehen

image-9 Docker Basics - Docker Compose -Portainer Stacks

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, breite ports.
  • 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

image-10 Docker Basics - Docker Compose -Portainer Stacks

Share this content:

Das hast du vielleicht verpasst

shibiadmin
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzererfahrung bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst, und hilft unserem Team zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.