Using WP-CLI on WordPress inside a Docker container
A bit nervous setting this up, but thank you, Claude Sonnet 3.7.
What it will do:
-
Persistent
wp-content
folder, easy for migrating. We can just take the wp-content from old server and put it in the new server. Save thiswp-content
in the main host (e.g./root/yourdomain.com/wp-content
). Then, we will set up a Docker volume and link that to/var/www/html/wp-content
inside the WordPress container -
WP-CLI inside the WordPress container
In coolify, I use the WordPress image and set the docker-compose.yml
like this:
version: '3.3'
services:
wordpress:
image: 'wordpress:latest'
volumes:
- 'wordpress-files:/var/www/html'
- '/root/yourdomain.com/wp-content:/var/www/html/wp-content'
environment:
- SERVICE_FQDN_WORDPRESS
- WORDPRESS_DB_HOST=mariadb
- WORDPRESS_DB_USER=$SERVICE_USER_WORDPRESS
- WORDPRESS_DB_PASSWORD=$SERVICE_PASSWORD_WORDPRESS
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_TABLE_PREFIX=wp_
- WORDPRESS_DEBUG=0
depends_on:
- mariadb
restart: always
healthcheck:
test:
- CMD
- curl
- '-f'
- 'http://127.0.0.1'
interval: 2s
timeout: 10s
retries: 10
wordpress-cli:
depends_on:
- mariadb
- wordpress
image: 'wordpress:cli'
command: 'sleep infinity'
user: '33'
volumes:
- 'wordpress-files:/var/www/html'
- '/root/yourdomain.com/wp-content:/var/www/html/wp-content'
environment:
- WORDPRESS_DB_HOST=mariadb
- WORDPRESS_DB_USER=$SERVICE_USER_WORDPRESS
- WORDPRESS_DB_PASSWORD=$SERVICE_PASSWORD_WORDPRESS
- WORDPRESS_DB_NAME=wordpress
- ADMIN_PASSWORD=$WP_ADMIN_PASSWORD
- ADMIN_EMAIL=$WP_ADMIN_EMAIL
- WORDPRESS_DEBUG=0
mariadb:
image: 'mariadb:11'
volumes:
- 'mariadb-data:/var/lib/mysql'
environment:
- MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_ROOT
- MYSQL_DATABASE=wordpress
- MYSQL_USER=$SERVICE_USER_WORDPRESS
- MYSQL_PASSWORD=$SERVICE_PASSWORD_WORDPRESS
restart: always
healthcheck:
test:
- CMD
- healthcheck.sh
- '--connect'
- '--innodb_initialized'
interval: 5s
timeout: 20s
retries: 10
volumes:
wordpress-files:
mariadb-data:
The configuration is based on Coolify's default docker-compose.yml, combined by Claude Sonnet 3.7 with Stefan Vetsch's (vstm) answer on StackOverflow.
Let's discuss some of the notable configuration.
wordpress
container
volumes:
- 'wordpress-files:/var/www/html'
- '/root/yourdomain.com/wp-content:/var/www/html/wp-content'
It uses the volume wordpress-files
that will be located in /var/www/html
inside the WordPress container. This is where we have wp-admin
, wp-content
, wp-config.php
, etc, i.e. your standard WordPress installation files. Running this docker-compose, will install a clean WordPress installation.
As you may infer, you may don't need - '/root/yourdomain.com/wp-content:/var/www/html/wp-content'
. In case you're not familiar with docker, /root/yourdomain.com/wp-content
will be located in your machine while /var/www/html/wp-content
is inside the container. Whatever you do to your wp-content
folder in your machine will be reflected in the container. If we want the WordPress container be able to modify the wp-content
folder, set the ownership/access to the user/group 33
(www-data
).
wordpress-cli
container
wordpress-cli:
depends_on:
- mariadb
- wordpress
image: 'wordpress:cli'
command: 'sleep infinity'
user: '33'
volumes:
- 'wordpress-files:/var/www/html'
- '/root/yourdomain.com/wp-content:/var/www/html/wp-content'
Ah, I love wp-cli
. Why sleep infinity
? I raised the question to Claude, since "infinity" sounds heavy. Claude says it's a usual command to keep it always running and don't worry about it. Why user: '33'
? That is the www-data user that is used by the wordpress container to maintain the file. It is just so wp-cli can modify the same files. Then, we set the volumes as the same as the WordPress container. To use wp-cli
, access the wordpress-cli
container, not the wordpress
container.
mariadb
container
For the mariadb
configuration, I follow coolify's configuration blindly. In the context of migrating, after running this docker, like the wordpress files, mariadb will start a wordpress database clean. Import your database using wp-cli
or a WP backup/restore plugin.