Install
openclaw skills install wordpress-vps-installBootstrap a fresh VPS with WordPress installed and verified end-to-end; use when you need to provision the stack, align volumes and environment variables, run WP-CLI installation, and confirm the public site is live.
openclaw skills install wordpress-vps-installUse this skill when setting up a brand-new VPS so WordPress installs successfully and the public site comes online cleanly.
This skill covers:
.env bootstrap values for WordPress and database setupBefore first deploy in a new WordPress VPS repo, ensure non-runtime folders are not synced:
.claude/.cursor/.trellis/docs/ (unless user explicitly wants docs versioned)Commands:
# add ignore rules
printf "\n.claude/\n.cursor/\n.trellis/\ndocs/\n" >> .gitignore
# stop tracking already-committed folders without deleting local files
git rm -r --cached .claude .cursor .trellis docs
Rule:
All services must be created and managed through Dokploy only.
Hard rules:
docker compose up outside Dokploy CLI/API project management.1. Confirm the public domain and target VPS
2. Inspect the container stack and compose files
3. Verify the WordPress volume, DB env, and proxy labels
4. Fix the smallest missing piece
5. Run WP-CLI install against the live volume
6. Verify the domain returns 200 and the homepage loads
Before any docker compose up/down or compose edits on VPS:
# 0.1 identify the exact Dokploy project and compose path
docker inspect <wordpress-container> --format '{{ index .Config.Labels "com.docker.compose.project" }} {{ index .Config.Labels "com.docker.compose.project.config_files" }}'
# 0.2 mandatory backup (compose + env) with timestamp
TS="$(date +%Y%m%d-%H%M%S)"
cp /etc/dokploy/compose/<project>/code/docker-compose.yml /etc/dokploy/compose/<project>/code/docker-compose.yml.bak.$TS
cp /etc/dokploy/compose/<project>/code/.env /etc/dokploy/compose/<project>/code/.env.bak.$TS
# 0.3 validate with explicit project name and env file
cd /etc/dokploy/compose/<project>/code
docker compose -p <project> --env-file .env config >/tmp/<project>.resolved.yml
Hard rules:
docker compose without -p <project> on Dokploy hosts.code-* stacks)..env.cp docker-compose.yml.bak.<timestamp> docker-compose.yml
cp .env.bak.<timestamp> .env
docker compose -p <project> --env-file .env up -d
Collect the minimal target info:
Check the running services, network, and mounts.
docker ps --format "{{.ID}} {{.Image}} {{.Names}} {{.Status}}"
docker inspect <wordpress-container>
docker inspect <db-container>
Verify:
The install job must use the real live env values, not placeholders.
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' <wordpress-container> | grep -E 'WORDPRESS_|MYSQL_'
Check:
WORDPRESS_DB_HOSTWORDPRESS_DB_NAMEWORDPRESS_DB_USERWORDPRESS_DB_PASSWORDWORDPRESS_URLWORDPRESS_TITLEWORDPRESS_ADMIN_USERWORDPRESS_ADMIN_PASSWORDWORDPRESS_ADMIN_EMAILThe WP-CLI container must operate on the same /var/www/html data as the live WordPress container.
Good patterns:
--volumes-from <wordpress-container>/var/www/htmlBad patterns:
wp in a container that cannot see the live site filesUse the live WordPress files and the real DB credentials.
docker run --rm \
--network <wordpress-network> \
--volumes-from <wordpress-container> \
--entrypoint sh \
-e WORDPRESS_DB_HOST=<db-host> \
-e WORDPRESS_DB_NAME=<db-name> \
-e WORDPRESS_DB_USER=<db-user> \
-e WORDPRESS_DB_PASSWORD=<db-password> \
-e WORDPRESS_URL=https://example.com \
-e WORDPRESS_TITLE="Site Name" \
-e WORDPRESS_ADMIN_USER=admin \
-e WORDPRESS_ADMIN_PASSWORD='change-me' \
-e WORDPRESS_ADMIN_EMAIL=admin@example.com \
wordpress:cli-php8.2 -lc '
if ! wp core is-installed --path=/var/www/html --allow-root; then
wp core install --path=/var/www/html --allow-root \
--url="$WORDPRESS_URL" \
--title="$WORDPRESS_TITLE" \
--admin_user="$WORDPRESS_ADMIN_USER" \
--admin_password="$WORDPRESS_ADMIN_PASSWORD" \
--admin_email="$WORDPRESS_ADMIN_EMAIL" \
--skip-email;
fi;
wp theme activate <theme-slug> --path=/var/www/html --allow-root || true;
wp plugin activate <plugin-slug> --path=/var/www/html --allow-root || true;
'
If wp or rg is missing, install baseline tools on the VPS host:
apt-get update -y
apt-get install -y ripgrep curl less php-cli php-curl php-mbstring php-xml
curl -fsSL https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp
chmod +x /usr/local/bin/wp
wp --info
rg --version
Important:
wp interactively inside a running container is usually ephemeral and may disappear after redeploy.Preferred durable approach:
wpcli service in docker-compose.yml using wordpress:cli-*./var/www/html) and same project bind mount (./wp-content) as the app container.restart: unless-stopped and a long-running sleep loop), so docker exec <wpcli-container> wp ... is always available.profiles: ["setup"] if ongoing CLI access is required.command: ["sleep", "infinity"] (preferred) instead of shell loop strings to avoid quoting/parsing errors.Example durable service shape:
wpcli:
image: wordpress:cli-php8.2
restart: unless-stopped
depends_on:
db:
condition: service_healthy
wordpress:
condition: service_started
volumes:
- wordpress_data:/var/www/html
- ./wp-content:/var/www/html/wp-content
command: ["sleep", "infinity"]
If the install fails with database connection errors:
If wp db check fails with a certificate error:
If the domain still returns 404 after containers are healthy:
If install succeeds but the site still shows install or old content:
If host wp works but app/container commands fail:
/var/www/html with wp-config.phpwpcli service over patching the web containerdocker exec <wpcli-container> sh -lc 'cd /var/www/html && wp --allow-root <command>'
curl -k -I https://example.com/
curl -k https://example.com/ | head
Expect:
200 response on the public URL.env values on the VPS.The install is complete when:
200wp core is-installed succeeds on the live volume