Next few days I will enjoying some holidays and I wanted to play a bit with WordPress security.
The first step is a testing environment to avoid messing with my own production WordPress.
One of the easiest ways is a local environment using Docker.
In this post, I will describe the steps to create a new WordPress installation where you will be able to test everything you need.
I will be assuming that you have an already up-and-running docker environment.
Create a folder structure to contain the WordPress site.
❯ mkdir -p ~/projects/wordpress/target
❯ cd ~/projects/wordpress
Based on the official WordPress docker image we can use the docker-compose they suggest you:
version: '3'
services:
db:
image: mariadb:latest
volumes:
- data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=wordpress
- MYSQL_USER=manager
- MYSQL_PASSWORD=secret
web:
image: wordpress:latest
depends_on:
- db
volumes:
- ./target:/var/www/html
environment:
- WORDPRESS_DB_USER=manager
- WORDPRESS_DB_PASSWORD=secret
- WORDPRESS_DB_HOST=db
ports:
- 8080:80
volumes:
data:
Now with docker-compose up -d
The container will be started (you can add the -d
option to run them in detached mode (in the background))
To stop the containers started by Docker Compose, use the docker-compose down
command.
This command stops and removes the containers, networks, and volumes created by the Compose file.
Finally accessing http://localhost:8080 you will get the WordPress installation process window.



Now WordPress is installed and you can see all the WordPress files in the target folder:
❯ ls -la
total 260
drwxr-xr-x 5 www-data www-data 4096 d’ag. 18 12:27 .
drwxrwxr-x 3 ruben ruben 4096 d’ag. 18 12:26 ..
-rw-r--r-- 1 www-data www-data 261 d’ag. 18 12:38 .htaccess
-rw-r--r-- 1 www-data www-data 405 de febr. 6 2020 index.php
-rw-r--r-- 1 www-data www-data 19915 de gen. 1 2023 license.txt
-rw-r--r-- 1 www-data www-data 7399 de jul. 5 19:41 readme.html
-rw-r--r-- 1 www-data www-data 7211 de maig 12 23:35 wp-activate.php
drwxr-xr-x 9 www-data www-data 4096 d’ag. 8 21:32 wp-admin
-rw-r--r-- 1 www-data www-data 351 de febr. 6 2020 wp-blog-header.php
-rw-r--r-- 1 www-data www-data 2323 de juny 14 16:11 wp-comments-post.php
-rw-rw-r-- 1 www-data www-data 5492 d’ag. 17 06:02 wp-config-docker.php
-rw-r--r-- 1 www-data www-data 5596 d’ag. 18 12:27 wp-config.php
-rw-r--r-- 1 www-data www-data 3013 de febr. 23 11:38 wp-config-sample.php
drwxr-xr-x 4 www-data www-data 4096 d’ag. 18 12:38 wp-content
-rw-r--r-- 1 www-data www-data 5638 de maig 30 20:48 wp-cron.php
drwxr-xr-x 27 www-data www-data 16384 d’ag. 8 21:32 wp-includes
-rw-r--r-- 1 www-data www-data 2502 de nov. 26 2022 wp-links-opml.php
-rw-r--r-- 1 www-data www-data 3927 de jul. 16 14:16 wp-load.php
-rw-r--r-- 1 www-data www-data 49441 de jul. 17 15:18 wp-login.php
-rw-r--r-- 1 www-data www-data 8537 de juny 22 16:36 wp-mail.php
-rw-r--r-- 1 www-data www-data 25602 de jul. 25 08:35 wp-settings.php
-rw-r--r-- 1 www-data www-data 34385 de juny 19 20:27 wp-signup.php
-rw-r--r-- 1 www-data www-data 4885 de juny 22 16:36 wp-trackback.php
-rw-r--r-- 1 www-data www-data 3236 de juny 14 16:11 xmlrpc.php
As we can see all WordPress files are from www-data users. We need to fix that in order to be able to work with those files.
A way of fixing this could be:
Creating a `.env` file.
UID=1000
GID=1000
Add into the corresponding docker-compose.yml service:
user: "${UID}:${GID}"
And now just simply remove the old containers and recreate them again.
Now doing the same ls as before:
❯ ls -la
total 260
drwxr-xr-x 5 ruben ruben 4096 d’ag. 18 15:04 .
drwxrwxr-x 3 ruben ruben 4096 d’ag. 18 15:03 ..
-rw-r--r-- 1 ruben ruben 261 d’ag. 17 06:04 .htaccess
-rw-r--r-- 1 ruben ruben 405 de febr. 6 2020 index.php
-rw-r--r-- 1 ruben ruben 19915 de gen. 1 2023 license.txt
-rw-r--r-- 1 ruben ruben 7399 de jul. 5 19:41 readme.html
-rw-r--r-- 1 ruben ruben 7211 de maig 12 23:35 wp-activate.php
drwxr-xr-x 9 ruben ruben 4096 d’ag. 8 21:32 wp-admin
-rw-r--r-- 1 ruben ruben 351 de febr. 6 2020 wp-blog-header.php
-rw-r--r-- 1 ruben ruben 2323 de juny 14 16:11 wp-comments-post.php
-rw-r--r-- 1 ruben ruben 5492 d’ag. 17 06:02 wp-config-docker.php
-rw-r--r-- 1 ruben ruben 5596 d’ag. 18 15:04 wp-config.php
-rw-r--r-- 1 ruben ruben 3013 de febr. 23 11:38 wp-config-sample.php
drwxr-xr-x 4 ruben ruben 4096 d’ag. 8 21:32 wp-content
-rw-r--r-- 1 ruben ruben 5638 de maig 30 20:48 wp-cron.php
drwxr-xr-x 27 ruben ruben 16384 d’ag. 8 21:32 wp-includes
-rw-r--r-- 1 ruben ruben 2502 de nov. 26 2022 wp-links-opml.php
-rw-r--r-- 1 ruben ruben 3927 de jul. 16 14:16 wp-load.php
-rw-r--r-- 1 ruben ruben 49441 de jul. 17 15:18 wp-login.php
-rw-r--r-- 1 ruben ruben 8537 de juny 22 16:36 wp-mail.php
-rw-r--r-- 1 ruben ruben 25602 de jul. 25 08:35 wp-settings.php
-rw-r--r-- 1 ruben ruben 34385 de juny 19 20:27 wp-signup.php
-rw-r--r-- 1 ruben ruben 4885 de juny 22 16:36 wp-trackback.php
-rw-r--r-- 1 ruben ruben 3236 de juny 14 16:11 xmlrpc.php
docker-compose stop
will stop the services.docker-compose start
will start again the services.docker-compose down -v
will stop and remove the containers along with the associated volumes.
From this point, you should be able to start your WordPress testing.