Self-hosted WordPress

How to host your own WordPress site using Docker, Nginx Proxy and a VPS.

The introduction of Docker in the past decade is regarded as one of the most pivotal advancements in software development. Docker allows developers to package applications and their dependencies into convenient containers, significantly simplifying their workflow. While containerization isn’t always possible or advisable, there are specific situations where Docker greatly enhances the development process. One prime example is setting up a website with WordPress, which will be our main focus today. Continue reading to discover why WordPress and Docker are a perfect match in the world of containerization.

Some advantages of using Docker / Containerization:

 

  • Instant Application Deployment: Docker allows you to create a separate container for each process, enabling you to deploy applications within seconds. You can create and destroy containers instantly.
  • Modularity: Docker enables you to update or repair any part of an application without taking down the whole app. By breaking your application into separate microservices, each with its own function, Docker allows these services to remain independent and easily isolated from one another.
  • Portability: Docker packages the app and its dependencies into a single container, which can be transferred to other machines with different hardware and OS setups without compatibility issues.

Here are the steps we will follow in this tutorial:

  1. Choose your Operating System
  2. Install Docker and Docker Compose
  3. Our first container – Portainer
  4. Our second container – Nginx Proxy Manager
  5. Our third container – WordPress
  6. Configuring Nginx Proxy Manager for WordPress

If you need a VPS, you can find them here:
AMD EPYC™ VPS Servers
Intel Xeon® Gold VPS Servers
ARM Ampere® Altra® VPS Servers.

Note, the Docker install for ARM servers is slightly different.  You need to use this GPT Key:

echo "deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Choose your operating system.

For this tutorial, we will use Ubuntu 24.04 as our operating system. Ubuntu is a popular choice for web hosting due to its stability, user-friendly interface, and extensive community support.

 

Install Docker and Docker Compose.

Installing Docker

  1. SSH to your vps and update your existing list of packages:
  2. sudo apt update sudo apt upgrade -y

  3. Install required packages for Docker:
  4. sudo apt install apt-transport-https ca-certificates curl software-properties-common -y

  5. Add Docker’s official GPG key:
  6. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

  7. Add the Docker APT repository:
  8. echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

  9. Update the package database with Docker packages from the newly added repository:
  10. sudo apt update

  11. Install Docker:
  12. sudo apt install docker-ce -y

Installing Docker Compose

  1. Download the current stable release of Docker Compose
  2. sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

  3. Apply executable permissions to the binary:
  4. sudo chmod +x /usr/local/bin/docker-compose

  5. Verify that the installation was successful:
  6. docker-compose --version

    https://github.com/portainer/portainer?tab=readme-ov-file

    Our first container – Portainer.

    Portainer Community Edition is a lightweight platform for managing containerized applications like Docker, Swarm, Kubernetes, and ACI environments. It is designed for simplicity in both deployment and use. Portainer provides a ‘smart’ graphical user interface (GUI) and an extensive API to manage all your orchestrator resources, including containers, images, volumes, networks, and more.

    1. Create a directory for your docker compose files. We will create ours under /home/Docker/
    2. mkdir -p /home/Docker/Portainer

      cd /home/Docker/Portainer

    3. Create a ‘docker-compose.yaml’ file and add the following content:
    4.     version: '3.3'

          services:

            portainer:

            image: portainer/portainer-ce

            container_name: portainer

            restart: always

            ports:

              - "9000:9000"

            volumes:

              - /var/run/docker.sock:/var/run/docker.sock

              - ./portainer_data:/data

            volumes:

               portainer_data:

    5. Start the Portainer container:
    6. sudo docker-compose up -d

    7. You can access your Portainer environment by browsing to http://:9000 in your web browser.

    You will be required to create a login before accessing Portainer.  Your completed docker-compose.yaml file should look like this screenshot.  NB: Note the indentation.

    Our second container – Nginx Proxy Manager.

    Nginx Proxy Manager is an easy-to-use management interface for proxying and managing web traffic.

    We will run this from within Portainer.  Once you are logged in to Portainer, click on Home and then on the ‘local’ environment.

     

     

    Once you are on the ‘local’ dashboards, you can then click on ‘Stacks’ on the left menu.

    On the page that loads, click the ‘Add stack’ button on the top right:

     

    On the next page, we will add the docker-compose code to make the Nginx Proxy Manager work.

    Name your container – use lowercase letters only.

    Use the ‘Web editor’ feature and add the docker-compose code (you can find it here):

    Now you can press the ‘Deploy the stack’ button.  Nginx Proxy Manager will be available on http://<your-server-ip>:81

    Our third container – WordPress

    WordPress is one of the most popular blogging and CMS platforms. Using Docker, we can quickly set up a WordPress site along with all the required services it needs – MySQL, Apache, and PHP.

    Running WordPress in Docker means we do not have to install Apache/PHP/MySQL on the host operating system, as we run what we require in a container. This – in essence – is the biggest advantage of containerization.

    To start, click on ‘Add stack’.  Type a lower-case name for your WordPress site and then add the following code, making sure your indentation is correct:

    There’s a few things to note here:

    1. You need to create unique passwords for the following:
    WORDPRESS_DB_PASSWORD:
    MYSQL_ROOT_PASSWORD:
    MYSQL_PASSWORD:

    2. In the configuration ports: – “8080:80”, the container’s port is the second number in the pair, which is 80. This means port 80 inside the container is mapped to port 8080 on the host machine.  It is to this port – 8080 – that we will proxy our domain so that it opens our WordPress site.

    1. Configuring Nginx Proxy Manager for WordPress

    Configuring Nginx Proxy Manager for WordPress

    1. Open Nginx Proxy Manager at http://<your_vps_ip>:81.
    2. Log in with the default credentials (admin@example.com / changeme).
    3. Add a new Proxy Host with the following settings:
      • Domain Names: yourdomain.com
      • Scheme: http
      • Forward Hostname / IP: wordpress
      • Forward Port: 8080 (since the container’s port 80 is mapped to 8080 on the host)
      • Access List: None
      • SSL: Enable SSL and force SSL (you can use Let’s Encrypt for a free SSL certificate).

    You can now access your site on https://yourdomain.com and your WordPress site will load from the Docker container.

     By following these steps, you’ll have a fully functional blog or CMS hosted on your VPS, managed with Docker and Docker Compose. This setup provides a robust, scalable, and easily maintainable environment for your web content.

    Following what we did here, you can now add more services / applications using Docker / Portainer, and then point URL’s to them using Nginx Proxy Manager.