keepcalculator

06 Numbers and Powers

Run WordPress in Docker on a VPS: Step-by-Step

Card No. 06·69689 · Updated · Standard formula, shown below

This guide walks you through running WordPress inside Docker containers on your own VPS. You’ll end up with a production-ready setup: WordPress and MySQL (MariaDB) each in their own container, with persistent storage and automatic restarts. Docker isolates the app, makes upgrades painless, and lets you move the whole stack to another server in minutes.

What You’ll Need

  • A VPS running Ubuntu 22.04 or 24.04 (or Debian 11/12) with at least 1 GB RAM and 20 GB disk.
  • Root or sudo access to that server.
  • A domain name pointed to your VPS’s IP (optional but recommended for HTTPS).
  • Basic comfort with the command line.

Step-by-Step

  1. Connect to your VPS via SSH: ssh user@your-server-ip.
  2. Update the system packages: sudo apt update && sudo apt upgrade -y.
  3. Install Docker and Docker Compose plugin using the official convenience script or apt. For Ubuntu, the simplest is:
    curl -fsSL https://get.docker.com | sudo sh
    sudo usermod -aG docker $USER

    Log out and back in so the group change takes effect.

  4. Verify Docker: docker --version and docker compose version.
  5. Create a project directory: mkdir ~/wordpress && cd ~/wordpress.
  6. Create a docker-compose.yml file with the following content. This defines two services: db (MariaDB) and wordpress. It also creates named volumes for persistent data.
    services:
      db:
        image: mariadb:11
        restart: always
        environment:
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wpuser
          MYSQL_PASSWORD: change_this_strong_password
          MYSQL_ROOT_PASSWORD: change_this_root_password
        volumes:
          - db_data:/var/lib/mysql
    
      wordpress:
        depends_on:
          - db
        image: wordpress:latest
        restart: always
        ports:
          - "80:80"
        environment:
          WORDPRESS_DB_HOST: db:3306
          WORDPRESS_DB_USER: wpuser
          WORDPRESS_DB_PASSWORD: change_this_strong_password
          WORDPRESS_DB_NAME: wordpress
        volumes:
          - wp_data:/var/www/html
    
    volumes:
      db_data:
      wp_data:

    Replace the passwords with strong random ones (e.g., openssl rand -base64 24).

  7. Start the stack: docker compose up -d. This pulls the images and starts the containers in the background.
  8. Check the status: docker compose ps. Both services should show “running” and “healthy” (if healthchecks were defined; otherwise “running” is enough).
  9. Open your browser and go to http://your-server-ip. You should see the WordPress installation wizard. Follow the steps: choose your language, enter the site title, admin username, password, and email.
  10. Finish the install. WordPress will create the necessary tables in the database container.
  11. Optional – Enable HTTPS with a reverse proxy (like Caddy or Nginx) or install Certbot directly on the host and proxy port 80 to the WordPress container. For a simple setup, you can run sudo apt install certbot python3-certbot-nginx and follow the prompts, but you’ll need to configure Nginx to proxy to localhost:80.

Common Mistakes

  • Using weak passwords – if you use “password” or “admin”, your site will be hacked quickly. Always use strong, unique passwords.
  • Forgetting to persist data – if you don’t use volumes, all your content disappears when the container is removed. The compose file above uses named volumes.
  • Binding to port 80 without a firewall – your VPS may have a firewall (UFW) that blocks port 80. Open it with sudo ufw allow 80/tcp (and 443 for HTTPS).
  • Using the wrong database host – inside the compose network, the hostname is db, not localhost. If you set WORDPRESS_DB_HOST to localhost, WordPress will try to connect to a database inside its own container, which doesn’t exist.
  • Not restarting after editing compose – after changing docker-compose.yml, run docker compose up -d again to apply changes.

Tips

  • Use a reverse proxy for better performance and HTTPS. Caddy is the easiest: it automatically obtains and renews SSL certificates.
  • Back up your volumes regularly. You can back up the entire ~/wordpress directory (which includes the compose file) and the volume data. To back up a volume, run a temporary container that tars the volume: docker run --rm -v wp_data:/data -v $(pwd):/backup alpine tar czf /backup/wp_data.tar.gz -C /data .
  • Keep images updated: docker compose pull and then docker compose up -d to apply updates. Always test on a staging site first.
  • Set up a firewall with UFW: allow SSH (port 22), HTTP (80), and HTTPS (443) only. sudo ufw allow 22/tcp && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw enable.
  • Use environment variables for passwords instead of hardcoding them in the compose file, especially if you commit the file to a repository. You can use a .env file with ${MYSQL_PASSWORD} placeholders.

Troubleshooting

  • Site not loading – check if the containers are running: docker compose ps. If not, run docker compose logs to see errors. Common issue: port 80 already in use. Change the host port in the compose file (e.g., "8080:80") and try again.
  • Database connection error – WordPress says “Error establishing a database connection”. Verify the database container is healthy: docker compose logs db. Check that the passwords in the compose file match between the db and wordpress services. Also, ensure the database name and user are correct.
  • Permissions issues – if you get a “Permission denied” when writing to the wp-content directory, the volume may have wrong ownership. You can fix it by entering the container and adjusting permissions, but a simpler approach is to run docker compose exec wordpress chown -R www-data:www-data /var/www/html.
  • HTTPS not working – if you used Certbot, make sure port 80 is open and that your domain resolves to the VPS IP. Certbot needs to verify domain ownership via HTTP.
  • Changes not reflecting – if you edit files in the volume, but the site doesn’t update, your browser may be caching. Hard refresh (Ctrl+Shift+R) or clear cache.

Frequently Asked Questions

Is it safe to run WordPress in Docker on a production site?

Yes, if you follow best practices: keep images updated, use strong passwords, enable HTTPS, and back up regularly. Docker adds a layer of isolation, but you still need to secure the host OS and the WordPress installation itself.

How do I update WordPress core or plugins?

You can update from the WordPress admin dashboard as usual. However, because the files are in a volume, the changes persist. For core updates, it’s safer to pull a new image and recreate the container, but that requires moving the volume. Many users simply update via the dashboard.

Can I use an existing WordPress site with this setup?

Yes. You can migrate your existing WordPress files into the wp_data volume and import your database into the MariaDB container. Use tools like wp-cli or manually copy files and run a SQL import.

How do I change the domain name later?

Update the WordPress site URL in the admin dashboard (Settings > General) and, if using a reverse proxy, update its config. The database stores the domain, so you can also change it via phpMyAdmin or the command line.

What if my VPS has less than 1 GB RAM?

WordPress and MariaDB can run on 512 MB, but it will be slow. Consider adding swap space or using a lighter database like SQLite (not supported by the official image). For production, 1 GB is the minimum recommended.

How do I back up the entire site?

Back up both the WordPress files (in the wp_data volume) and the database (in db_data). You can use the docker run --rm command shown in Tips, or use a plugin like UpdraftPlus to back up from the admin panel.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →