A complete local WordPress development setup using Docker, with automated plugin installation and custom plugin management via Git submodules.
- WordPress with Apache web server
- MySQL database
- phpMyAdmin for database management
- WP-CLI for command-line WordPress management
- Automated plugin installation on startup
- Custom plugin development with Git submodules
- Bind-mounted wp-content for persistent local development
- Docker and Docker Compose
- Git
git clone --recurse-submodules https://github.com/your-username/wordpress-docker.git
cd wordpress-dockerIf you already cloned without submodules:
git submodule update --init --recursiveCreate a .env file in the project root:
# Database
MYSQL_ROOT_PASSWORD=your_root_password
DB_NAME=wordpress
DB_USER=wordpress
DB_PASSWORD=your_db_password
# Ports
WEB_PORT=8012
PHP_MYADMIN_PORT=8081docker compose up -d- WordPress:
http://localhost:8012(or your WEB_PORT) - phpMyAdmin:
http://localhost:8081(or your PHP_MYADMIN_PORT)
| Service | Description | Image |
|---|---|---|
wordpress |
WordPress with Apache | Custom build from Dockerfile |
db |
MySQL database | mysql:latest |
my-wpcli |
WP-CLI for command-line management | Custom build from Dockerfile.wpcli |
phpmyadmin |
Database admin interface | phpmyadmin/phpmyadmin |
wordpress-docker/
├── custom-plugins/ # Git submodules for custom plugins
│ ├── to-tha-top/
│ └── rivedge-image-slider/
├── WordPress/
│ └── wp-content/ # Bind-mounted WordPress content
├── docker-compose.yml # Docker services configuration
├── Dockerfile # WordPress image with extensions
├── Dockerfile.wpcli # WP-CLI image with git
├── wpcli-entrypoint.sh # Plugin installation script
├── wp-config.php # WordPress configuration
├── wordpress.ini # PHP configuration
└── .env # Environment variables (create this)
The following plugins are automatically installed and activated on container startup:
From WordPress.org:
- Prime Mover (backup/migration)
- Create Block Theme (theme development)
- Query Monitor (debugging)
- Google Site Kit (analytics)
Custom Plugins (via submodules):
- to-tha-top
- rivedge-image-slider
To modify which plugins are installed, edit wpcli-entrypoint.sh.
Custom plugins are managed as Git submodules in the custom-plugins/ directory and bind-mounted into WordPress.
- Add the submodule:
git submodule add https://github.com/username/plugin-name.git custom-plugins/plugin-name- Add bind mount to
docker-compose.ymlunder wordpress volumes:
- type: bind
source: "./custom-plugins/plugin-name"
target: "/var/www/html/wp-content/plugins/plugin-name"- Add activation to
wpcli-entrypoint.sh:
wp plugin activate plugin-name --path=/var/www/html || echo "Warning: Failed to activate plugin-name"- Restart containers:
docker compose up -d --force-recreatePull latest changes for all submodules:
git submodule update --remoteOr update a specific plugin:
cd custom-plugins/plugin-name
git pull origin mainAccess WP-CLI commands:
# Interactive shell
docker compose exec my-wpcli sh
# Run single command
docker compose exec my-wpcli wp plugin list --path=/var/www/html
docker compose exec my-wpcli wp user list --path=/var/www/html
docker compose exec my-wpcli wp option get siteurl --path=/var/www/html# Start containers
docker compose up -d
# Stop containers
docker compose down
# Rebuild after Dockerfile changes
docker compose build
docker compose up -d
# View logs
docker compose logs -f # All services
docker compose logs -f wordpress # WordPress only
docker compose logs -f my-wpcli # WP-CLI only
# Restart a specific service
docker compose restart my-wpcli
# Force recreate containers
docker compose up -d --force-recreate
# Remove everything including volumes (WARNING: deletes database)
docker compose down -vCheck WP-CLI logs:
docker compose logs my-wpcliThe containers run as user 1000:1000 to match typical host user permissions. If you have issues, check your host user ID with id -u.
Change WEB_PORT or PHP_MYADMIN_PORT in your .env file if ports are already in use.
Ensure the database container is fully started before WordPress:
docker compose logs dbIf WordPress redirects to wrong port, clear browser cache or use incognito mode.
The WordPress image is built locally and tagged as rivedge/wordpress-image:latest. To rebuild:
docker compose build wordpressThe WP-CLI image is built as rivedge-wpcli:latest:
docker compose build my-wpcliGPL-2.0-or-later