In the modern era of web development, containerization has become a game changer, allowing developers to package applications and their dependencies into isolated environments for consistent and replicable deployments. In this guide, we will explore the process of dockerizing a WordPress application using MariaDB as the database and Nginx as a reverse proxy. This setup will ensure high performance, security, and ease of maintenance.
Architecture Overview
The architecture consists of three primary services:
- MariaDB: A robust database management system that will store all WordPress data.
- WordPress: The content management system that powers the web application.
- Nginx: A lightweight and powerful web server that acts as a reverse proxy, managing HTTP requests and serving static files efficiently.
Prerequisites
Before diving into the deployment process, ensure you have the following installed on your local development machine:
- Docker
- Docker Compose
Project Structure
Create a project directory with the following structure:
your-project/ ├── docker-compose.yml └── nginx/ ├── database/ ├── html/ ├── nginx-conf/ └── ssl/ # For SSL certificates
Step 1: Create the Docker Compose File
Inside your project directory, create a docker-compose.yml
file with the following content to define our services:
version: '3' services: mysql: image: mariadb volumes: - ./nginx/database/mysql:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: SECURE_PASSWORD MYSQL_DATABASE: wordpress MYSQL_USER: USERNAME MYSQL_PASSWORD: SECURE_PASSWORD restart: unless-stopped networks: - docker_network wordpress: image: wordpress:6.2-php8.0-fpm-alpine volumes: - ./nginx/html/:/usr/share/nginx/html depends_on: - mysql environment: WORDPRESS_DB_HOST: mysql MYSQL_ROOT_PASSWORD: SECURE_PASSWORD WORDPRESS_DB_NAME: wordpress WORDPRESS_DB_USER: USERNAME WORDPRESS_DB_PASSWORD: SECURE_PASSWORD WORDPRESS_TABLE_PREFIX: wp_ networks: - docker_network restart: unless-stopped nginx: image: nginx:alpine volumes: - ./nginx/nginx-conf:/etc/nginx/conf.d - ./nginx/html:/usr/share/nginx/html - ./nginx/ssl:/etc/ssl ports: - 80:80 - 443:443 networks: - docker_network restart: unless-stopped networks: docker_network: driver: bridge
Explanation of the Docker Compose File
- The mysql service uses the official MariaDB image and sets up the database with necessary credentials.
- The wordpress service uses the official WordPress image and connects to the MariaDB instance.
- The nginx service uses a lightweight Nginx image, exposing ports 80 and 443 for web traffic.
Step 2: Download WordPress
Navigate to your nginx/html
directory and download the latest version of WordPress:
# Move to the HTML directory cd your-project/nginx/html # Download the latest version of WordPress curl -O https://wordpress.org/latest.tar.gz # Extract the WordPress files tar -xvzf latest.tar.gz --strip-components=1 # Clean up the tar file rm latest.tar.gz
Step 3: Create Nginx Configuration
Inside the nginx/nginx-conf
directory, create a file named default.conf
for your Nginx configuration:
mkdir -p your-project/nginx/nginx-conf nano your-project/nginx/nginx-conf/default.conf
Copy the following generalized configuration for your domain:
# HTTP Configuration server { listen 80; listen [::]:80; server_name yourdomain.com www.yourdomain.com; # Change this to your domain location ~ /.well-known/acme-challenge { allow all; root /usr/share/nginx/html; # Point to the web root directory where .well-known is stored } location / { rewrite ^ https://$host$request_uri? permanent; # Redirect all HTTP traffic to HTTPS } } # HTTPS Configuration server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name yourdomain.com www.yourdomain.com; # Change this to your domain index index.php index.html index.htm; root /usr/share/nginx/html; # Point to the web root directory where WordPress is installed server_tokens off; client_max_body_size 100M; # Adjust as needed for uploads ssl_certificate /usr/share/nginx/ssl/yourdomain.com.fullchain.pem; # Update with your certificate file ssl_certificate_key /usr/share/nginx/ssl/yourdomain.com.privkey.pem; # Update with your private key # Security Headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' data: 'unsafe-eval' 'unsafe-inline';" always; # Handle WordPress URL Rewriting location / { try_files $uri $uri/ /index.php$is_args$args; # Use WordPress's pretty permalinks } # Handle PHP Files location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass wordpress:9000; # Ensure this points to your PHP-FPM service fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } # Deny access to .htaccess and .user.ini files location ~ /\.ht { deny all; } location ~ ^/\.user\.ini { deny all; } # Favicon and robots.txt settings location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; allow all; } # Cache static content location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; } }
Important Adjustments
- Domain Name: Replace
yourdomain.com
with your actual domain in theserver_name
directives. - SSL Certificates: Ensure to provide the correct paths to your SSL certificate and key files.
Step 4: Running Your Application
Once you have set everything up, you can run the application with Docker:
- Navigate back to your project directory.
- Execute the following command to start the services:
docker-compose up -d
- Visit
http://localhost
or your domain in a web browser.
Step 5: Complete WordPress Installation
Upon visiting your site, you will encounter the WordPress installation wizard. Follow the instructions to set up your site title, username, password, and email.
Conclusion
By dockersing WordPress with MariaDB and Nginx, you achieve a powerful, scalable, and maintainable web environment. This setup simplifies the deployment process and allows you to easily manage updates and security configurations.
With your Dockerized WordPress site now live, feel free to customize it, install themes, and add plugins to suit your needs. Enjoy creating with WordPress in a containerized environment!
Troubleshooting: Migrating Your Docker Instance / Permission Errors
When migrating your Dockerized WordPress application from one computer to another, you may encounter file permission issues, especially if you are using a volume to persist your WordPress data. Here’s how to resolve these issues and ensure your application operates smoothly after the migration.
Step 1: Identify User IDs
Before you migrate your Docker containers, it’s essential to determine the user IDs that Nginx and WordPress run as. This ensures that the file permissions are set correctly in the new environment so that Nginx can serve WordPress files without permission issues.
- Access the WordPress Container: To find the user ID for both Nginx and WordPress, you will need to get into the WordPress container:
docker exec -it <wordpress_container_name> /bin/sh
Once inside, Check the running processes to see which user is running the app e.g. webserver:
ps aux
Check the user ID:
id www-data
- Repeat for Nginx: Similarly, access the Nginx container:
docker exec -it <nginx_container_name> /bin/sh
Again, check the user ID for www-data
:
id www-data
Step 2: Change Ownership and Set Permissions
After identifying the appropriate user IDs, ensure that the ownership and permissions on your WordPress files are correct. This will help prevent issues with file uploads and other file operations.
- Set Ownership: While still inside the WordPress container, update the ownership of the html directory:
chown -R www-data:www-data /usr/share/nginx/html
- Set Directory Permissions: Set the correct permissions for directories and files within the html directory:
find /usr/share/nginx/html -type d -exec chmod 755 {} \; find /usr/share/nginx/html -type f -exec chmod 644 {} \;
Step 3: Restart Containers
docker-compose down docker-compose up -d
Step 4: Verify Your Setup
Check that your WordPress site functions correctly after migration:
- Navigate to your website and ensure that pages load.
- Test uploading files through the WordPress admin interface to confirm that permissions are correctly set.