Log In

How to Install WordPress Using Docker

How to Install WordPress Using Docker
Reading time: 12 min
Hostman Team
Technical writer

WordPress is an open-source product written in PHP and one of the many popular website content management systems (CMS). The CMS stores data in a relational database, MySQL.

The purpose of WordPress does not end with managing blogs, as is commonly believed. Thanks to a system of themes and plugins, the CMS's basic functionality can be expanded to the level of more complex projects, making WordPress the most popular CMS in the world.

WordPress is based on a technological stack of server software, the most common of which is LAMP: Linux, Apache, MySQL, and PHP.

Manually installing these components may not be very practical if you regularly deploy the application to server machines. A better choice would be running WordPress in a Docker container. This way, you can automate the installation and running of CMS, turning WordPress into a multi-container application. If you are developing a product using Docker, the application will definitely work anywhere after deployment.

In this tutorial, we will look at deploying the WordPress with Docker and Docker Compose. However, the tech stack will not be entirely LAMP; the project in this guide is based on Nginx, PHP, MySQL, and, of course, WordPress.

Please note that this guide is intended for UNIX-like operating systems, particularly Debian and Ubuntu.

Install Docker components

To set up Wordpress in Docker, we obviously need to install Docker and its components first.

Step 1. First of all, update the list of existing packages on your server machine:

sudo apt update

Step 2. To ensure the installation process runs correctly, we will need a few key packages to ensure the HTTPS connection works:

sudo apt install apt-transport-https ca-certificates curl software-properties-common

Removing old versions of Docker

Step 3. To prevent possible problems, it is worth checking if one of the older versions of Docker is installed on your system (docker-engine and docker.io, which are considered obsolete, unlike docker-ce and docker-ee). If they are present, remove them:

sudo apt autoremove docker docker-engine docker.io docker-ce

Installing the Docker engine

Step 4. Now you can take the GPG key from the official Docker repository and add it to the system:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

And then include the repository itself in the list of packages:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

Step 5. Let's once again update the list of packages:

sudo apt update

Now you can download Docker itself:

sudo apt install docker-ce docker-ce-cli docker-compose-plugin

To check if Docker is installed successfully, use this simple command that will display the version in the terminal:

docker --version

Installing Docker Compose

Docker Compose is a tool for automating container management. It uses a special instruction file in YAML format.

It's somewhat similar to Node's package.json, but it goes a little deeper: you define services, their dependencies, storage spaces, and environment variables. Docker Compose, following the descriptions, performs automatic deployment. In general, this ensures the portability of developed projects.

Please note that a separate installation of Docker Compose is not required if you are using the latest versions of Docker. Instead of a separate Compose V1, the Docker CLI package ships Compose V2, written in Go. In this case, docker compose is used instead of the usual docker-compose command.

If, for some reason, you need the old version of Compose V1, then the instructions below are for you.

Step 6. From the official GitHub repository, download the executable file with the latest version of docker-compose:

sudo curl -L "https://github.com/docker/compose/releases/download/2.19.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/ bin/docker-compose

Step 7. Next, set the permissions to use this file:

sudo chmod +x /usr/local/bin/docker-compose

The installation can be considered virtually completed. Subsequently, the downloaded file will process the definition files and start or stop containers per our commands.

Step 8: For added reliability, we recommend trying to run the file to get version information:

docker-compose --version

Configure Nginx

Before we begin describing the container structure in the Docker Compose file, we must prepare all the required directories and configuration files for the components used in the application.

One of the main configuration files, which contains the settings and routing of the Nginx web server, is of particular importance.

Creating directories

Step 1. Let's create a separate directory for our application in the home directory and immediately go to it:  

mkdir -p ~/wordpress
cd ~/wordpress

Here we will create additional subdirectories within which Nginx, MySQL and WordPress data will be located.   

mkdir -p nginx/
mkdir -p logs/
mkdir -p logs/nginx
mkdir -p data/
mkdir -p data/html
mkdir -p data/mysql

We have a directory designed specifically for storing Nginx, as well as a separate folder where server log files will be saved. The directory called data will contain the main CMS and database files.

Creating an Nginx configuration file

Step 2. Now, we will create a configuration file for Nginx in the previously created directory dedicated to it:

nano ~/wordpress/nginx/nginx.conf

Step 3. We will add a minimal description to the file for the purposes of this guide. Later on, you can expand the file's content as the complexity of your projects grows:

