Server deploy
Cross-project agent workflow skills — session onboarding, handoffs, PR review, and merge workflows
npx -y skills add jsirish/workflow-skills --skill server-deployAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Push local databases and assets to a remote pre-prod or staging server using deploy.sh. Use during major version upgrades or when deploying pre-computed public/assets to a staging environment. See server-sync for the reverse direction.
SKILL.md
7.6 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it
Server Deploy — Push Local → Remote
Pushes local content state (database and assets) from a DDEV environment up to a remote pre-prod or staging server using deploy.sh.
[!WARNING]
deploy.shis highly destructive. It will drop and overwrite the remote database and assets. Always confirm the destination environment before running.
[!CAUTION] NEVER run
deploy.shwhenPREPROD_*points to the master content source. If pre-prod is the environment where editors work (e.g. production is not yet live), overwriting pre-prod with local data destroys the authoritative content. In this case,PREPROD_*should remain empty anddeploy.shshould not be used at all.
Prerequisites / Safety
[!IMPORTANT]
deploy.shruns on the HOST (bash deploy.sh). It shells out toddev execinternally (to dump the local DB) and validates thatddevis in PATH. Running it viaddev exec ./deploy.shfails immediately — there is noddevbinary inside the container.
# Push local → pre-prod: runs on the HOST (it calls ddev exec internally)
bash deploy.sh
[!WARNING]
deploy.shwill push your localSS_DEFAULT_ADMIN_*account to the remote target. If.envhasSS_DEFAULT_ADMIN_USERNAME/PASSWORDset (common for freshdev/buildconvenience), localdev/buildmaterializes those dev credentials as a realMemberrow with a bcrypt hash. The DB-push phase ofdeploy.shdumps and imports the entire localMembertable, so every deploy re-introduces (or refreshes) an admin login with dev credentials on the remote target — a real security hole if left in place.Fix: Once real CMS accounts exist for local login, comment out
SS_DEFAULT_ADMIN_*in local.env— root-cause fix, rather than deleting the leakedMemberrow after every deploy.
Environment Configuration (.env)
deploy.sh reads PREPROD_* vars from the project .env:
PREPROD_USER="username"
PREPROD_HOST="target-host.com"
PREPROD_ASSETS_PATH="/var/www/html/public/assets"
PREPROD_DB_NAME="db_name"
PREPROD_DB_USER="db_user"
PREPROD_DB_PASSWORD="db_password"
PREPROD_DB_HOST="localhost"
Local execution relies on the application's database environment variables (SS_DATABASE_NAME, SS_DATABASE_SERVER for SilverStripe; adapt to your framework's equivalents).
[!CAUTION]
REMOTE_*andPREPROD_*must point at DIFFERENT hosts.sync.shreadsREMOTE_*(pull FROM).deploy.shreadsPREPROD_*(push TO). If both vars resolve to the same host, you pull from pre-prod and deploy to pre-prod — production is never touched. Always verify before migration work:grep -E "REMOTE_HOST|PREPROD_HOST" .env # must be two DIFFERENT hosts grep "^PREPROD_" deploy.sh # deploy.sh must read PREPROD_*
Command Flags
| Flag | Description |
|---|---|
--help | Shows usage information |
--dry-run | Tests the rsync without writing to the remote disk or executing the remote DB import. Note: the local DB dump and remote push are executed even in dry-run mode — only the remote import/restore is skipped. See the dry-run caution below. Always recommend running --dry-run first. |
--assets | Bypasses the database phase. Only syncs public/assets/. |
--db | Bypasses the asset rsync phase. Only dumps and imports the database. |
--exclude=PATTERN | Exclude specific files or globs from the rsync cycle (repeat for multiple patterns). Example: --exclude=*.log --exclude=_resampled/ |
Script Internal Logic
- DB segment: Dumps the local
SS_DBto/tmp, gzips it, pushes to the remote/tmpviarsync, then executesgunzip | mysqlvia SSH on the remote to overwrite the target DB. - Cleanup: Removes the local staging dump and the remote pushed dump from
/tmp. - Assets segment: Executes
rsync --deleteto push local/assets/to the target server.
[!TIP] Run heavy local computation (e.g.
GalleryResampleTask) beforedeploy.sh --assetsto offload processing burden from the remote VPS.
Dry-Run Caution
[!WARNING]
--dry-runcreates — and, if cleanup is gated incorrectly, leaves — DB dumps that are never removed.deploy.shproduces two dumps during a push: a local staging dump and a copy pushed to the remote/tmp. If cleanup is gated on!dry-run, every--dry-runsilently accumulates both dumps — a data-at-rest exposure on both the local host and the remote server.Fix: Make cleanup unconditional for both dumps — they are always created, so they must always be removed:
# Always remove the local staging dump rm -f ${LOCAL_DUMP_PATH} # Always remove the remote pushed dump ssh ${PREPROD_USER}@${PREPROD_HOST} "rm -f /tmp/${LOCAL_DB_NAME}_deploy_${TIMESTAMP}.sql.gz"The dry-run gate should guard only the remote import/restore step. Audit your local
deploy.shto confirm both cleanup steps are unconditional.
DeployHQ / Ploi Caveats
deploy.sh moves data; the actual code deploy is usually handled by DeployHQ (build + SSH) onto a Ploi-managed server. These behaviours are not obvious from the scripts.
[!CAUTION] DeployHQ deploys from the git remote, not your working copy — check for unpushed commits first. If your deploy branch has local commits you haven't pushed,
dhq deploysilently ships the older remote revision. Run a preflight before every deploy:git log origin/<branch>..<branch> --oneline # must be empty before dhq deploy
[!CAUTION]
composer installskips packages whose constraint is already satisfied. On a server with an existingvendor/,composer installwill not re-fetch a package just because the locked content changed — leaving stale or mismatched code. For a clean parity deploy, wipe first:rm -rf vendor && composer install --no-dev -oAdd
rm -rf vendorto the DeployHQ post-deploy SSH command (or build step) so every deploy starts from a clean vendor tree.
[!WARNING] DeployHQ deletes files that are removed from git. When a tracked file is de-tracked, DeployHQ deletes it from the server on the next deploy. Keep server-only files (
.env, secrets, uploaded assets outsidepublic/assets/) in DeployHQ's config files / excluded paths feature, or recreate them out-of-band — never assume a de-tracked file survives on the server.
[!WARNING] Ploi requires
127.0.0.1, notlocalhost, as the database server. On Ploi-managed servers,localhostresolves to a MySQL socket path rather than the TCP interface, causing connection failures. Use the TCP loopback in the server.env:# SilverStripe: SS_DATABASE_SERVER="127.0.0.1" # Other frameworks: set the equivalent DB_HOST / DATABASE_URL host to 127.0.0.1
Terminology
| Term | Meaning | Tool |
|---|---|---|
| Code deploy | Deploys application code (PHP/CSS/JS) via CI/CD | dhq deploy (DeployHQ), or your CI pipeline |
| Content sync | Pulls DB + assets FROM the authoritative source to local | sync.sh (via ddev exec ./sync.sh) — see server-sync |
| Content push | Pushes local DB + assets TO a target environment | deploy.sh (via bash deploy.sh) |
"Deploy" alone is ambiguous — always qualify as "code deploy" or "content push."