Stand: März 2026
Docker braucht einen Linux-Kernel, um Container auszuführen. Auf macOS gibt’s keinen Linux-Kernel, deshalb muss eine VM im Hintergrund laufen (z. B. mit colima).
Docker Desktop ist ressourcenfressend und träge. Nutze deshalb colima als VM. Mit Docker läuft alles viel schneller als mit LocalWP!
Colima installieren
brew install colimaColima starten
colima startMac ID finden
#Mac User ID
ID
# Auf Mac oft 501, deshalb unten user: "510:20" - sonst Katastrophe mit Berechtigungen.Docker Compose File
Für macOS – ARM und fixe WordPress Installation.
services:
wordpress:
build: .
platform: linux/arm64
ports:
- '8080:80'
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WP_CLI_CACHE_DIR: /dev/null
volumes:
- .:/var/www/html
- ./php-config.ini:/usr/local/etc/php/conf.d/uploads.ini
user: '501:20'
depends_on:
db:
condition: service_healthy
db:
image: mariadb:10.11
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_ROOT_PASSWORD: root
volumes:
- db_data:/var/lib/mysql
command: >
--innodb_buffer_pool_size=256M
--max_allowed_packet=64M
--max_connections=20
--table_open_cache=64
--innodb_file_per_table=1
--innodb_flush_log_at_trx_commit=2
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
healthcheck:
test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-proot']
timeout: 20s
retries: 10
interval: 10s
start_period: 30s
adminer:
image: adminer:4.8.1
platform: linux/arm64
ports:
- '8081:8080'
environment:
ADMINER_DEFAULT_SERVER: db
depends_on:
db:
condition: service_healthy
mailpit:
image: axllent/mailpit:latest
platform: linux/arm64
ports:
- '8026:8025'
- '1026:1025'
environment:
MP_SMTP_AUTH_ACCEPT_ANY: 1
MP_SMTP_AUTH_ALLOW_INSECURE: 1
volumes:
- mailpit_data:/data
volumes:
db_data:
mailpit_data:
Dockerfile
FROM wordpress:6.9.1-php8.3-apache
# WP-CLI installieren
RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \
chmod +x wp-cli.phar && \
mv wp-cli.phar /usr/local/bin/wp
# PHP-Config kopieren
COPY php-config.ini /usr/local/etc/php/conf.d/uploads.ini
WORKDIR /var/www/htmlphp-config.ini in Root Folder
# Upload und Request Limits
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_time = 300
memory_limit = 256M
max_input_vars = 3000
max_file_uploads = 20
# OPcache
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 4000
opcache.revalidate_freq = 2
opcache.validate_timestamps = 1Wohin mit den Files?
- docker-compose.yml
- php-config.ini
- Dockerfile
in Sites/new-wp-site Ordner.
cd Sites
mkdir new-wp-site
cd new-wp-site
touch docker-compose.yml php-config.ini Dockerfile
# Code von oben reinkopierenPlugin und Theme Stack installieren
Füge den ganzen entpackten Plugins und Themes Ordner in new-wp-site mit dazu. So kannst du vorausgewählte Themes und Plugins gleich direkt mitinstallieren.
CLI Skript Automatisierung
Füge in .zshrc Profil aliase für Automatisierungen hinzu.
1. wpsetup dein-ordnername
Erstellt in Sites Ordner einen neuen Ordner mit „dein-ordnername“ und installiert dort WordPress lokal mit den Settings aus dem docker-compose.yml file und der php-config.ini. Es wird zusätzlich wp-cli mitinstalliert. Du bist danach automatisch im Ordner drin.
2. wpinit
Löscht die Standardplugins und Themes und kopiert die Inhalte aus dem Themes und Plugins Ordner in die lokale Entwicklungsumgebung. Mit wp-cli werden noch einige Seiteneinstellungen vorgenommen.
alias wpsetup='function _wpsetup() {
cd ~/Sites && mkdir "$1" && \
cp new-wp-site/{docker-compose.yml,php-config.ini,Dockerfile} "$1/" && \
cd "$1" && docker-compose up -d --build
}; _wpsetup'
alias wpinit='function _wpinit() {
if [ ! -f "docker-compose.yml" ]; then
echo "Fehler: Keine docker-compose.yml gefunden."
return 1
fi
current_dir=$(basename "$PWD")
echo "Initialisiere: $current_dir"
rm -f wp-content/plugins/hello.php
rm -rf wp-content/plugins/akismet
rm -rf wp-content/themes/twentytwentyfive
rm -rf wp-content/themes/twentytwentyfour
rm -rf wp-content/themes/twentytwentythree
rm -f license.txt wp-config-sample.php readme.html
[ -d "$HOME/Sites/new-wp-site/themes" ] && cp -r "$HOME/Sites/new-wp-site/themes/"* wp-content/themes/
[ -d "$HOME/Sites/new-wp-site/plugins" ] && cp -r "$HOME/Sites/new-wp-site/plugins/"* wp-content/plugins/
sleep 5
docker-compose exec -T wordpress wp core install --url=https://gwdev.ch --title="$current_dir" --admin_user=admin --admin_password=admin --admin_email=admin@admin.ch --skip-email
docker-compose exec -T wordpress wp language core install de_DE
docker-compose exec -T wordpress wp site switch-language de_DE
docker-compose exec -T wordpress wp option update timezone_string "Europe/Zurich"
docker-compose exec -T wordpress wp option update home "https://gwdev.ch"
docker-compose exec -T wordpress wp option update siteurl "https://gwdev.ch"
docker-compose exec -T wordpress wp rewrite structure "/%postname%/" --hard
docker-compose exec -T wordpress wp option update default_comment_status closed
docker-compose exec -T wordpress wp option update default_ping_status closed
docker-compose exec -T wordpress wp option update date_format "j. F Y"
docker-compose exec -T wordpress wp option update time_format "G:i"
docker-compose exec -T wordpress wp option update uploads_use_yearmonth_folders 0
docker-compose exec -T wordpress wp theme update --all
docker-compose exec -T wordpress wp plugin update --all
docker-compose exec -T wordpress wp core update
docker-compose exec -T wordpress wp language core update
docker-compose exec -T wordpress wp language plugin update --all
docker-compose exec -T wordpress wp language theme update --all
docker-compose exec -T wordpress wp plugin activate --all
docker-compose exec -T wordpress wp theme activate gwbase
docker-compose exec -T wordpress wp post create --post_type=page --post_title="Home" --post_status=publish
docker-compose exec -T wordpress wp post create --post_type=page --post_title="Impressum" --post_status=publish
docker-compose exec -T wordpress wp post create --post_type=page --post_title="Datenschutz" --post_status=publish
docker-compose exec -T wordpress wp post delete 1 --force
docker-compose exec -T wordpress wp post delete 2 --force
docker-compose exec -T wordpress wp post delete 3 --force
echo "✓ Fertig!"
}; _wpinit'zshrc Aliase
Site öffnen
alias ols=“open https://gwdev.ch“
Backend der Seite öffnen
alias ola=“open https://gwdev.ch/wp-login.php“
Adminer öffnen
alias olad=“open http://localhost:8081″
Mailpit öffnen
alias olm=“open http://localhost:8025″
SMTP Ports für Mailpit
Mit SMTP Plugin mailpit mit Port 1025 – ohne PW.
Docker Container starten
docker compose up -d
# dcuBei Änderungen an bestehendem docker-compose.yml File
docker compose down --remove-orphans
docker compose up -d --remove-orphansAktive Container anzeigen
docker psDocker Container beenden
docker compose down
# dcdAlle Docker Container stoppen
docker stop $(docker ps -q)
# Bei KonfliktenVM stoppen
Da geht gar nichts mehr, da keine Virtual Machine mehr läuft
colima stopProblembehandlung
Ports laufen noch. Wichtig: Hier immer alles beenden bevor du neu beginnst. Wenn du nicht mehr weisst, was genau wo gestartet ist: docker stop $(docker ps -q) egal von wo aus.
Nach löschen von Ordner sind Daten in Volumes noch da!
Volumes mit gleichem Namen sind noch gespeichert und geben bei DB Änderungen Fehler aus raus.
# Alle Volumes anzeigen (auch ungenutzte)
docker volume ls
# Detaillierte Informationen zu einem Volume
docker volume inspect VOLUME_NAME
# Volumes nach Namen filtern
docker volume ls --filter name=wp-kadence
# Einzelnes Volume löschen
docker volume rm VOLUME_NAME
# Alles stoppen und löschen
docker kill $(docker ps -aq)
docker rm $(docker ps -aq)
docker volume rm $(docker volume ls -q)Mehrere Sites?
Jeweils nur an einer arbeiten. Wenn du eine andere willst, docker compose down, dann ins andere verzeichnis und dort docker compose up -d
Geht das Easy?
OMG – wenn du keinen Bock auf Wutanfälle hast, nutze einfach WP Studio oder LocalWP. Docker ist zwar mächtiger und viel flexibler – aber diese ständige Berechtigungs-Kacke. Das ist so mühsam. Ich habe heute Stunden verschwendet alle Berechtigungs-Fehler auszumerzen.
Hat es sich gelohnt? Ja definitiv. Läuft schon viel schneller und stabiler. Aber das war eine richtige Zangengeburt.
Docker ist flexibel erweiterbar
Meine Variante hier ist die easy Variante. Ich habe verschiedene getestet. Die hier ist extrem minimal. Das reicht für mein Setup.
Du kannst All-in mit Docker. WordPress als eigenständige Dependency und nur Verwaltung der wp-config.php und des wp-content Ordners.
Nicht direkt die offiziellen Images laden sondern eigene Zusammenbauen mittels DOCKERFILE – Node, Composer, WP Cli integrieren etc.
Ich nutze oft Subdomains auf Production-Server als Entwicklungs-Sites. WP CLI, Node, Composer, LiteSpeed Cache, SSL, scharfes SMTP – dort ist alles schon vorhanden. Und ich kann Kunden direkt eine PW geschützte Seite zukommen lassen. Für meine eigenen Projekte nutze ich Docker.
Wenn du mit mehreren Entwicklern am gleichen Projekt arbeitest? All-In mit Github – Github Actions, Node, Composer und WP CLI. Sonst wird das viel zu chaotisch.
LocalWP geht trotzdem schneller?
Naja, in nichtmal 1 Minute habe ich alles am laufen mit Docker. Ordner erstellen, File rein, docker compose up -d, und los gehts.