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
- Connect to your VPS via SSH:
ssh user@your-server-ip. - Update the system packages:
sudo apt update && sudo apt upgrade -y. - 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.
- Verify Docker:
docker --versionanddocker compose version. - Create a project directory:
mkdir ~/wordpress && cd ~/wordpress. - Create a
docker-compose.ymlfile with the following content. This defines two services:db(MariaDB) andwordpress. 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). - Start the stack:
docker compose up -d. This pulls the images and starts the containers in the background. - Check the status:
docker compose ps. Both services should show “running” and “healthy” (if healthchecks were defined; otherwise “running” is enough). - 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. - Finish the install. WordPress will create the necessary tables in the database container.
- 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-nginxand follow the prompts, but you’ll need to configure Nginx to proxy tolocalhost: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, notlocalhost. If you setWORDPRESS_DB_HOSTtolocalhost, 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, rundocker compose up -dagain 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
~/wordpressdirectory (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 pulland thendocker compose up -dto 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
.envfile with${MYSQL_PASSWORD}placeholders.
Troubleshooting
- Site not loading – check if the containers are running:
docker compose ps. If not, rundocker compose logsto 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
- AI vs Enigma: How It Could Have Cracked WWII Codes
- Logitech Cloud Gaming Images: What They Are
- HDMI Cable for Gaming: What to Look For
- WordPress Multisite with Nginx Setup Guide
- DayZ Server Tools Every Admin Needs
- Tower Defense Simulator Event Schedule & Dates