WordPress
ePHPm runs WordPress as a drop-in. No PHP-FPM, no MySQL server, no reverse proxy. One binary, one config, one directory of WordPress files.
1. Get WordPress
sudo mkdir -p /var/www/wordpress
cd /var/www/wordpress
sudo curl -fsSL https://wordpress.org/latest.tar.gz | sudo tar xz --strip-components=1
sudo chown -R ephpm:ephpm /var/www/wordpress # match your service user2. Configure ePHPm
# /etc/ephpm/ephpm.toml
[server]
listen = "0.0.0.0:8080"
document_root = "/var/www/wordpress"
index_files = ["index.php"]
# Pretty permalinks: try the URI as a file → as a dir → fall back to index.php
fallback = ["$uri", "$uri/", "/index.php?$query_string"]
[server.security]
# Block direct PHP execution outside of the WordPress entry points.
allowed_php_paths = [
"/index.php",
"/wp-login.php",
"/wp-admin/*.php",
"/wp-cron.php",
"/wp-comments-post.php",
"/xmlrpc.php",
"/wp-trackback.php",
]
blocked_paths = ["/wp-config.php", "/.htaccess", "/.env"]
[php]
memory_limit = "256M"
max_execution_time = 60
# Embedded SQLite — WordPress thinks it's MySQL, it's actually SQLite.
[db.sqlite]
path = "/var/lib/ephpm/wordpress.db"Restart the service:
sudo ephpm restart3. Tell WordPress about the database
wp-config.php:
define('DB_HOST', '127.0.0.1');
define('DB_USER', 'ephpm');
define('DB_PASSWORD', '');
define('DB_NAME', 'wordpress');PHP connects to 127.0.0.1:3306 via pdo_mysql. ePHPm answers with litewire, which translates MySQL wire to SQLite. WordPress doesn’t know.
If you’d rather use a real MySQL server, swap [db.sqlite] for [db.mysql]:
[db.mysql]
url = "mysql://wpuser:secret@db.internal:3306/wordpress"ePHPm becomes a connection-pooling MySQL proxy. PHP still connects to 127.0.0.1:3306; nothing in wp-config.php changes.
4. Visit it
Open http://your-server:8080/. WordPress’ setup wizard runs against the embedded database.
WP-CLI
Use the embedded interpreter so the PHP version always matches:
ephpm php wp-cli.phar plugin list --path=/var/www/wordpress
ephpm php wp-cli.phar user create alice alice@example.com --role=administrator --path=/var/www/wordpressMultisite
Multi-tenant WordPress (one ePHPm process, many independent installs):
[server]
listen = "0.0.0.0:8080"
document_root = "/var/www/marketing" # fallback for unmatched hosts
sites_dir = "/var/www/sites"/var/www/sites/
├── alice-blog.com/
│ ├── index.php
│ └── wp-config.php # uses ephpm.db in this directory
└── bobs-recipes.com/
├── index.php
└── wp-config.phpThe Host: header chooses the directory. With [server.security] open_basedir = true (default in vhost mode), each site’s PHP is filesystem-sandboxed to its own directory. See Architecture → Architecture for the vhost design.
Add HTTPS
[server.tls]
domains = ["yourdomain.com", "www.yourdomain.com"]
email = "admin@yourdomain.com"
cache_dir = "/var/lib/ephpm/certs"
# Optionally also keep an HTTP listener that 301-redirects:
listen = "0.0.0.0:443"
redirect_http = trueSet [server] listen = "0.0.0.0:80" for the HTTP redirect side.
Performance
WordPress benefits from two things ePHPm does well:
- Object cache via the KV store. Drop in any WP plugin that supports Predis (
[kv.redis_compat] enabled = true) or theephpm_kv_*SAPI functions. See KV from PHP. - Static asset serving is handled directly in Rust with sendfile and ETag — PHP isn’t involved for
.jpg/.css/.js.