228 lines
6.8 KiB
Markdown
228 lines
6.8 KiB
Markdown
# WordPress Operations Guide
|
|
|
|
This document provides WordPress-specific operations, configurations, and troubleshooting for WordPress sites running in Docker behind Traefik on systems-prod-01.
|
|
|
|
## Docker Configuration Best Practices
|
|
|
|
### MariaDB Version Selection
|
|
- **Use MariaDB 10.11** for compatibility with existing WordPress databases
|
|
- **Avoid MariaDB 10.7** - may cause redo log format errors during restoration
|
|
- MariaDB 10.11 is the recommended LTS version for WordPress
|
|
|
|
### SSL/HTTPS Behind Traefik
|
|
- **Real Simple SSL plugin NOT needed** when behind Traefik
|
|
- Disable Real Simple SSL to avoid redirect loops
|
|
- Traefik handles all SSL termination automatically
|
|
- Add proxy detection configuration to `wp-config.php` (see below)
|
|
|
|
### Proxy Detection Configuration
|
|
|
|
Add this to your `wp-config.php` before the "That's all, stop editing!" line:
|
|
|
|
```php
|
|
// Proxy SSL detection for Traefik
|
|
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
|
$_SERVER['HTTPS'] = 'on';
|
|
}
|
|
```
|
|
|
|
## Using WP-CLI in Docker
|
|
|
|
### Installing WP-CLI
|
|
If WP-CLI is not present in your WordPress container:
|
|
|
|
```bash
|
|
docker exec CONTAINER_NAME bash -c 'curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp'
|
|
```
|
|
|
|
### Common WP-CLI Commands
|
|
|
|
**List plugins:**
|
|
```bash
|
|
docker exec CONTAINER_NAME wp --allow-root plugin list
|
|
```
|
|
|
|
**Deactivate a plugin:**
|
|
```bash
|
|
docker exec CONTAINER_NAME wp --allow-root plugin deactivate PLUGIN_NAME
|
|
|
|
# Example: Disable Real Simple SSL
|
|
docker exec CONTAINER_NAME wp --allow-root plugin deactivate really-simple-ssl
|
|
```
|
|
|
|
**Update WordPress core:**
|
|
```bash
|
|
docker exec CONTAINER_NAME wp --allow-root core update
|
|
```
|
|
|
|
**Check WordPress version:**
|
|
```bash
|
|
docker exec CONTAINER_NAME wp --allow-root core version
|
|
```
|
|
|
|
## Database Operations
|
|
|
|
### Quick WordPress URL Change
|
|
|
|
When switching between temporary and production domains:
|
|
|
|
```bash
|
|
# Generic command (change to production domain)
|
|
ssh jared@15.204.247.153 "docker exec CONTAINER_DB mysql -u DB_USER -pDB_PASS -e \"
|
|
USE DATABASE_NAME;
|
|
UPDATE wp_options SET option_value = 'https://domain.com' WHERE option_name IN ('siteurl', 'home');
|
|
\""
|
|
|
|
# Verify the change
|
|
ssh jared@15.204.247.153 "docker exec CONTAINER_DB mysql -u DB_USER -pDB_PASS -e \"
|
|
USE DATABASE_NAME;
|
|
SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl', 'home');
|
|
\""
|
|
```
|
|
|
|
**Real Example - BestSolarTech:**
|
|
```bash
|
|
# Change to production domain
|
|
ssh jared@15.204.247.153 "docker exec bestsolartech_db mysql -u wordpress -pBST_wp2024_secure -e \"
|
|
USE bst_wordpress;
|
|
UPDATE wp_vuhx_options SET option_value = 'https://bestsolartech.com' WHERE option_name IN ('siteurl', 'home');
|
|
\""
|
|
|
|
# Verify
|
|
ssh jared@15.204.247.153 "docker exec bestsolartech_db mysql -u wordpress -pBST_wp2024_secure -e \"
|
|
USE bst_wordpress;
|
|
SELECT option_name, option_value FROM wp_vuhx_options WHERE option_name IN ('siteurl', 'home');
|
|
\""
|
|
```
|
|
|
|
### Database Access with Skip Grant Tables
|
|
|
|
If you need to reset database passwords or access without credentials:
|
|
|
|
```bash
|
|
# Stop the current database container
|
|
docker stop SERVICE_db
|
|
|
|
# Start temporary database with skip-grant-tables
|
|
docker run -d --name temp_db \
|
|
-v ~/services/SERVICE/db_data:/var/lib/mysql \
|
|
mariadb:10.11 --skip-grant-tables
|
|
|
|
# Access the database (no password needed)
|
|
docker exec -it temp_db mysql
|
|
|
|
# After making changes, stop temp container and restart normal one
|
|
docker stop temp_db && docker rm temp_db
|
|
docker start SERVICE_db
|
|
```
|
|
|
|
### Database Backup
|
|
|
|
```bash
|
|
# Backup WordPress database
|
|
docker exec CONTAINER_DB mysqldump -u DB_USER -pDB_PASS DATABASE_NAME > backup.sql
|
|
|
|
# Example: Backup BestSolarTech
|
|
docker exec bestsolartech_db mysqldump -u wordpress -pBST_wp2024_secure bst_wordpress > bestsolartech-backup.sql
|
|
```
|
|
|
|
### Database Restore
|
|
|
|
```bash
|
|
# Restore from backup
|
|
cat backup.sql | docker exec -i CONTAINER_DB mysql -u DB_USER -pDB_PASS DATABASE_NAME
|
|
|
|
# Example: Restore BestSolarTech
|
|
cat bestsolartech-backup.sql | docker exec -i bestsolartech_db mysql -u wordpress -pBST_wp2024_secure bst_wordpress
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Redirect Loops
|
|
**Symptom:** Browser shows "too many redirects" error
|
|
**Cause:** Real Simple SSL plugin conflicting with Traefik SSL termination
|
|
**Solution:** Disable Real Simple SSL plugin using WP-CLI (see above)
|
|
|
|
### Database Connection Errors
|
|
**Symptom:** "Error establishing database connection"
|
|
**Cause:** Database container not ready or wrong credentials
|
|
**Solution:**
|
|
1. Check database container is running: `docker ps | grep db`
|
|
2. Check database logs: `docker logs CONTAINER_DB`
|
|
3. Verify credentials in `wp-config.php` match `docker-compose.yml`
|
|
|
|
### Mixed Content Warnings
|
|
**Symptom:** HTTPS page loading HTTP resources
|
|
**Cause:** Missing proxy detection in `wp-config.php`
|
|
**Solution:** Add proxy detection code (see above)
|
|
|
|
## Migration Checklist
|
|
|
|
When migrating a WordPress site to systems-prod-01:
|
|
|
|
- [ ] Backup WordPress files and database from source
|
|
- [ ] Create service directory: `~/services/SITE_NAME`
|
|
- [ ] Create `docker-compose.yml` with MariaDB 10.11
|
|
- [ ] Add proxy detection code to `wp-config.php`
|
|
- [ ] Deploy containers with temporary domain
|
|
- [ ] Test HTTPS on temporary domain
|
|
- [ ] Disable Real Simple SSL plugin if present
|
|
- [ ] Update site URLs in database for production domain
|
|
- [ ] Test all functionality (admin panel, forms, etc.)
|
|
- [ ] Update DNS for production cutover
|
|
- [ ] Monitor for 24 hours after migration
|
|
|
|
## WordPress-Specific Docker Compose Template
|
|
|
|
```yaml
|
|
services:
|
|
wordpress:
|
|
image: wordpress:6.7-apache
|
|
restart: unless-stopped
|
|
environment:
|
|
WORDPRESS_DB_HOST: db:3306
|
|
WORDPRESS_DB_NAME: wordpress
|
|
WORDPRESS_DB_USER: wordpress
|
|
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
|
|
volumes:
|
|
- ./wordpress_data:/var/www/html
|
|
networks:
|
|
- traefik
|
|
- internal
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.SITE.rule=Host(`domain.com`) || Host(`www.domain.com`)"
|
|
- "traefik.http.routers.SITE.entrypoints=websecure"
|
|
- "traefik.http.routers.SITE.tls.certresolver=letsencrypt"
|
|
|
|
db:
|
|
image: mariadb:10.11
|
|
restart: unless-stopped
|
|
environment:
|
|
MYSQL_DATABASE: wordpress
|
|
MYSQL_USER: wordpress
|
|
MYSQL_PASSWORD: ${DB_PASSWORD}
|
|
MYSQL_RANDOM_ROOT_PASSWORD: '1'
|
|
volumes:
|
|
- ./db_data:/var/lib/mysql
|
|
networks:
|
|
- internal
|
|
healthcheck:
|
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 5
|
|
|
|
networks:
|
|
traefik:
|
|
external: true
|
|
internal:
|
|
external: true
|
|
```
|
|
|
|
## See Also
|
|
|
|
- [Configuration Reference](./configuration-reference.md) - Docker Compose templates
|
|
- [Services Inventory](./services-inventory.md) - Current WordPress sites
|
|
- [CLAUDE.md](../CLAUDE.md) - General server operations
|