Docker Compose: Nginx, PHP-FPM, MySQL, WordPress Setup
Docker Compose: Nginx, PHP-FPM, MySQL, WordPress Setup
Hey everyone! Today, we’re diving deep into the awesome world of Docker Compose to set up a killer WordPress environment. If you’re a web developer, sysadmin, or just someone who loves to tinker with websites, you know how much of a pain it can be to get all your services talking to each other. We’re talking Nginx, PHP-FPM, MySQL, and of course, the ever-popular WordPress. Manually configuring each of these can be a real headache, right? Well, that’s where Docker Compose swoops in to save the day! It lets you define and run multi-container Docker applications with just a single YAML file. Think of it as your ultimate cheat sheet for spinning up complex environments quickly and consistently. No more ‘it works on my machine’ excuses, guys! This article is going to walk you through, step-by-step, how to get your local development server humming with all these essential components, making your WordPress development workflow smoother than a fresh coat of paint.
Table of Contents
We’ll cover everything from installing Docker and Docker Compose (if you haven’t already, get on it!), to writing that magical
docker-compose.yml
file that will be the heart of our setup. We’ll break down what each service does – Nginx as our super-fast web server, PHP-FPM to process all that dynamic WordPress code, MySQL to store all your precious data, and finally, WordPress itself, sitting on top of it all. By the end of this, you’ll have a robust, reproducible development environment that you can easily share with your team or deploy to a server. So, grab your favorite beverage, settle in, and let’s get this party started! We’re going to make setting up complex web applications as easy as pie. Get ready to level up your development game!
Why Docker Compose for WordPress?
So, you’re probably wondering, “Why go through the hassle of Docker Compose when I can just install everything directly on my machine?” Great question, guys! Let me tell you, Docker Compose is an absolute game-changer, especially when you’re dealing with multi-service applications like a typical WordPress setup. First off, let’s talk consistency . How many times have you set up a WordPress site on your local machine, and it worked perfectly, only to find it breaks on the staging or production server because of slight differences in configurations or dependencies? It’s infuriating! Docker Compose solves this by packaging each service (Nginx, PHP-FPM, MySQL) into its own isolated container with all its dependencies. This means your development environment mirrors your production environment much more closely, drastically reducing those nasty ‘works on my machine’ bugs. It’s like having a portable, perfect replica of your entire server stack ready to go wherever you need it.
Another massive win is
speed and ease of setup
. Remember the old days of painstakingly installing PHP versions, configuring web servers, setting up database users, and fiddling with permissions? Yeah, me neither (kidding!). With Docker Compose, you define your entire application stack in a single
docker-compose.yml
file. Need to spin up your WordPress environment? Just run
docker-compose up -d
. Boom! All your containers are built, configured, and running in minutes. Need to tear it all down?
docker-compose down
. It’s that simple. This makes setting up new projects, onboarding new team members, or even experimenting with different configurations incredibly fast and painless. Plus, it keeps your host machine clean! No more installing tons of software that might conflict with other projects. Everything lives inside its own container, leaving your main OS pristine.
Finally,
reproducibility and collaboration
are massive advantages. Because your entire environment is defined in code (that
docker-compose.yml
file), it’s easily version-controlled. You can commit it to your Git repository alongside your WordPress code. This means anyone on your team can pull the code and spin up the exact same environment with a single command. It ensures everyone is working with the same tools and versions, eliminating discrepancies and making collaboration seamless. If you need to document your setup, the
docker-compose.yml
file
is
the documentation. It’s clear, concise, and actionable. So, for any serious WordPress developer or team, using Docker Compose isn’t just a convenience; it’s a fundamental improvement to the entire development lifecycle. It saves time, reduces errors, and makes working with complex stacks a breeze. Seriously, guys, once you start using it, you’ll wonder how you ever lived without it!
Setting Up Your Environment
Alright, let’s get down to business and start building our
Docker Compose
setup for WordPress. Before we jump into the
docker-compose.yml
file, you’ll need to have Docker and Docker Compose installed on your machine. If you don’t have them yet, head over to the official Docker website and follow their installation guide for your operating system. It’s usually a straightforward process. Once that’s done, create a new directory for your WordPress project. Let’s call it
my-wordpress-site
. Inside this directory, create a new file named
docker-compose.yml
. This file is where all the magic happens – it defines the services, networks, and volumes for our application.
Now, let’s break down the
docker-compose.yml
file. We’ll need three main services: one for our database (MySQL), one for our PHP processing (PHP-FPM), and one for our web server (Nginx). We’ll also need a WordPress application service, which will essentially tie everything together and serve our site. Here’s a basic structure to get us started:
version: '3.8'
services:
db:
image: mysql:8.0
container_name: wordpress_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_strong_root_password
MYSQL_DATABASE: wordpress_db
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: your_strong_user_password
volumes:
- db_data:/var/lib/mysql
networks:
- wordpress-network
phpmyadmin:
image: phpmyadmin:latest
container_name: wordpress_phpmyadmin
restart: always
ports:
- '8080:80'
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: your_strong_root_password
depends_on:
- db
networks:
- wordpress-network
wordpress:
build:
context: .
dockerfile: Dockerfile.wordpress
container_name: wordpress_app
restart: always
volumes:
- ./wordpress:/var/www/html
ports:
- '8000:80'
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress_db
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: your_strong_user_password
depends_on:
- db
networks:
- wordpress-network
volumes:
db_data:
networks:
wordpress-network:
driver: bridge
This
docker-compose.yml
file sets up our database, PHP-FPM, and WordPress application. Notice the
db
service uses the official
mysql:8.0
image, defines environment variables for the database credentials, and uses a named volume
db_data
to persist our database data even if the container is removed. The
wordpress
service uses a custom
Dockerfile.wordpress
which we’ll create next. It maps a local directory
./wordpress
to the web root inside the container for our WordPress files and exposes port 8000 on the host to port 80 in the container. It also sets environment variables for WordPress to connect to our
db
service. The
depends_on
clause ensures the database starts before the WordPress application.
The WordPress Dockerfile
Now, let’s create the
Dockerfile.wordpress
file in the same directory as your
docker-compose.yml
. This file will define our PHP-FPM environment. We’ll use an official PHP image with the Nginx web server installed and configured for PHP-FPM. Here’s what it looks like:
FROM php:8.2-fpm
# Install necessary extensions for WordPress
RUN apt-get update && apt-get install -y \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libssl-dev \
libzip-dev \
unzip \
git \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install -j$(nproc) gd mbstring zip exif pcntl
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
# Configure PHP-FPM
COPY php.ini /usr/local/etc/php/conf.d/custom.ini
# Set working directory
WORKDIR /var/www/html
# Download and install WordPress
RUN curl -O https://wordpress.org/latest.tar.gz && tar xzf latest.tar.gz && mv wordpress/* .
# Permissions for Nginx
RUN chown -R www-data:www-data /var/www/html
RUN chmod -R 755 /var/www/html
This
Dockerfile.wordpress
starts with a PHP 8.2 FPM base image. It then installs essential PHP extensions that WordPress relies on, like GD for image manipulation and Zip for plugin/theme installations. We also install Composer, the PHP package manager, which is super handy. Crucially, we copy a custom
php.ini
file (which we’ll create next) to fine-tune our PHP settings. Then, we set the working directory to
/var/www/html
and download the latest WordPress core files directly into it. Finally, we ensure the web server (
www-data
user) has the correct permissions to read and write files in the WordPress directory. This setup ensures our PHP environment is ready to go for WordPress.
Nginx Configuration
Now, we need to configure Nginx to serve our WordPress site and pass PHP requests to PHP-FPM. Create a new file named
nginx.conf
in the root of your project directory (alongside
docker-compose.yml
). Here’s a sample configuration:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?q=$request_uri;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;$document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_pass php-fpm:9000;
}
location ~ /\.ht {
deny all;
}
# Add other Nginx configurations as needed
}
This
nginx.conf
sets up Nginx to listen on port 80. It defines the document root as
/var/www/html
, where WordPress is installed. The
location /
block handles regular file requests, and the crucial
location ~ \.php$
block tells Nginx how to pass PHP files to the PHP-FPM service. Notice
fastcgi_pass php-fpm:9000;
. This is important! In our
docker-compose.yml
, we used
wordpress
as the service name for PHP-FPM. However, when Nginx is running in its own container, it needs to know how to reach the PHP-FPM container. By default, Docker Compose creates a network where containers can reach each other using their service names. So, if we name our PHP-FPM service
php-fpm
instead of
wordpress
in
docker-compose.yml
, Nginx can correctly communicate with it. Let’s update our
docker-compose.yml
to reflect this. Also, we’ll need to mount this
nginx.conf
into our Nginx container. For simplicity, we’ll create a separate Nginx service definition in
docker-compose.yml
.
Updating Docker Compose for Nginx
Let’s add an Nginx service to our
docker-compose.yml
and adjust the PHP-FPM service name. Create a new file called
Dockerfile.nginx
as well.
Updated
docker-compose.yml
:
version: '3.8'
services:
db:
image: mysql:8.0
container_name: wordpress_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_strong_root_password
MYSQL_DATABASE: wordpress_db
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: your_strong_user_password
volumes:
- db_data:/var/lib/mysql
networks:
- wordpress-network
phpmyadmin:
image: phpmyadmin:latest
container_name: wordpress_phpmyadmin
restart: always
ports:
- '8080:80'
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: your_strong_root_password
depends_on:
- db
networks:
- wordpress-network
php-fpm:
build:
context: .
dockerfile: Dockerfile.wordpress
container_name: wordpress_php_fpm
volumes:
- ./wordpress:/var/www/html
networks:
- wordpress-network
nginx:
image: nginx:latest
container_name: wordpress_nginx
ports:
- '80:80'
volumes:
- ./wordpress:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php-fpm
networks:
- wordpress-network
volumes:
db_data:
networks:
wordpress-network:
driver: bridge
New
Dockerfile.nginx
:
FROM nginx:latest
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Ensure Nginx can access PHP-FPM
RUN touch /etc/nginx/conf.d/default.conf # Ensure the file exists
# You might need to add configurations to allow Nginx to resolve 'php-fpm' if using older Docker versions or custom networks.
# Usually, Docker Compose handles this automatically.
In the updated
docker-compose.yml
, we renamed the WordPress service to
php-fpm
for clarity in Nginx configuration. We’ve added a new
nginx
service that uses the official Nginx image. It maps port 80 on the host to port 80 in the container, mounts our local WordPress files, and crucially, mounts our custom
nginx.conf
to override the default Nginx configuration. The
depends_on: - php-fpm
ensures Nginx starts after PHP-FPM is ready. Now, Nginx will correctly pass PHP requests to the
php-fpm
service using its network name. You can now access your WordPress site by navigating to
http://localhost
in your browser.
PHP Configuration (php.ini)
To fine-tune your PHP environment, create a
php.ini
file in your project root. Here are some recommended settings for WordPress:
memory_limit = 256M
post_max_size = 64M
upload_max_filesize = 64M
max_execution_time = 300
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
session.save_path = "/var/lib/php/sessions"
This
php.ini
file provides essential configurations.
memory_limit
and
post_max_size
are increased to handle larger uploads and more complex operations common in WordPress.
max_execution_time
allows longer scripts to run, which can be useful during plugin installations or updates.
display_errors
and
error_reporting
are helpful for debugging during development. We also configure a
session.save_path
for PHP sessions. This file will be copied into our PHP-FPM container by the
Dockerfile.wordpress
we created earlier. Make sure these settings are suitable for your development needs.
Running Your WordPress Site
With all the configuration files in place –
docker-compose.yml
,
Dockerfile.wordpress
,
Dockerfile.nginx
, and
nginx.conf
– we’re ready to bring our WordPress site to life! Open your terminal or command prompt, navigate to the root directory of your project (where
docker-compose.yml
is located), and run the following command:
docker-compose up -d
This command tells Docker Compose to build the images (if they don’t exist) and start all the services defined in your
docker-compose.yml
file in detached mode (
-d
), meaning they’ll run in the background. Docker Compose will pull the necessary images (MySQL, Nginx, PHP base), build your custom PHP image, create the network, and start the containers. It might take a few minutes the first time as it downloads images and builds your custom PHP container.
Once the command completes without errors, you can check the status of your containers using:
docker-compose ps
You should see your
db
,
php-fpm
, and
nginx
containers running. Now, head over to your web browser and navigate to
http://localhost
. You should be greeted by the familiar WordPress installation screen! Follow the on-screen prompts to set up your WordPress site, database name, username, and password. Remember to use the credentials you defined in your
docker-compose.yml
file (e.g.,
wordpress_db
,
wordpress_user
, and
your_strong_user_password
).
If you want to access phpMyAdmin to manage your database directly, you can navigate to
http://localhost:8080
. Use
root
as the username and
your_strong_root_password
(the one you set in
docker-compose.yml
) as the password to log in.
Stopping and Managing Your Environment
When you’re done working on your WordPress site for the day, you’ll want to stop the containers to free up resources. Navigate back to your project’s root directory in the terminal and run:
docker-compose down
This command stops and removes all the containers, networks, and volumes created by
docker-compose up
. If you want to stop the containers but keep the volumes (so your database data and WordPress files are preserved), you can use
docker-compose stop
. To start them again later, just run
docker-compose up -d
from the same directory.
If you ever need to see the logs from your containers, you can use:
docker-compose logs -f [service_name]
Replace
[service_name]
with the name of the service you want to check (e.g.,
db
,
php-fpm
,
nginx
). The
-f
flag will follow the logs in real-time.
For managing the WordPress files, remember we mapped
./wordpress
from your host machine to
/var/www/html
inside the containers. Any changes you make to files in the
./wordpress
directory on your host will be reflected inside the container, and vice-versa. This makes it super easy to edit your WordPress theme, plugins, or core files directly using your favorite code editor.
And that’s it, guys! You’ve successfully set up a fully functional, isolated WordPress development environment using Docker Compose. This setup is not only easy to manage but also highly reproducible, which is a massive win for any developer or team. You can now focus on building awesome websites without worrying about environment inconsistencies. Happy coding!