How to Install or Migrate WordPress on Docker


Setting up a reliable WordPress development environment has always been a pain point for developers. Between XAMPP installations, virtual machine configurations, and the notorious “it works on my machine” syndrome, local WordPress development can consume hours before you even write your first line of code. That changes today with this comprehensive WordPress Docker boilerplate that transforms setup complexity into a single command execution.

This isn’t just another Docker compose file – it’s a production-grade boilerplate that solves real development workflow problems with intelligent automation, proper user permission handling, and built-in database management. Let’s dive deep into how this solution revolutionizes WordPress development

WordPress Docker Boilerplate Setup Workflow

The Problem with Traditional WordPress Development

Most WordPress developers have experienced the frustration of environment setup. Traditional approaches suffer from several critical issues:

Permission Nightmares: Files created by Docker containers often belong to www-data or root, making them impossible to edit from your host system. This forces developers into awkward permission fixes or constant sudo usage.

Database Management Complexity: Setting up phpMyAdmin, managing MySQL connections, and handling database imports/exports typically requires separate tools and configurations.

Environment Inconsistency: Different developers work with different PHP versions, MySQL configurations, and server setups, leading to compatibility issues when code moves between environments.

Tedious Reconfiguration: Every new project requires manual setup of database connections, URL configurations, and plugin installations.

This WordPress Docker boilerplate eliminates every single one of these problems with a sophisticated yet simple approach.

Architecture Overview: How the Magic Works

WordPress Docker Container Architecture

The boilerplate creates a containerized ecosystem with three primary services working in perfect harmony:

WordPress Container (wp_app): Runs the latest WordPress with proper user permission mapping, accessible at localhost:8080.

MySQL Database Container (wp_db): Provides persistent MySQL 8.0 storage with automatic initialization and proper networking.

Adminer Container (wp_adminer): Offers web-based database management at localhost:8081, eliminating the need for separate database tools.

All containers communicate through a dedicated wpsite network, ensuring isolated and secure inter-service communication. The architecture uses intelligent volume mapping to maintain data persistence while solving the notorious Docker permission problems.

File Structure Breakdown: Every Component Explained

The boilerplate’s power lies in its carefully crafted file organization. Here’s what makes each component essential:

compose.yml: The Orchestration Master

services:
  db:
    image: ${MYSQL_IMAGE_TAG}
    container_name: wp_db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      # Additional MySQL configuration
    volumes:
      - db_data:/var/lib/mysql
      - ./db:/docker-entrypoint-initdb.d
    networks:
      - wpsite

  wordpress:
    image: ${WORDPRESS_IMAGE_TAG}
    container_name: wp_app
    restart: unless-stopped
    user: "${UID:-1000}:${GID:-1000}"
    depends_on:
      - db
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: ${MYSQL_HOST}
      # WordPress configuration from .env
    volumes:
      - ./wp-content:/var/www/html/wp-content
    networks:
      - wpsite

  adminer:
    image: adminer
    container_name: wp_adminer
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "8081:8080"
    networks:
      - wpsite

The genius is in the details: Environment variable substitution makes configuration flexible, user mapping solves permission issues, and the dependency chain ensures proper startup order.

.env: Configuration Without Complexity

The environment file centralizes all customizable settings:

SITE_URL=http://localhost:8080
WORDPRESS_TABLE_PREFIX=wput_
WORDPRESS_DEBUG=true
WORDPRESS_IMAGE_TAG=wordpress:latest
MYSQL_IMAGE_TAG=mysql:8.0
MYSQL_ROOT_PASSWORD=root_pass
MYSQL_DATABASE=wp_db
MYSQL_USER=wp_user
MYSQL_PASSWORD=wp_passss
MYSQL_HOST=db:3306

This approach enables instant environment switching – simply change values in .env to work with different configurations, databases, or WordPress versions.

start.sh: Intelligent Automation

The startup script is where this boilerplate truly shines. It’s not just a simple docker-compose wrapper – it’s a smart automation system:

#!/bin/sh
export UID=$(id -u)
export GID=$(id -g)

# Parse command-line arguments for different modes
for arg in "$@"; do
  case $arg in
    --rebuild|-r) ACTION="rebuild" ;;
    --reset-db) ACTION="reset-db" ;;
    --yes|-y) AUTO_CONFIRM=true ;;
    --detach|-d) DETACH=true ;;
    --help|-h) print_help; exit 0 ;;
  esac
done

# Generate dynamic SQL for site URL updates
cat << EOF > "$SQL_FILE"
UPDATE ${TABLE_PREFIX}options SET option_value='${SITE_URL}' WHERE option_name='home' OR option_name='siteurl';
EOF

Key automation features:

  1. Automatic UID/GID export eliminates permission problems by mapping container users to your host user
  2. Dynamic SQL generation ensures WordPress URLs match your environment configuration
  3. Multiple operational modes handle different development scenarios (fresh start, database reset, complete rebuild)
  4. Safety confirmations prevent accidental data loss during destructive operations

Database Initialization: Pre-Configured and Ready

The db/ directory contains SQL files that automatically execute during MySQL initialization:

  • 01-db.sql: Complete WordPress database structure with pre-installed plugins and configuration
  • 02-siteurl.sql: Dynamically generated URL configuration (created by start.sh)

This eliminates the tedious WordPress setup wizard and provides a ready-to-code environment immediately.

Solving the Permission Problem: The Technical Breakthrough

Traditional Docker WordPress setups fail because container processes run as different users than your host system. Files created inside containers become uneditable outside containers. This boilerplate solves it with intelligent user mapping:

# In start.sh
export UID=$(id -u)
export GID=$(id -g)

