---
# System prepended metadata

title: Wordpress setup
tags: [42-inception]

---


# 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
```




