A plain-language guide for anyone who wants an AI agent (or a teammate) to actually run a WordPress plugin in the cloud — and understand what’s happening under the hood. Many people follow in our footsteps here, so this is written to be copied.
The problem: a plugin is a brick, not a castle
A WordPress plugin is an add-on. On its own it does nothing — it only comes alive once it’s snapped into a running WordPress website. So when you clone a plugin repository and ask “how do I run this?”, the honest answer is: you can’t, until you build the whole website around it first.
Think of it like LEGO. The plugin is one special brick. It needs a castle (WordPress) to snap into, and the castle needs a baseplate (a web server and a database). “Setting up the dev environment” just means building the whole castle around the brick so you can see the brick work.
| Piece | LEGO analogy | Real thing | Why it’s needed |
|---|---|---|---|
| The plugin | the special brick | your plugin repo | the thing you’re building |
| WordPress | the castle | WordPress core | the app the plugin plugs into |
| PHP | the castle’s language | PHP 8.3 | WordPress is written in PHP |
| MariaDB | the filing cabinet | MariaDB (MySQL-compatible) | stores pages, settings, options |
| WP-CLI | a magic remote control | the wp command |
installs/configures WordPress without clicking |
A Cloud Agent environment has two layers
When an AI coding agent spins up a fresh cloud machine, its environment is built in two layers:
- The base layer (a saved snapshot). The operating system plus the slow, stable pieces — PHP, MariaDB, WP-CLI, and a ready WordPress install. This is captured once so nobody rebuilds it from scratch every time.
- The repository layer (two scripts). After your code is checked out, an
installscript prepares the project, and astartscript turns services on each time the machine boots.
The rule of thumb: slow and stable goes in the base layer; project-specific setup goes in install; turn-it-on-every-boot goes in start.
What the two scripts do
install — builds and repairs the setup (safe to re-run)
“Idempotent” is the key word: running it twice changes nothing the second time. It makes sure the tools exist, starts the database, creates a dev database, downloads and installs WordPress, turns on pretty permalinks, then symlinks the plugin into WordPress and activates it. Because it auto-detects where the code was checked out, it works no matter which folder the agent lands in.
start — turns things on every boot
It starts the database, waits until it answers, then runs the WordPress dev server on port 8080 and stays attached so its logs are visible. The site then lives at http://localhost:8080.
Why the web server lives in start: the cloud build/save config only accepts install and start — there’s no separate “long-running server” slot — and start is explicitly allowed to be a dev server that stays attached. So that’s where it belongs.
Proving it works: a real “hello world”
Starting a server is not proof. You have to make the plugin actually do something. Three checks close the loop:
- Admin UI: log into wp-admin and confirm the plugin’s menu, settings page, and dashboard widget all render with no PHP errors.
- Read path: call the plugin’s REST endpoint and confirm it answers correctly.
- Write path: send data to a second endpoint, then read it back out of the database — proof the whole request → plugin → database chain works.
What is the “REST API,” in plain words?
Imagine the plugin installs a few mailboxes on the website, each with its own web address. Any program — a form on a page, a dashboard, or an outside service — can drop a note in a mailbox, and the plugin reads it and does a job: hand back data, save a setting, create a record. Hitting one of those addresses and getting the expected answer back is the simplest possible “yes, the plugin is awake and wired up” test.
The last mile: photo → recipe → verify → Save
Building the whole castle by hand every time is slow, so the finish line is:
- Snapshot the finished machine (a photo of the working castle).
- Build a draft environment from that snapshot plus the
install/startscripts, and confirm it succeeds. - Verify by booting a brand-new agent from that build and re-running the checks.
- Save (a human click). This makes the tested setup the default for every future agent on the repo.
After Save, the next person — human or AI — gets a working WordPress with the plugin already snapped in, in seconds instead of by hand.
Gotchas we hit, so you don’t have to
| Gotcha | Symptom | Fix |
|---|---|---|
| Plain permalinks | /wp-json/… returns the homepage instead of JSON |
Switch to pretty permalinks (/%postname%/) |
start doesn’t auto-run from a draft build |
A fresh agent from a draft build has its database and server down | Expected for draft builds only — on a Saved environment, start runs on every boot |
| No separate server slot | Wanting a dedicated long-running-server field | Put the dev server in start (it can stay attached) |
| Database client conflict | default-mysql-client won’t install next to MariaDB |
Use mariadb-client (it provides the mysql command) |
Reproduce it yourself
On a fresh Ubuntu machine:
- Install PHP and extensions, MariaDB, and WP-CLI.
- Start MariaDB; create a database and a local dev user.
wp core download, thenwp config create, thenwp core install.wp rewrite structure '/%postname%/'for pretty permalinks.- Symlink your plugin into
wp-content/plugins/andwp plugin activateit. wp server --host=0.0.0.0 --port=8080.- Visit
/wp-admin/and the plugin’s REST endpoint to confirm it’s alive.
That’s exactly the sequence the install and start scripts automate.
The one-paragraph version
A plugin is a brick, so you build a WordPress “castle” around it to run it. An install script builds and repairs that setup (safe to re-run) and a start script turns the database and web server on each boot. You prove it works with a real action — the plugin’s REST endpoint answering and a database write round-trip — then you snapshot, build, verify, and Save so everyone after you starts with a working environment instantly. Build the slow, stable parts once; automate the rest; and never trust “it started” as proof — make it actually do something.
