@hybridlabor-api/bdb-deploy
v0.1.0
Published
Universal, config-driven rsync-over-SSH deploy CLI. Works with any project — not BDB-specific — via a committed bdb-deploy.json plus a local .env for secrets.
Downloads
16
Readme
bdb-deploy
Universal, config-driven build-and-deploy CLI. Build a project, rsync the output to a server over SSH, optionally restart a remote service and verify a healthcheck URL — all from one committed config file plus a local .env for secrets. Not tied to BDB infrastructure; works for any project.
Zero dependencies.
Install
npm install -D @hybridlabor-api/bdb-deploySetup (per project)
npx bdb-deploy initAsks for build command, output directory, host, SSH user, key path, remote directory, optional restart command, optional healthcheck URL. Writes:
bdb-deploy.json— safe to commit. Structure only, no secrets (uses${VAR}placeholders)..env.example— safe to commit. Documents which env vars this project needs..env— do not commit. Holds the real host/user/key path for your machine. Added to.gitignoreautomatically.
Multiple targets (e.g. staging + production)? Run init once, then copy the targets block in bdb-deploy.json and add a second ${VAR} set to .env.
Deploy
npx bdb-deploy --target production --dry-run # see exactly what would happen, changes nothing
npx bdb-deploy --target production # the real thingIf a target is configured with "production": true, you'll be asked to type the target name to confirm (skip with --yes, but only pass that when you mean it).
If there's only one target configured, --target is optional.
Config reference
{
"version": 1,
"build": {
"command": "npm run build",
"outputDir": "dist"
},
"targets": {
"production": {
"host": "${BDB_DEPLOY_PRODUCTION_HOST}",
"user": "${BDB_DEPLOY_PRODUCTION_USER}",
"sshKey": "${BDB_DEPLOY_PRODUCTION_SSH_KEY}",
"remotePath": "/var/www/my-project/",
"restartCommand": null, // optional, runs over SSH after rsync
"healthcheckUrl": null, // optional, GET-checked after deploy
"production": true // requires typed confirmation unless --yes
}
}
}${VAR} placeholders resolve from .env (loaded first) then the real process environment (which always wins — CI secrets override local .env).
What it actually does
- Runs
build.commandin the repo root. - Hashes every file in
build.outputDir(SHA-256 over path + content, sorted) and prints it — a record of exactly what's about to ship. rsync -avz --deletethe output directory touser@host:remotePathover SSH using the configured key.--deletemeans the remote directory ends up an exact mirror of the build output — files removed locally are removed remotely too.- If
restartCommandis set, runs it over SSH after the sync. - If
healthcheckUrlis set, GETs it and fails the whole run (non-zero exit) if the response isn't OK.
Skill
skills/bdb-deploy/SKILL.md is a thin wrapper for AI agents: it tells an agent when/how to invoke this CLI and to always dry-run first, but never lets the agent construct rsync/ssh commands by hand. Copy that directory into your agent skill setup if you want an agent to be able to trigger deploys safely.
Safety notes
--deleteon rsync is powerful — a wrongremotePathmirrors your build output onto the wrong directory and deletes whatever was there. Always--dry-runa new target before the first real run.- SSH auth uses
BatchMode=yes(fails immediately instead of hanging on a password prompt) andStrictHostKeyChecking=accept-new(trusts a host's key on first connection, then verifies it matches on every subsequent connection — protects against a changed host key later, doesn't protect against a malicious host on the very first connect). - This tool never touches git. It doesn't commit, push, or care about your branch. Build-and-deploy only.
