Docker makes it straightforward to run self-contained applications without polluting the host system. WordPress is a perfect candidate: it needs a web server, PHP, and a database — all of which can be isolated in containers and wired together in minutes.
This guide targets Ubuntu Server and assumes Docker is already installed and the docker daemon is running. If you still need to set Docker up, follow the official Docker Engine installation guide for Ubuntu before continuing.
Overview of the Approach
We will spin up two containers:
- MariaDB — stores the WordPress database, with data persisted to the host via a bind mount.
- WordPress (official image) — runs Apache and PHP-FPM, connected to the database container, with the site files persisted to the host.
Data for both containers is stored under /opt/wordpress on the host so that it survives container restarts and upgrades.
Step 1 — Create Persistent Storage Directories
Before starting any containers, create the directories that will hold the database files and WordPress HTML files:
sudo mkdir -p /opt/wordpress/database
sudo mkdir -p /opt/wordpress/html
Step 2 — Pull and Run the MariaDB Container
Pull the latest MariaDB image:
sudo docker pull mariadb
Then start the database container, passing in environment variables to configure the root password, a dedicated WordPress user, that user’s password, and the database name:
docker run \
-e MYSQL_ROOT_PASSWORD=your_root_password \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=your_wpuser_password \
-e MYSQL_DATABASE=wordpress_db \
-v /opt/wordpress/database:/var/lib/mysql \
--name wordpressdb \
-d mariadbCode language: JavaScript (javascript)
Replace your_root_password and your_wpuser_password with strong, unique values. Docker will automatically create the wpuser account and the wordpress_db database on first run.
Verify the Database Container
Find the internal IP address Docker assigned to the container:
docker inspect -f '{{ .NetworkSettings.IPAddress }}' wordpressdbCode language: JavaScript (javascript)
You can optionally test connectivity by logging in with the MySQL client (install with sudo apt install mysql-client if needed):
mysql -u wpuser -h <CONTAINER_IP> -pCode language: HTML, XML (xml)
Enter the wpuser password when prompted. If the MySQL prompt appears, the database container is working correctly. Type exit; to leave the prompt.
Step 3 — Pull and Run the WordPress Container
Pull the official WordPress image:
docker pull wordpress:latestCode language: CSS (css)
Start the WordPress container, linking it to the database container and mapping port 8081 on the host to port 80 inside the container:
docker run \
-e WORDPRESS_DB_USER=wpuser \
-e WORDPRESS_DB_PASSWORD=your_wpuser_password \
-e WORDPRESS_DB_NAME=wordpress_db \
-p 8081:80 \
-v /opt/wordpress/html:/var/www/html \
--link wordpressdb:mysql \
--name wpcontainer \
-d wordpressCode language: JavaScript (javascript)
Key flags explained:
-e WORDPRESS_DB_*— passes database credentials directly to the WordPress image’s entrypoint, which writes them intowp-config.phpautomatically.-p 8081:80— exposes WordPress on port8081of the host machine.-v /opt/wordpress/html:/var/www/html— persists WordPress files (themes, plugins, uploads) on the host.--link wordpressdb:mysql— makes the database container reachable inside the WordPress container as the hostnamemysql. Note:--linkis a legacy Docker feature; see the note below about Docker Compose for a more maintainable alternative.
Step 4 — Complete the WordPress Installation
Open a browser and navigate to:
http://<HOST_SERVER_IP>:8081Code language: HTML, XML (xml)
Use the IP address of the host machine running Docker, not the internal container IP. The standard WordPress five-minute installation wizard will appear. Choose your language, set the site title, admin username, and admin password, and click Install WordPress.
Managing Your Containers
A few useful commands once both containers are running:
| Task | Command |
|---|---|
| List running containers | docker ps |
| Stop WordPress | docker stop wpcontainer |
| Start WordPress | docker start wpcontainer |
| View WordPress logs | docker logs wpcontainer |
| Remove a container (data is safe in /opt/wordpress) | docker rm wpcontainer |
Consider Docker Compose for Production Use
The --link flag used above is considered legacy in modern Docker. For anything beyond a quick local test, use Docker Compose to define both services in a single docker-compose.yml file. Compose handles networking, dependency ordering, and restart policies more cleanly, and makes the whole stack reproducible from a single file. The official WordPress Docker Hub page includes a ready-to-use Compose example.
Summary
With fewer than ten commands you can have a fully functional WordPress site running inside Docker containers, complete with persistent storage for both the database and the site files. Containers encapsulate the full stack, keep the host system clean, and make the deployment easy to move or recreate. For longer-term maintainability, migrate the setup to Docker Compose and consider adding an Nginx reverse proxy container to handle SSL termination.