Files
WP-Ops/dev-panel.vincentdevelopment.ca/htdocs/README.md
2026-01-01 19:20:06 +00:00

260 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WordOps Dev Panel
A lightweight internal control panel for managing WordOps WordPress sites without forcing developers onto the CLI.
## What this does
- Lists WordOps sites (hides `dev-panel.local`)
- Create / delete sites via WordOps
- Optional bootstrap step after site creation (`wp-dev-bootstrap.sh`)
- User auth + roles:
- `admin` can see/manage all sites + manage users
- `dev` can only see/manage sites they created
- SQLite-backed storage (no external DB required)
- Password change modal + logout under a username dropdown
- Streaming output for long-running bootstrap (WordOps output may still arrive in chunks)
## Requirements
### Server
- Up-to-date Linux OS (built and tested on Ubuntu 24.04)
- [WordOps](https://wordops.net/) installed and working (`/usr/local/bin/wo`)
- [WP-CLI](https://wp-cli.org/) installed and working (`wp` in PATH)
- Nginx + PHP-FPM (WordOps provides this)
### PHP packages
Install SQLite support for PHP (required):
```bash
sudo apt update
sudo apt install -y php-sqlite3
sudo systemctl restart php8.3-fpm || true
sudo systemctl restart php-fpm || true
```
> Adjust `php8.3-fpm` to your PHP version if needed.
### File layout
Panel site lives at:
- `/var/www/<dev panel URL>/htdocs/index.php`
- `/var/www/<dev panel URL>/htdocs/includes/db.php`
- `/var/www/<dev panel URL>/htdocs/includes/functions.php`
- `/var/www/<dev panel URL>/htdocs/style.css`
- `/var/www/<dev panel URL>/htdocs/panel.sqlite (auto-created)`
Scripts live at:
- `/usr/local/bin/wp-dev-bootstrap.sh`
- `/usr/local/bin/wo-fix-perms.sh` (optional)
## Install steps
1. Create the WordOps “panel” site
`sudo wo site create <dev panel URL> --php`
Add host entry on your workstation (or internal DNS), then confirm you can load the site.
2. Drop in the panel files
Copy:
- `index.php``/var/www/<dev panel URL>/htdocs/index.php`
- `style.css``/var/www/<dev panel URL>/htdocs/style.css`
Make sure the web server can write the SQLite DB (the panel will create it on first load):
`sudo chown -R www-data:www-data /var/www/<dev panel URL>/htdocs`
> Optional: lock down later once seeded; see permissions section below
3. Install bootstrap + helper scripts
Copy:
- `wp-dev-bootstrap.sh``/usr/local/bin/wp-dev-bootstrap.sh` (custom bootstrap script)
- `wo-fix-perms.sh``/usr/local/bin/wo-fix-perms.sh` (optional)
Then:
- `sudo chmod +x /usr/local/bin/wp-dev-bootstrap.sh`
- `sudo chmod +x /usr/local/bin/wo-fix-perms.sh`
4. Allow www-data to run WordOps + scripts via sudo
Create sudoers file: `sudo visudo -f /etc/sudoers.d/dev-panel`
Contents:
```text
www-data ALL=(root) NOPASSWD: /usr/local/bin/wo *
www-data ALL=(root) NOPASSWD: /usr/local/bin/wp-dev-bootstrap.sh *
www-data ALL=(root) NOPASSWD: /usr/local/bin/wo-fix-perms.sh *
```
This lets the panel (running as www-data) execute the exact commands it needs as root.
Do not add `www-data` to the sudo group.
Test:
`sudo -u www-data sudo /usr/local/bin/wo site list`
## First login / seeding
On first load, if there are no users, the panel auto-creates:
```text
Username: admin
Password: change-me
```
Log in and change it immediately using the user dropdown → “Change password”.
### Ownership & permissions strategy
You have two competing needs:
1. WordPress / PHP needs to write certain files
2. Developers need to edit themes/plugins without being root
A safe, simple model is group-based permissions.
```bash
# Create a shared dev group
sudo groupadd webdev || true
# Add all devs to group
sudo usermod -aG webdev <devUser1>
sudo usermod -aG webdev <devUser2>
...
# Add web server user
sudo usermod -aG webdev www-data
```
Log out and back in for group membership to apply.
### Set group ownership + setgid under `/var/www`
```bash
sudo chown -R root:webdev /var/www
# Directories: 2775 (setgid + group writable)
sudo find /var/www -type d -exec chmod 2775 {} \;
# Files: 664 (group writable)
sudo find /var/www -type f -exec chmod 664 {} \;
```
### Ensure new files stay group-writable
Make sure your bootstrap script starts with `umask 0002`
If WordOps creates files with different perms, run the optional fixer after site creation:
`sudo /usr/local/bin/wo-fix-perms.sh example.local`
### SSH keys for private repos (bootstrap theme cloning)
If your bootstrap clones private repos, youll need a key that can access them.
**Option A** (recommended): deploy key or bot account key for the server
Create `/var/www/.ssh/` or `/home/<serviceUser>/.ssh/` depending on your model
**Ensure correct perms:**
- `/var/www/.ssh` or `/home/<serviceUser>/.ssh` = 700
- private key = 600
Add to GitHub as a deploy key or bot account key
Ensure `known_hosts` contains github.com to avoid prompts:
`sudo -u www-data ssh-keyscan github.com >> /var/www/.ssh/known_hosts`
**Option B:** keep bootstrap theme cloning optional and run theme cloning from a dev account via VSCode Remote.
**Dont store a personal private key in a shared server environment.**
## Daily workflow
**Option A:** (recommended) [VSCode Remote - SSH](https://code.visualstudio.com/docs/remote/ssh)
- Devs connect via SSH to the server
- Edit project files directly under `/var/www/<site>/htdocs`
- Panel handles provisioning + bootstrap + ownership metadata
- No need for tooling (`node`, `php`, etc) on user machines beyond VSCode + SSH
**Option B:** SMB shares (with SSH tunnel)
- Export `/var/www` (or per-site roots) via Samba
- Use group permissions (webdev) so edits behave identically to SSH
- Map network drives on dev machines
- Requires tooling (`node`, `php`, etc) on user machines for composer, Tailwind, etc
## Troubleshooting
### “PDOException: could not find driver”
PHP SQLite extension missing:
```bash
sudo apt install -y php-sqlite3
sudo systemctl restart php8.3-fpm || sudo systemctl restart php-fpm
```
### WordOps fails when run as www-data
Dont run wo as www-data directly:
**Correct** (what the panel does):
`sudo -u www-data sudo /usr/local/bin/wo site list`
**Incorrect**:
`sudo -u www-data /usr/local/bin/wo site list`
### WordOps delete prompts / EOFError
Use `--no-prompt` on deletes (panel already does).
### Panel isnt streaming output
Bootstrap output streams (proc_open + flush)
WordOps sometimes buffers; thats normal. The panel will still show output when it arrives.
## Security notes
The panels `sudoers` file is the main security boundary:
- Keep it as narrow as possible
- Avoid wildcarding unrelated commands
- Consider restricting panel access by:
- Internal network only
- VPN only
- HTTP basic auth in front of it
- Keep OS patches current
- Regularly audit panel users + roles
## Backups (minimum viable)
At minimum, back up:
- /var/www (all site roots)
- Databases (WordOps MariaDB/MySQL)
- `/etc/nginx` and WordOps configs (optional but helpful)
- Panel SQLite DB:
- `/var/www/dev-panel.local/htdocs/panel.sqlite`
## Next steps / nice-to-haves
- “Fix perms” button in the panel post-create
- Per-site notes (who/why) for management visibility
- Audit log for create/delete/bootstrap actions
- Optional “clone template site” support