# Brief | Example of Complete Flow:
```bash
.env file docker-compose.yml Container
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ MYSQL_ROOT_ │ ──→ │ mariadb: │ ──→ │ Environment: │
│ PASSWORD= │ │ environment: │ │ MYSQL_ROOT_ │
│ happybirthday │ │ MYSQL_ROOT_ │ │ PASSWORD= │
│ │ │ PASSWORD: │ │ happybirthday │
│ WP_ADMIN_USER= │ │ ${MYSQL_ROOT│ │ │
│ yilin │ │ _PASSWORD} │ │ (Only gets │
│ │ │ │ │ needed vars) │
│ (Not passed │ │ wordpress: │ ┌─────────────────┐
│ to MariaDB) │ │ environment: │ ──→ │ Environment: │
│ │ │ WP_ADMIN_ │ │ WP_ADMIN_ │
│ │ │ USER: │ │ USER=yilin │
│ │ │ ${WP_ADMIN_ │ │ │
│ │ │ USER} │ │ (Gets WordPress │
│ │ │ │ │ vars only) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
# How to get www.conf file?
## ❓**Do you need to write a Dockerfile for WordPress to get `www.conf`?**
**Not necessarily.** If your goal is to **access the default `www.conf` file from PHP-FPM**, you don’t need to build a full custom WordPress Dockerfile just to get it.
---
## ✅ **Recommended Workflow to Access `www.conf`**
You can simply run a container that has PHP-FPM installed, then **inspect or extract** the default `www.conf` file.
### 🔧 Option 1: Use an official PHP-FPM image
Run the container:
```bash
docker run -it --rm php:7.4-fpm bash
```
Once inside:
```bash
cat /usr/local/etc/php-fpm.d/www.conf
```
Or just:
```bash
cp /usr/local/etc/php-fpm.d/www.conf /some/host/path
```
> Note: The path might vary depending on PHP version. For example:
>
> * `/usr/local/etc/php-fpm.d/www.conf` (Debian base)
> * `/etc/php/7.4/fpm/pool.d/www.conf` (Ubuntu/Debian systems)
---
### 🔧 Option 2: Use a container that already includes WordPress + PHP-FPM
For learning, you can also run:
```bash
docker run -it --rm wordpress:php8.1-fpm bash
```
Then:
```bash
cat /usr/local/etc/php-fpm.d/www.conf
```
---
## 🧱 Should You Build a Custom Dockerfile for WordPress?
Only if:
* You need to **customize PHP-FPM settings**, or
* You want to add extensions, performance tweaks, or copy a custom `www.conf`
In that case, yes — build your own image like this:
```Dockerfile
FROM wordpress:php8.1-fpm
# Optional: override www.conf
COPY www.conf /usr/local/etc/php-fpm.d/www.conf
```
---
## ✅ Summary
| Goal | Recommended Action |
| -------------------------------------- | -------------------------------------------------------- |
| Just want to see or extract `www.conf` | Use `php:<version>-fpm` image and copy it from container |
| Need to customize PHP-FPM config | Build a Dockerfile and override `www.conf` |
| Want to build your own WordPress image | Extend from `wordpress:php*-fpm` and configure as needed |
---
# docker-compose file
| **Syntax Key** | **Description** | **Typical Values / Options** |
| ---------------- | ------------------------------------------- | ----------------------------------------------------------- |
| **driver** | Volume driver to manage the volume | `local` (default), or third-party drivers (e.g., `nfs`) |
| **driver\_opts** | Key-value options passed to the driver | Depends on driver, commonly includes: `type`, `device`, `o` |
| **type** | Specifies mount type or filesystem | `volume`, `bind`, `tmpfs`, `nfs` |
| **device** | Source path or device for the mount | Host path (e.g., `/path/on/host`), or network path |
| **o** | Mount options passed to kernel during mount | `bind`, `ro`, `rw`, `noexec`, `nosuid`, `nodev`, `relatime` |
---
Here are the commands to run your WordPress container. Since you want to test it and retrieve the www.conf file, I'll give you different options:
## Option 1: Run container and immediately access it (Interactive)
```bash
docker run -it --name test-wordpress wp_img1 /bin/bash
```
## Option 2: Run container in the background and then exec into it
```bash
# Start container in background
docker run -d --name test-wordpress wp_img1
# Then access it
docker exec -it test-wordpress /bin/bash
```
## Option 3: Run container with port mapping (if you want to test PHP-FPM)
```bash
docker run -d -p 9000:9000 --name test-wordpress wp_img1
```
## => To retrieve your www.conf file specifically:
```bash
# Run container and copy the file out
docker run -d --name test-wordpress wp_img1
docker cp test-wordpress:/etc/php/7.4/fpm/pool.d/www.conf ./www.conf
```
Or to view the file directly:
```bash
docker run --rm wp_img1 cat /etc/php/7.4/fpm/pool.d/www.conf
```
### Recommended for testing: Use Option 1 if you want to explore the container interactively, or the last command if you just want to quickly see the www.conf content.
# Syntax in www.conf
| Syntax | Purpose | Best Practice in Docker |
| ------------------------------------------------------------------------------ | ----------------------------------------------------------- | -------------------------------------------- |
| `pm = dynamic` | Sets process manager type (`static`, `dynamic`, `ondemand`) | ✅ `dynamic` is ideal for autoscaling workers |
| `pm.max_children = 5` | Max number of child processes | ✅ Controls concurrency, avoid overload |
| `pm.start_servers = 2` | Processes to start on launch (only in `dynamic`) | ✅ Start small, scale with load |
| `pm.min_spare_servers = 1` | Minimum idle workers | ✅ Ensures responsiveness |
| `pm.max_spare_servers = 3` | Maximum idle workers | ✅ Prevents waste |
| `pm.max_requests = 500` | How many requests each child handles before respawn | ✅ Helps avoid memory leaks over time |
| `request_slowlog_timeout = 0` | Time after which slow PHP scripts are logged | ⚠️ Set >0 if you want to monitor |
| `php_admin_value[memory_limit] = 32M` | PHP memory limit per script | ✅ Prevents runaway memory in container |
| `listen = 9000` | Port or socket where FPM listens | ✅ TCP port for Docker networking |
| `listen.owner = www-data`<br>`listen.group = www-data`<br>`listen.mode = 0660` | Socket access control (for UNIX socket) | ✅ Required only if using sockets |
| `decorate_workers_output = no` | Controls log formatting for worker output | ✅ Simpler logs in Docker |
| `catch_workers_output = yes` | Sends PHP stdout/stderr to main log | ✅ Essential for Docker logging to work |
| `env[VAR_NAME] = $VALUE` | Passes environment variables to PHP code | ✅ Optional but useful with Docker `.env` |
| `security.limit_extensions = .php .php3 .php4 ...` | Limits allowed script extensions | ✅ Restrict to `.php` for security |
---
# What's PID 1 / service logs / memory control
---
## 🔹 English Explanation
### 1. **PID 1 (Process ID 1)**
In a Docker container:
* The **first process** that starts in the container becomes **PID 1**.
* **PID 1 has special responsibilities**, such as:
* Reaping zombie processes (child processes that have exited)
* Receiving system signals (e.g., `SIGTERM`, `SIGINT`) from Docker to shut down gracefully
* **If your script becomes PID 1** and doesn't handle these responsibilities, it can:
* Cause containers to hang or not stop correctly
* Leave zombie processes behind (leaking memory)
✅ **Best Practice**: Use a proper service (like `php-fpm`, `nginx`, `mysqld`) as PID 1, not scripts like:
```bash
tail -f /dev/null
sleep infinity
bash
```
---
### 2. **Service Logs**
* Docker / .env / docker-compose filelogs are captured from the **STDOUT** and **STDERR** of PID 1.
* If the main process doesn't output logs correctly (e.g., PHP logs going to a file only), you won’t see them with `docker logs <container>`.
✅ **Best Practice**:
* Make sure services like PHP-FPM and NGINX send logs to **stdout/stderr**.
* Use settings like:
```ini
catch_workers_output = yes
```
in `www.conf` so logs go to the Docker logging system.
---
### 3. **Memory Control**
* Containers have memory limits (set by `--memory` or `mem_limit` in Docker Compose).
* PHP scripts or services that consume too much memory can:
* Crash the container
* Get killed by the OOM (Out-Of-Memory) killer
✅ **Best Practice**:
* Set reasonable limits in `php.ini` or `www.conf`:
```ini
php_admin_value[memory_limit] = 128M
pm.max_requests = 500
```
* Prevent memory leaks by respawning child processes regularly.
---
# Test Wordpress setup
# step 1 | build images
# step 2 | run container
# step 3 | check container (tests that bypass the database dependency and test WordPress functionality independently)
## Test 1: Test WordPress Container with Modified Script (Recommended)
```bash
# Create a test script that bypasses database
docker exec wp_container1 bash -c 'cat > /tmp/test_wp.sh << "EOF"
#!/bin/bash
echo "Testing WordPress without database..."
# Start PHP-FPM in background
/usr/sbin/php-fpm7.4 -D
# Wait for PHP-FPM to start
sleep 2
# Check if PHP-FPM is running
if pgrep php-fpm7.4 > /dev/null; then
echo "✅ PHP-FPM is running"
ss -tulpn | grep :9000
else
echo "❌ PHP-FPM failed to start"
fi
# Test WP-CLI
echo "Testing WP-CLI..."
cd /var/www/html
wp core version --allow-root
# Test PHP functionality
echo "Testing PHP..."
php -v
# Create a simple PHP test file
echo "<?php phpinfo(); ?>" > /tmp/test.php
php /tmp/test.php | head -20
EOF'
```
=> then run commands:
```bash
# Make it executable and run
docker exec wp_container1 chmod +x /tmp/test_wp.sh
docker exec wp_container1 /tmp/test_wp.sh
```
## Test 2: Test Container Components Individually
```bash
# Test 1: PHP-FPM Configuration
docker exec wp_container1 php-fpm7.4 -t
# Test 2: Start PHP-FPM manually and verify
docker exec -d wp_container1 php-fpm7.4 -F
sleep 3
docker exec wp_container1 ps aux | grep php-fpm
docker exec wp_container1 ss -tulpn | grep :9000
# Test 3: Test WP-CLI commands
docker exec wp_container1 wp --info --allow-root
docker exec wp_container1 wp core version --allow-root --path=/var/www/html
# Test 4: Test PHP modules
docker exec wp_container1 php -m | grep -E "(mysql|mysqli|pdo)"
# Test 5: Test file permissions
docker exec wp_container1 ls -la /var/www/html/ | head -10
docker exec wp_container1 id www-data
```
## Test 3: Create a Test PHP File to Verify Web Server Readiness
```bash
# Create a comprehensive test PHP file
docker exec wp_container1 bash -c 'cat > /var/www/html/test-wp.php << "EOF"
<?php
echo "<h1>WordPress Container Test</h1>";
echo "<h2>PHP Information</h2>";
echo "PHP Version: " . phpversion() . "<br>";
echo "Server: " . $_SERVER["SERVER_SOFTWARE"] ?? "N/A" . "<br>";
echo "<h2>WordPress Core</h2>";
if (file_exists("/var/www/html/wp-config-sample.php")) {
echo "✅ WordPress core files present<br>";
} else {
echo "❌ WordPress core files missing<br>";
}
echo "<h2>Database Extensions</h2>";
echo "MySQL Extension: " . (extension_loaded("mysql") ? "✅ Loaded" : "❌ Not loaded") . "<br>";
echo "MySQLi Extension: " . (extension_loaded("mysqli") ? "✅ Loaded" : "❌ Not loaded") . "<br>";
echo "PDO MySQL Extension: " . (extension_loaded("pdo_mysql") ? "✅ Loaded" : "❌ Not loaded") . "<br>";
echo "<h2>File Permissions</h2>";
$wp_dir = "/var/www/html";
if (is_readable($wp_dir)) {
echo "✅ WordPress directory is readable<br>";
} else {
echo "❌ WordPress directory is not readable<br>";
}
if (is_writable($wp_dir)) {
echo "✅ WordPress directory is writable<br>";
} else {
echo "❌ WordPress directory is not writable<br>";
}
echo "<h2>Configuration</h2>";
echo "www.conf location: /etc/php/7.4/fpm/pool.d/www.conf<br>";
if (file_exists("/etc/php/7.4/fpm/pool.d/www.conf")) {
echo "✅ PHP-FPM pool configuration exists<br>";
} else {
echo "❌ PHP-FPM pool configuration missing<br>";
}
?>
EOF'
```
=> then run command:
```bash
# Test the PHP file
docker exec wp_container1 php /var/www/html/test-wp.php
```
## Test 4: Test Container Networking Readiness
```bash
# Test if container can resolve external domains (for WordPress updates)
docker exec wp_container1 nslookup wordpress.org
# Test if container has internet connectivity
docker exec wp_container1 curl -s -o /dev/null -w "%{http_code}" https://api.wordpress.org/core/version-check/1.7/
# Test internal networking (for future MariaDB connection)
docker exec wp_container1 getent hosts mariadb || echo "MariaDB host not found (expected)"
```
## Test 5: Comprehensive WordPress Container Health Check
```bash
# Create a complete health check script
docker exec wp_container1 bash -c 'cat > /tmp/health_check.sh << "EOF"
#!/bin/bash
echo "=== WordPress Container Health Check ==="
# 1. Check if WordPress files exist
if [ -f "/var/www/html/wp-load.php" ]; then
echo "✅ WordPress core files present"
else
echo "❌ WordPress core files missing"
exit 1
fi
# 2. Check WP-CLI
if wp --version --allow-root > /dev/null 2>&1; then
echo "✅ WP-CLI is functional"
wp --version --allow-root
else
echo "❌ WP-CLI is not working"
fi
# 3. Start PHP-FPM and check
/usr/sbin/php-fpm7.4 -D
sleep 2
if pgrep php-fpm7.4 > /dev/null; then
echo "✅ PHP-FPM started successfully"
echo " Listening on: $(ss -tulpn | grep :9000 | head -1)"
else
echo "❌ PHP-FPM failed to start"
fi
# 4. Check PHP configuration
echo "✅ PHP version: $(php -r "echo PHP_VERSION;")"
echo "✅ PHP-FPM pool config: $(php-fpm7.4 -t 2>&1 | grep successful)"
# 5. Check file permissions
echo "✅ WordPress directory owner: $(stat -c "%U:%G" /var/www/html)"
# 6. Check essential PHP extensions
echo "✅ MySQL extensions:"
php -m | grep -E "(mysqli|pdo_mysql)" | sed 's/^/ /'
echo "=== Health Check Complete ==="
EOF'
```
=> run commands:
```bash
# Run the health check
docker exec wp_container1 chmod +x /tmp/health_check.sh
docker exec wp_container1 /tmp/health_check.sh
```