Docker Compose and WordPress
Summary
This chapter walks through building and deploying a WordPress stack with Docker. It begins with a local development environment using Docker Desktop, then moves the same stack to AWS Lightsail using Docker’s remote SSH connection support.
The stack includes three main components:
- WordPress for the website application.
- MySQL for the database.
- WP-CLI for managing WordPress from the command line.
These services are managed together using Docker Compose.
WordPress Docker Compose Stack
Clone the Sample Project
Before starting the WordPress stack, clone the sample project from GitHub:
git clone https://github.com/acj1971/wordpressawslightsailsamples
Then move into the sample folder for this chapter:
cd wordpressawslightsailsamples/Docker_Compose_and_Wordpress
This folder contains the docker-compose.yml file used throughout this chapter:
services:
mysql:
image: mysql:latest
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- wp-network
wordpress:
image: wordpress:latest
container_name: wordpress
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
ports:
- "80:80"
volumes:
- wp_html:/var/www/html
depends_on:
- mysql
networks:
- wp-network
wpcli:
image: wordpress:cli
container_name: wpcli
depends_on:
- wordpress
entrypoint: wp
working_dir: /var/www/html
volumes:
- wp_html:/var/www/html
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
networks:
- wp-network
volumes:
wp_html:
external: true
mysql_data:
external: true
networks:
wp-network:
Understanding a Docker Compose File for WordPress
Services
services:
The Docker Compose file defines a basic WordPress environment made up of three services. Each service runs in its own container and communicates with the other services through the same Docker network.
MySQL Service
mysql:
The mysql service runs the MySQL database container. It sets the root password, creates the WordPress database, and creates a WordPress database user. The database files are stored in the external mysql_data volume so they can be retained even if the container is recreated.
Image
image: mysql:latest
Using mysql:latest tells Docker to pull the most recent MySQL image rather than a fixed version. This can help keep the setup current, but the underlying version may change over time.
For a more predictable production setup, it is usually safer to pin the image to a specific version, such as 8.4. Upgrading between major versions or LTS releases can introduce compatibility or upgrade issues, so version changes should be planned carefully.
Container Name
container_name: mysql
This assigns the container the fixed name mysql, making it easier to identify and manage when using Docker commands, logs, and other administration tasks.
Restart
restart: always
This tells Docker to automatically restart the container if it stops or if the server is restarted. For a database service such as MySQL, this helps keep the WordPress stack available after a restart.
Environment
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
This section configures the initial MySQL setup. It sets the root password, creates the WordPress database, and creates a WordPress database user with a password. These values are then used by the WordPress container when connecting to MySQL.
In this example, the values are written directly in the Compose file for clarity. In a later chapter, these values will be managed using Docker Secrets for improved security.
Options Explained
MYSQL_ROOT_PASSWORDsets the password for the MySQL root user. In a later step, this value should be managed using Docker Secrets for improved security.MYSQL_DATABASEdefines the database that MySQL creates when the container starts for the first time.MYSQL_USERcreates a database user account when the container starts.MYSQL_PASSWORDsets the password for the database user account. In a later step, this value should be managed using Docker Secrets for improved security.
Ports
ports:
- "3306:3306"
This maps port 3306 on the host to port 3306 inside the MySQL container. Port 3306 is the standard MySQL port, and this mapping allows external access to the database if required.
WordPress does not require this host port mapping when both containers are connected to the same Docker network. In that case, WordPress connects internally using mysql:3306.
Volumes
volumes:
- mysql_data:/var/lib/mysql
This volume mapping connects the Docker volume mysql_data to /var/lib/mysql inside the container. This directory is where MySQL stores its database files.
Networks
networks:
- wp-network
Docker Compose networks allow containers to communicate without relying on fixed IP addresses. When services are connected to the same network, they can find and connect to each other by service name.
In this setup, wp-network provides communication between WordPress, MySQL, and WP-CLI.
WordPress Service
wordpress:
The wordpress service runs the main WordPress website using the selected WordPress image. It connects to the MySQL database using the settings provided in the environment variables. Port 80 is mapped so the site can be opened in a web browser, and the WordPress files are stored in the external wp_html volume.
The WordPress service also depends on the MySQL service, so Docker Compose starts the database container before starting WordPress.
Image
image: wordpress:latest
Using wordpress:latest tells Docker to use the most recent WordPress image available. This can include the latest bug fixes, security updates, and feature improvements.
For production environments, consider using a specific image tag so that updates can be tested before being applied.
Container Name
container_name: wordpress
This assigns the container the fixed name wordpress, making it easier to identify and manage when using Docker commands.
Restart
restart: always
This tells Docker to automatically restart the WordPress container if it stops or if the server is restarted. For a web service such as WordPress, this helps keep the site available when the stack restarts.
Environment
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
This section configures how the WordPress container connects to the MySQL database. It defines the database host, database name, username, and password used by WordPress.
These values must match the MySQL service settings so WordPress can communicate with the database correctly. In this example, the values are written directly in the Compose file for clarity, although Docker Secrets should be used for improved security.
Options Explained
WORDPRESS_DB_HOSTtells WordPress how to connect to the database service. In this setup,mysql:3306points to the MySQL service on the Docker network.WORDPRESS_DB_NAMEdefines the name of the database WordPress will use.WORDPRESS_DB_USERdefines the username WordPress uses when connecting to the database service.WORDPRESS_DB_PASSWORDdefines the password WordPress uses when authenticating with the database service.
For improved security, sensitive credentials such as the database password should be managed using Docker Secrets.
Ports
ports:
- "80:80"
This maps port 80 on the host to port 80 inside the WordPress container, allowing the site to be accessed in a web browser. Port 443 can be added in a later chapter to support HTTPS.
Volumes
volumes:
- wp_html:/var/www/html
This volume mapping connects the Docker volume wp_html to /var/www/html inside the container. This is where WordPress stores its site files, including the wp-content folder.
Depends On
depends_on:
- mysql
The depends_on setting tells Docker Compose to start the mysql service before the wordpress service. This helps ensure that the database container starts first, so WordPress can connect to it during startup.
Networks
networks:
- wp-network
For the WordPress service, the Docker network allows it to communicate with MySQL and WP-CLI using service names instead of fixed IP addresses. In this setup, wp-network provides that internal connection.
WP-CLI Service
wpcli:
The wpcli service runs the WordPress CLI image, which allows you to manage the WordPress site from the command line. It uses wp as its entry point, works from /var/www/html, and shares the same wp_html volume as the WordPress service so it can access the same site files.
It also uses the same database connection settings as the WordPress service, ensuring WP-CLI commands operate against the same WordPress installation.
Image
image: wordpress:cli
Using wordpress:cli tells Docker to use the WordPress CLI image. This image provides the wp command-line tool for managing a WordPress site.
Container Name
container_name: wpcli
This assigns the container the fixed name wpcli, making it easier to identify and manage when using Docker commands.
Depends On
depends_on:
- wordpress
This setting tells Docker Compose to start the wordpress service before the wpcli container.
Entrypoint
entrypoint: wp
This configures the container to use wp as its default command. As a result, WP-CLI commands can be run without specifying wp each time.
For example:
docker compose run --rm wpcli plugin list
Working Directory
working_dir: /var/www/html
This specifies /var/www/html as the working directory inside the container. It helps ensure that commands run from the WordPress root directory.
Volumes
volumes:
- wp_html:/var/www/html
This volume mapping connects the Docker volume wp_html to /var/www/html inside the container. By sharing the same volume as the WordPress service, WP-CLI can work with the same WordPress files.
Environment
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
The environment variables in the wpcli service mirror those used by the wordpress service because both containers connect to the same WordPress database. This ensures that WP-CLI commands operate on the same site data and configuration as the main WordPress application.
Networks
networks:
- wp-network
For the wpcli service, the Docker network allows it to communicate with WordPress and MySQL using service names instead of fixed IP addresses. In this setup, wp-network provides that internal connection.
Volumes
volumes:
wp_html:
external: true
mysql_data:
external: true
This section defines two named Docker volumes: wp_html and mysql_data.
wp_htmlstores the WordPress website files.mysql_datastores the MySQL database files.external: truetells Docker Compose to use an existing Docker volume rather than creating a new one.
This approach helps ensure that important data is stored independently of the containers, allowing it to persist even if the containers are recreated or updated.
Networks
networks:
wp-network:
The networks section defines a custom Docker network named wp-network.
Docker Compose networks provide a straightforward way for containers to communicate without relying on fixed IP addresses. By connecting services to the same network, Docker allows them to discover and connect to one another using their service names.
In this stack, wp-network enables communication between WordPress, MySQL, and WP-CLI.
Start the WordPress Stack Using Docker Desktop
From inside the project folder wordpressawslightsailsamples/Docker_Compose_and_Wordpress, run:
docker compose up -d
Options Explained
docker composemanages multi-container applications using a Compose file.upcreates and starts the services defined indocker-compose.yml.-druns the containers in the background in detached mode.
What Starts Automatically
Docker Compose will create and start the following services:
mysqlinitializes the database and stores data in themysql_datavolume.wordpressruns the web server and serves the site on port80.wpcliprovides the command-line tool for managing the WordPress site.
On the first run, Docker downloads the required images:
mysqlwordpresswordpress:cli
Docker then creates the containers, connects them to the wp-network, and attaches the external volumes wp_html and mysql_data to the appropriate services.
Verify the Stack Is Running
Option 1: Command Line
Run the following command:
docker compose ps
You should see the WordPress, MySQL, and WP-CLI services listed.
Option 2: Docker Desktop UI
Open Docker Desktop and locate the project container group, for example:
wordpress-docker
You should see the following services listed:
mysqlwordpresswpcli
You can click each container to:
- View logs.
- Inspect environment variables.
- Restart or stop the container.
Option 3: Start the Stack and Configure WordPress with WP-CLI
Start the WordPress stack in the background:
docker compose up -d
Once the containers are running, you can use WP-CLI to complete the initial WordPress setup from the command line. This will be covered in more detail in the Docker and WP-CLI chapter.
docker compose run --rm wpcli core install --url="http://localhost" \
--title="My WordPress Site" \
--admin_user="admin" \
--admin_password="password" \
--admin_email="admin@example.com"
Options Explained
docker composemanages multi-container applications using a Compose file.run --rmstarts a temporary container and removes it when the command finishes.wpcliis the Docker Compose service that runs WP-CLI.core installruns thewp core installcommand.--url="http://localhost"sets the URL for the new site.--title="My WordPress Site"sets the name of the new site.--admin_user="admin"sets the username for the site administrator.--admin_password="password"sets the password for the administrator account. If this option is not supplied, WordPress can generate a secure password automatically.--admin_email="admin@example.com"sets the email address for the administrator account.
Access WordPress
Once the containers are running, open a web browser and go to:
http://localhost
This opens the local WordPress site. On the first visit, WordPress should display the initial setup screen unless the site has already been configured with WP-CLI.
View Logs for Troubleshooting
To view container logs, run:
docker compose logs -f
Options Explained
docker composemanages multi-container applications using a Compose file.logsdisplays log output from the containers.-ffollows the logs in real time.
Stop the Stack
When you have finished working with the WordPress stack, you can stop the running containers using:
docker compose down
Because this project uses external Docker volumes, the following volumes are retained:
wp_htmlfor the WordPress website files.mysql_datafor the MySQL database files.
Use Docker Compose with AWS Lightsail
The same Docker Compose stack can also be managed remotely on an AWS Lightsail instance. In this example, Docker connects to the Lightsail server over SSH using the Docker -H option.
Verify Remote Docker Access
First, confirm that Docker is available on your Lightsail instance:
docker -H ssh://MyUbuntuInstance info
Options Explained
dockerruns the Docker command-line interface.-H ssh://MyUbuntuInstancetells Docker to connect to the remote Docker host namedMyUbuntuInstanceover SSH.inforequests detailed information about the Docker environment on the remote host.
Start the WordPress Stack with Docker Compose
Once remote Docker access has been verified, start the WordPress, MySQL, and WP-CLI services on MyUbuntuInstance:
docker -H ssh://MyUbuntuInstance compose up -d
Options Explained
dockerruns the Docker command-line interface.-H ssh://MyUbuntuInstanceconnects Docker to the remote Lightsail instance over SSH.composeruns Docker Compose commands against the selected Docker host.upcreates and starts the services defined indocker-compose.yml.-druns the containers in the background in detached mode.
Retrieve the Lightsail Static IP Address
Using the AWS CLI, you can retrieve the current static IP address assigned to the Lightsail instance MyUbuntuInstance:
aws lightsail get-static-ip --static-ip-name MyUbuntuInstanceStaticIP --region ap-southeast-2 --profile MyUbuntuProfile
Access WordPress Remotely
Once the containers are running, open a web browser and go to:
http://ipAddress
Replace ipAddress with the static IP address returned by the AWS CLI command.
Stop the WordPress Stack with Docker Compose
To gracefully stop the WordPress stack running on the remote Lightsail instance and remove the containers associated with the application, run:
docker -H ssh://MyUbuntuInstance compose down
Because this project uses external Docker volumes, the following volumes are retained:
wp_htmlfor the WordPress website files.mysql_datafor the MySQL database files.
This means the site files and database are preserved even after the containers are removed.
Further Reading
- Docker Compose
- Services in Docker Compose
- MySQL Docker Official Image
- MySQL Docker environment variables
- Networking in Compose
- WordPress Docker Official Image
- WP-CLI
- wp core install

Leave a Reply
You must be logged in to post a comment.