# In compose.yml
wordpress:
  user: "${UID:-1000}:${GID:-1000}"

How it works: The start script automatically detects your host user ID and group ID, then passes them to Docker Compose. The WordPress container runs with YOUR user permissions, ensuring all files remain editable from your host system.

This is a game-changing solution that most Docker tutorials completely ignore.

Database Management: Adminer Integration

Instead of requiring separate phpMyAdmin installation or complex MySQL command-line usage, this boilerplate includes Adminer – a lightweight, powerful database management tool.

Access your database at localhost:8081 with these credentials:

  • System: MySQL
  • Server: db
  • Username: wp_user
  • Password: wp_passss
  • Database: wp_db

Adminer advantages over phpMyAdmin:

  • Single PHP file deployment
  • Better performance and security
  • Support for multiple database systems
  • Modern, intuitive interface
  • No additional configuration required

Step-by-Step Setup Guide: From Clone to Code

Ready to revolutionize your WordPress development? Here’s the complete setup process:

1. Clone and Initialize

git clone https://github.com/aniketan/wordpress-docker-boilerplate.git
cd wordpress-docker-boilerplate
chmod +x start.sh

2. Customize Configuration (Optional)

Edit the .env file to match your preferences:

# Change site URL if needed
SITE_URL=http://localhost:8080

# Customize database credentials
MYSQL_PASSWORD=your_secure_password

# Enable/disable WordPress debugging
WORDPRESS_DEBUG=true

3. Launch Your Environment

# Standard startup
./start.sh

# Detached mode (run in background)
./start.sh --detach

# Complete rebuild (removes all data)
./start.sh --rebuild --yes

4. Access Your Development Environment

  • WordPress Sitehttp://localhost:8080
  • WordPress Adminhttp://localhost:8080/wp-admin
  • Database Managerhttp://localhost:8081

Default Login Credentials:

  • Username: admin_tty
  • Password: (check the database or reset via Adminer)

Advanced Usage: Power User Features

Rebuild and Reset Operations

The start script provides sophisticated operational modes for different development scenarios:

# Complete environment rebuild (removes ALL data)
./start.sh --rebuild

# Reset only database (keeps WordPress files)
./start.sh --reset-db

# Automatic confirmation (no prompts)
./start.sh --rebuild --yes

# Background operation
./start.sh --detach

Troubleshooting: Common Issues and Solutions

Permission Denied Errors

Problem: Cannot edit files in wp-content directory
Solution: Ensure start.sh is executable and user mapping is working:

chmod +x start.sh
./start.sh --rebuild

Port Conflicts

Problem: Port 8080 or 8081 already in use
Solution: Modify ports in compose.yml:

ports:
  - "8090:80"  # Change WordPress port

Database Connection Errors

Problem: WordPress cannot connect to MySQL
Solution: Verify environment variables and container health:

# Check container status
docker ps

# View WordPress logs
docker logs wp_app

# Restart with database reset
./start.sh --reset-db

Security Considerations: Production-Ready Features

This boilerplate implements security best practices suitable for production environments:

Environment Variable Management: Sensitive data stored in .env file, never committed to version control.

Container Isolation: Services communicate through dedicated networks, preventing unauthorized access.

User Permission Control: Proper UID/GID mapping eliminates dangerous root access requirements.

Resource Limitations: Containers run with restart policies to ensure stability.

Regular Updates: Environment variables control image versions for security patch management.

Extending the Boilerplate: Customization Options

Adding SSL/HTTPS Support

Integrate with Traefik or nginx-proxy for SSL termination:

wordpress:
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.wordpress.rule=Host(`localhost`)"
    - "traefik.http.routers.wordpress.tls=true"




Redis Caching Integration

Add Redis for improved performance:

redis:
  image: redis:alpine
  container_name: wp_redis
  networks:
    - wpsite

Multi-site Support

Configure WordPress multisite by modifying environment variables:

WORDPRESS_CONFIG_EXTRA: |
  define('WP_ALLOW_MULTISITE', true);
  define('MULTISITE', true);

Performance Optimization: Speed and Efficiency

This boilerplate is optimized for maximum development efficiency:

Fast Startup Times: Intelligent caching and optimized image selection minimize container startup delays.

Resource Efficiency: Minimal base images and proper resource allocation prevent system overload.

Development Speed: Instant file synchronization and hot-reloading eliminate rebuild cycles.

Database Performance: Optimized MySQL configuration and persistent volumes ensure fast query execution.

Comparison: Why This Boilerplate Wins

FeatureTraditional SetupOther Docker SolutionsThis Boilerplate
Setup TimeHours30+ minutes2 minutes
Permission IssuesConstant problemsManual fixes requiredAutomatically solved
Database ManagementSeparate installationNot includedBuilt-in Adminer
Environment FlexibilityManual reconfigurationLimited optionsComplete .env control
Automation LevelNoneBasicIntelligent scripting
Production ReadinessVariesOften lackingSecurity-focused

Conclusion: The Future of WordPress Development

This WordPress Docker boilerplate represents a paradigm shift in local development practices. By solving fundamental problems like user permissions, database management, and environment consistency, it enables developers to focus on what matters: building amazing WordPress solutions.

The combination of intelligent automation, production-ready security, and developer-friendly features makes this boilerplate the definitive solution for modern WordPress development. Whether you’re building custom themes, developing plugins, or maintaining client sites, this environment provides the reliability and efficiency that professional development demands.

Ready to transform your WordPress workflow? Clone the repository, run the start script, and experience the difference that properly engineered development tools make. Your future self will thank you for making the switch to containerized development done right.

The era of fighting with local development environments is over. Welcome to effortless WordPress development.


Related Resources: