CLI for provisioning and managing WordPress or static sites on the QA LNMP server fleet. The tool orchestrates nginx, filesystem layout, SSL certificates, and MySQL/MariaDB databases so that each site follows the same hardened baseline.
- End-to-end lifecycle –
spawn,delete,deactivate,activate,update, andlistcommands cover the entire site lifecycle. - Safe automation – every provisioning step is tracked so the tool can roll back partial work automatically when failures occur.
- WordPress aware – downloads the latest WordPress build, creates a dedicated database, and generates a salted
wp-config.phpfile. - HTTPS ready – integrates with
acme.shto request and install Let's Encrypt certificates, then appends the HTTPS server block to nginx. - Static sites supported –
--no-wpproduces a static site skeleton backed by the bundleddefault-index.htmltemplate. - Site inventory –
listcommand provides a comprehensive overview of all configured sites with their status and features.
IMPORTANT
This binary is tailored for the WP Media QA LNMP environment documented in the QA LNMP runbook. Paths, users, and services are hard-coded to match that stack. Other LNMP servers that share similar configuration might be compatible as well. However, it should be possible to use in environments with different configuration if values of constants are adapted for it.
- Linux host with nginx, PHP-FPM, and systemd (the tool reloads nginx via
systemctl). - Root or sudo privileges. All commands exit early if they are not executed by root.
curlandtarfor downloading and unpacking WordPress.mysql/mariadbserver reachable atlocalhost(host constant can be changed) with a root account that can create databases and grant privileges.- Writable directories that match the built-in paths:
- Sites root:
/var/www/html - Nginx configs:
/etc/nginx/conf.d - SSL certs:
/etc/nginx/ssl
- Sites root:
acme.shmust be installed as root / sudo and in$PATHfor any--sslorupdate --ssloperation. The tool checksacme.sh --versionbefore continuing.- DNS must already point the requested domain to the server and port 80 must be reachable for the HTTP-01 challenge.
Install Rust by following the instructions at rust-lang.org, then build and install the CLI:
git clone <repository-url>
cd e2e-site-spawner
# Build and install to /usr/local/bin for system-wide access
cargo build --release
sudo cp target/release/e2sp /usr/local/bin/
sudo chown root:root /usr/local/bin/e2sp
sudo chmod 755 /usr/local/bin/e2spThe binary is now available system-wide and can be run with sudo e2sp without PATH issues.
If you prefer to use Cargo's install mechanism:
# Install to a temporary location
cargo install --path . --root /tmp/e2sp-install
# Copy to system location
sudo cp /tmp/e2sp-install/bin/e2sp /usr/local/bin/
sudo chown root:root /usr/local/bin/e2sp
sudo chmod 755 /usr/local/bin/e2sp
# Clean up temporary files
rm -rf /tmp/e2sp-installTo upgrade to the latest version:
cd e2e-site-spawner
git pull
# Rebuild and replace the binary
cargo build --release
sudo cp target/release/e2sp /usr/local/bin/
sudo chown root:root /usr/local/bin/e2sp
sudo chmod 755 /usr/local/bin/e2spTo remove the binary:
sudo rm /usr/local/bin/e2spIf you originally installed with cargo install --path . to your user directory:
# Also remove from user's cargo bin if it exists there
cargo uninstall e2e-site-spawnerAll lifecycle commands require elevated privileges:
sudo e2sp --help| Command | Description |
|---|---|
spawn <site> [--ssl] [--no-wp] |
Creates a new site, sets up nginx, filesystem, default WordPress install, optional SSL. |
delete <site> |
Removes nginx configs, site files, SSL certificates, and the MySQL database. |
deactivate <site> |
Renames the nginx config to .conf.deactivated to take the site offline without deleting assets. |
activate <site> |
Reverts the .deactivated config back to .conf and reloads nginx. |
update <site> [--wp] [--ssl] |
Adds WordPress to a static site and/or enables SSL on an existing HTTP-only deployment. |
list |
Displays all configured sites with their status, features, and management information. |
Use e2sp <command> --help for command-specific usage text and examples.
Creates /var/www/html/<site> along with /etc/nginx/conf.d/<site>.conf. When WordPress is enabled (default):
- Downloads the latest WordPress release.
- Creates a MySQL database named
wp_<site>(punctuation replaced with_). - Generates
wp-config.phpwith salts and the credentials defined insrc/constants.rs.
Flags:
--ssl– triggers certificate issuance via acme.sh and appends the HTTPS server block.--no-wp– skips the WordPress install and drops in the default staticindex.html.
Destroys everything created by spawn, including SSL directories and databases, then reloads nginx. This command is destructive and cannot be undone.
Toggle site availability by renaming the nginx configuration (example.conf ↔ example.conf.deactivated). Site files, SSL assets, and databases remain untouched.
Extends an existing site in-place:
--wp– installs WordPress into an existing static site after ensuring no previous installation or database exists.--ssl– generates certificates, backs up the nginx config, appends the HTTPS block, validates nginx, and reverts on failure.
Provides a comprehensive inventory of all configured sites on the server. The command scans /etc/nginx/conf.d/ for configuration files and displays:
- Site name – The domain name extracted from the config filename
- Features – Indicates if SSL and/or WordPress are enabled (color-coded)
- Status – Shows if the site is active or deactivated
- Management – Identifies sites managed by e2sp vs. external configurations
Output format:
Sites list:
example.com - ssl, wp - (active)
test-site.com - wp - (deactivated)
static-site.com - (active)
old-site.com - (active) - not managed by e2sp
Summary:
Total sites: 4 (3 active, 1 deactivated)
Managed by e2sp: 3
Not managed by e2sp: 1
Color coding:
- Site names: bright white
- SSL indicator: green
- WordPress indicator: blue
- Active status: green
- Deactivated status: yellow
- Unmanaged sites: dimmed gray
The command detects:
- SSL status by checking for HTTPS configuration markers in the nginx config
- WordPress by verifying the presence of
wp-config.phpin the site directory - Active/Deactivated based on the config file extension (
.confvs.conf.deactivated) - e2sp management by looking for specific configuration markers added by the tool
No arguments are required:
sudo e2sp list| Resource | Location | Notes |
|---|---|---|
| Site root | /var/www/html/<site> |
Owned by www-data:root, chmod 0777 for compatibility with existing workflows. |
| Nginx config | /etc/nginx/conf.d/<site>.conf |
HTTP block is always present; HTTPS block is appended when SSL is enabled. |
| SSL material | /etc/nginx/ssl/<site>/ |
Contains privkey.pem and fullchain.pem. Created only when SSL is requested. |
| Database | wp_<site> |
Created through the MySQL root account and granted to the wordpress user with password pleaseadvise (see src/constants.rs). |
Each provisioning phase validates nginx syntax via nginx -t; failures trigger an automatic rollback using the tracked step list defined in SpawnSteps.
-
Build the binary locally:
cargo build
-
Run the full test suite (some integration tests expect root access and a configured nginx/MySQL stack; run them inside a disposable VM):
cargo test -
Format and lint before sending patches:
cargo fmt cargo clippy --all-targets --all-features
Test doubles for nginx/MySQL are not provided—tests interact with the real system. When running without root the tests assert that permission errors are surfaced correctly.
- "ELEVATED PRIVILEGES REQUIRED" – rerun the command with
sudo(or as root). The CLI prints the exact command to copy/paste. acme.shmissing – install it from https://github.com/acmesh-official/acme.sh as root / sudo or omit--ssl. And make sure create a symlink to be accesible globaly by all users, so,sudo acme.sh..work. You can do it with:sudo ln -sf "/root/acme.sh" /usr/local/bin/acme.sh- Nginx validation failures – inspect
nginx -toutput. The tool cancels the operation if validation fails before or after file changes. - Database errors – ensure the MySQL root user can create databases without a password or update
src/constants.rsto match your environment.
Distributed under the MIT License. See LICENSE for more information.
Sandy Figueroa: Github