server {
   listen 80 default_server;
   root /var/www/html;
   index index.php;
   access_log /var/log/nginx/site-access.log;
   error_log /var/log/nginx/site-error.log;
     try_files $uri $uri/ /index.php?$args;
   location ~ \.php$ {
     try_files $uri =404;
     fastcgi_split_path_info ^(.+\.php)(/.+)$;
     fastcgi_pass wordpress:9000;
     fastcgi_index index.php;
     include fastcgi_params;
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
     fastcgi_param PATH_INFO $fastcgi_path_info;

The listening port is standard 80. The default_server directive and the _ setting in server_name instruct Nginx to process any requests (with any host value in the HTTP headers) on port 80.

The root directory with the files is located at /var/www/html. Index.php, a kind of entry point in WordPress, is among them.

The next lines are the paths to the log files (the request log and the error log).

The standard route directs the user to the entry point index.php, also passing all the arguments (query string) from the address. Accordingly, all requests for PHP files are sent directly to the PHP container via the FastCGI protocol.

Describe the required images and containers

Creating the docker-compose.yml file

The normal functioning of WordPress involves the joint work of 3 main components from the previously described tech stack: the Nginx server, WordPress itself, and the MySQL database.

At the same time, MySQL is a fundamental component of the application because all the data that WordPress handles is located there.

Therefore, disk space will be required both for MySQL and for the theme files and plugins that are integral to the CMS.

It is precisely because WordPress is a multi-component application that we need docker-compose to deploy its structure in a portable manner.

Step 1. We will place a description of all dependencies in a special file docker-compose.yml:

sudo nano docker-compose.yml

Step 2. Fill the file with the following content:

version: '3.3'
         - ./nginx:/etc/nginx/conf.d
         - ./data/html:/var/www/html
         - 8080:80
         - wordpress
     image: wordpress:latest
       - ./data/html:/var/www/html
       - "80:80"
     restart: always
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: *username from MySQL*
       WORDPRESS_DB_PASSWORD: *MySQL password*
       WORDPRESS_DB_NAME: wordpress
     image: mysql:5.7
       - ./data/mysql:/var/lib/mysql
     restart: always
       MYSQL_ROOT_PASSWORD: *MySQL root password*
       MYSQL_DATABASE: wordpress
       MYSQL_USER: *username from MySQL*
       MYSQL_PASSWORD: *MySQL password*

The intricacies of writing YAML files are beyond the scope of this article; this is a separate extensive topic that you can read about in the official documentation. Let's just go through the main points.

Specifically, here, we first define Nginx, WordPress, and MySQL as the application's main services (containers), not forgetting to specify their dependencies. For example, WordPress won't work without a database.

For WordPress and Nginx, we use the latest versions of containers. By default, we link them by reserving port 80 for web traffic.

When you enter a URL into a browser, Nginx and WordPress Docker containers work together to process requests sequentially and return generated web pages to the user as a response.

The database service is a MySQL version 5.7 image. Accordingly, we do not forget to specify environment variables with the necessary credentials for containers to communicate with each other.

Inside each service, the volumes parameter declares disk space, i.e. directories in which working Nginx, WordPress and MySQL files are stored. When using the CMS in a real project, it is important to make backup copies of these directories regularly.

Optional component: phpMyAdmin

It's worth mentioning that you can optionally include the phpMyAdmin image in the yml file:

     image: phpmyadmin/phpmyadmin
     restart: always
       - db:mysql
       - 8081:80
       MYSQL_ROOT_PASSWORD: *MySQL password*

PhpMyAdmin is a web interface for MySQL. It allows you to manage the database not through the terminal and SQL queries, but visually in the browser window.

In our case, phpMyAdmin is not a required component, but in more complex projects such functionality may be useful.

Loading images and running containers

Step 3. Now you can run this file, and Docker Compose will create working containers from all the described images and configure them accordingly:

docker compose up -d

Running this command for the first time will take significant time because the files will be downloaded from Docker Hub.

Step 4. Once the process is complete, you should make sure that the loaded containers are actually running:  

docker compose ps

If everything is correct, a list of running containers will appear in the terminal, the names of which will correspond to the descriptions in the docker-compose.yml file.

Restarting containers

Each container can be restarted if necessary. For example, if you update the Nginx configuration, you will need to restart the web server to apply the changes.

docker compose restart nginx

However, there is one more stage ahead. Immediately after loading and launching the containers, you will be able to open the WordPress web interface. This is where you will perform all further configuration of the CMS.

Complete the WordPress installation via the web interface

Now that we launched Docker containers for WordPress using Docker Compose, you can proceed to finalizing the installation.

Step 1. In the address bar of your web browser, you need to enter your server address, after which the WordPress installation screen will appear.

First, select the language in which the CMS will work. 

Step 2. Next, click Continue. A page with basic WordPress settings will open. You'll need to specify the site name, username, user password, and email address.


There is also a special clause at the bottom that prohibits search engines from indexing your site. If your site is not a private portal, you should leave indexing so that users can access your site from search results. By the way, it is better not to use such common names as admin or root as a username, as they will make it easier for attackers to hack.

In some cases, a screen may appear asking for information about the database previously created in phpMyAdmin. However, in our case, we won't see it because we already declared all the necessary environment variables in the docker-compose.yml file.


Step 3. When all fields are filled out correctly, the Install WordPress button will take you to the login page. After logging in, you will find yourself in the admin panel. It has many different sections, but it cannot be called too complex.


Further use of WordPress consists of operating many settings inside the admin panel. An exception is the case when PHP variables are manually entered into the page markup, thereby turning the raw HTML layout into a full-fledged WordPress theme that anyone can install.

If you have installed phyMyAdmin, then its web interface will be available at the address of your server but on port 8081.



While there are many ways to deploy a local WordPress app development environment, Docker stands out in stark contrast with its component sharing, cross-platform, and portability features.

With Docker, you can set up multiple environments side by side using different components. Each of them can be included or excluded from the stack used depending on needs and tasks.

In this tutorial, we used Docker containers to deploy all the required components of a WordPress application and followed a number of key steps:

  • Downloaded Docker and Docker Compose for managing containers.

  • Prepared an Nginx configuration file to transmit the requests to the WordPress container via the FastCGI protocol.

  • Downloaded phpMyAdmin for easy database management through the web interface.

  • Created a file describing the services, after which docker-compose automatically downloaded the necessary images and launched the required containers. In this case, Nginx was used as a web server, and we used a MySQL database to store data.

  • Completed the WordPress installation through the admin panel in the browser.

This basic configuration can be expanded or modified in a variety of ways. The official WordPress website has complete documentation describing the nuances of working with the admin panel of this CMS. The same goes for Nginx: you can find various guides on configuring and using this web server on the official website.