Docker Swarm is a popular infrastructure tool for running websites and web applications online. Here’s how to deploy WordPress Multisite on Docker Swarm.
This post extends https://blog.budhajeewa.com/deploy-wordpress-on-docker-swarm/. We’ll refer to that as the “parent post” in this post.
Setup WordPress
Follow the parent post, and get a WordPress stack up and running.
Allow Multisite Feature
Open the docker-compose.yml
and add the highlighted lines to it.
version: '3' services: wordpress: image: wordpress:5.1.1-php7.1-apache depends_on: - mariadb volumes: - ./volumes/wordpress/content:/var/www/html/wp-content environment: WORDPRESS_DB_HOST: mariadb:3306 WORDPRESS_DB_PASSWORD: root WORDPRESS_CONFIG_EXTRA: | /* Multisite */ define('WP_ALLOW_MULTISITE', true ); ports: - 8001:80 mariadb: image: mariadb:10.4.4 volumes: - ./volumes/mariadb/data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root
Then run make deploy
(This is facilitate by https://blog.budhajeewa.com/docker-swarm-deploying-web-apps-and-sites/#easy-redeployment-with-a-makefile.). Wait till the the site is back up, and continue with the rest of the instructions.
Network Setup
In the WordPress dashboard, go to Tools → Network Setup
, choose the address style, fill in network details, and click “Install”. It will then present you with some codes to be added to the wp-config.php
and some code to replace current content of.htaccess
file with.
Update wp-config.php
As you’re running a Docker Container based on an Docker Image for WordPress, you don’t really have to edit the file manually, and the changes will be lost sooner or later, as Docker Containers are volatile. We can use the environment variable WORDPRESS_CONFIG_EXTRA
to add the configuration changes.
What I have shown below is what was given to me by WordPress; yours may change. Be sure to use your own code, as given by WordPress. I’ve highlighted the newly added lines.
version: '3' services: wordpress: image: wordpress:5.1.1-php7.1-apache depends_on: - mariadb volumes: - ./volumes/wordpress/content:/var/www/html/wp-content environment: WORDPRESS_DB_HOST: mariadb:3306 WORDPRESS_DB_PASSWORD: root WORDPRESS_CONFIG_EXTRA: | /* Multisite */ define('WP_ALLOW_MULTISITE', true ); define('MULTISITE', true); define('SUBDOMAIN_INSTALL', true); define('DOMAIN_CURRENT_SITE', 'example.com'); define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); ports: - 8001:80 mariadb: image: mariadb:10.4.4 volumes: - ./volumes/mariadb/data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root
Update .htaccess
Unfortunately, there’s no quick environment variable to replace the content of the .htaccess
file. So we have to create a file, and mount it at the proper location.
In the com-example/volumes/wordpress/
directory, create a file named htaccess
(No period at the start of the file name, as we don’t want to turn that into a hidden file.), and add the following content into it.
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^wp-admin$ wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^(wp-(content|admin|includes).*) $1 [L] RewriteRule ^(.*\.php)$ $1 [L] RewriteRule . index.php [L]
Then open the docker-compose.yml
file and add the highlighted line to it.
version: '3' services: wordpress: image: wordpress:5.1.1-php7.1-apache depends_on: - mariadb volumes: - ./volumes/wordpress/content:/var/www/html/wp-content - ./volumes/wordpress/htaccess:/var/www/html/.htaccess environment: WORDPRESS_DB_HOST: mariadb:3306 WORDPRESS_DB_PASSWORD: root WORDPRESS_CONFIG_EXTRA: | /* Multisite */ define('WP_ALLOW_MULTISITE', true ); define('MULTISITE', true); define('SUBDOMAIN_INSTALL', true); define('DOMAIN_CURRENT_SITE', 'example.com'); define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); ports: - 8001:80 mariadb: image: mariadb:10.4.4 volumes: - ./volumes/mariadb/data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root
We now mount the outside volumes/wordpress/htaccess
file to the Docker Container’s mount point /var/www/html/.htaccess
.
Above is how your docker-compose.yml
would ultimately look.
Support Any Subdomain and Main Domain in NGINX
You only have to do this if you choose sub domains as the domain style for your child sites.
As instructed in https://blog.budhajeewa.com/deploy-wordpress-on-docker-swarm/#map-a-domain-to-the-wordpress-installation, our WordPress Stack’s NGINX configuration currently looks like following:
server { listen 80; server_name example.com; location / { proxy_pass http://host.public.ip.address:8001; proxy_set_header Host $host; } }
It only supports the main domain, you can get it to support the main domain as well as any sub domains of it, by prepending a period to the server_name
value. This is how the configuration file would look like after the change. Changed line is highligted.
server { listen 80; server_name .example.com; location / { proxy_pass http://host.public.ip.address:8001; proxy_set_header Host $host; } }
Restart NGINX, and you should be able to get a response from WordPress if you visit sub-domain.example.com
. If that is working, you can proceed to create the child sites you need.
One response to “Deploy WordPress Multisite on Docker Swarm”
followed the instruction and everything works but upload and wp-content folder are not writable.
i have tried setting pu permissions 755 to the folders, but still same