Skip to content

Latest commit

 

History

History
77 lines (60 loc) · 7.03 KB

File metadata and controls

77 lines (60 loc) · 7.03 KB

Implementation Plan — VPS Deployment Sync via Git

[Overview] Establish a single, git-based deployment pipeline for DrusaBoT so the VPS no longer drifts from the local repo.

The repository already contains scripts/update.sh, a complete, battle-tested bash deploy script that: fetches origin, diffs local vs remote, stops services, pulls, reinstalls deps, conditionally rebuilds the frontend, and restarts services. It is git-native. However, historical deploys bypassed it entirely via Paramiko file uploads (vps_deploy.py, vps_diag.py, manual sftp_put.py). That bypass produced the documented "VPS runs an older commit; local repo has many untracked patch files" drift in project memory.

Context: the working tree on master is one commit ahead pattern; VPS creds (root@152.239.122.211, password clear-text in D:\Vault\Projects\DiscBot\vps-scripts\vps_deploy.py) are real and verified by earlier sessions. There is an active remote https://github.com/devilforcex/discbot.git. The fix is not "write a new deploy tool" — it is to make scripts/update.sh the only deploy path, delete/retire the plaintext-credential paramiko scripts, and harden the credential storage so secrets never live in a script again.

[Types] No application type-system changes are required; this is infrastructure. The only "type" is the credential model in .env:

  • VPS_HOST (str) — VPS IP/hostname, e.g. 152.239.122.211.
  • VPS_SSH_USER (str) — default root.
  • VPS_KEY_PATH (str) — path to the SSH private key used for git pull auth and deploy SSH (recommended, replaces password auth).
  • No password field is added — passwords move out of scripts entirely.

Config precedence follows the existing config.py pydantic-settings pattern: env vars in .env (gitignored), documented in .env.example.

[Files] This change touches deploy tooling and docs, not bot/dashboard application code.

  • New files:
    • scripts/deploy.sh — thin local wrapper that: (1) pushes the current master to origin, (2) invokes the VPS scripts/update.sh --branch master over SSH using the VPS SSH key from env VPS_KEY_PATH. Keeps the workflow "local push → VPS pulls" symmetrical with git semantics.
  • Modified files:
    • .env.example — add the three VPS_* documented vars from [Types].
    • docs/HOSTINGER_VPS_INSTALL.md — replace the "smart manual update" section with a new "Git-based deploy" section documenting scripts/deploy.sh, and the one-time setup: add a deploy-only SSH key on the VPS, configure VPS_KEY_PATH, and make the local repo push to origin.
    • AGENTS.md — add a "Deployment" section stating the canonical path is scripts/deploy.sh; explicitly forbid raw file uploads / sftp_put as a deploy mechanism.
    • MEMORY.md / TODO.md (repo stubs) — mark the "Decide VPS sync strategy" TODO as resolved with this plan.
  • Deleted files:
    • D:\Vault\Projects\DiscBot\vps-scripts\vps_deploy.py
    • D:\Vault\Projects\DiscBot\vps-scripts\vps_deploy2.py
    • D:\Vault\Projects\DiscBot\vps-scripts\vps_diag.py
    • (These contain the plaintext root password; deleting them is the security hardening part. They are already gitignored per prior cleanup, so deletion is safe from the repo.)
  • Configuration updates:
    • .env (local, gitignored) — add VPS_HOST, VPS_SSH_USER, VPS_KEY_PATH.
    • VPS side (run via SSH once): generate a deploy-only SSH keypair; add the public key to the VPS ~/.ssh/authorized_keys; ensure the discbot user (not root) owns the deploy path per least-privilege.

[Functions] No Python application functions change. Two bash scripts carry the logic.

  • New function (script): scripts/deploy.sh
    • Name: deploy.sh (executable bash, run from project root on the local machine).
    • Purpose: coalesce push + remote pull into one reproducible command.
    • Logic: set -e; read VPS_HOST/VPS_SSH_USER/VPS_KEY_PATH from env (or .env via a small parser); git push origin master; then ssh -i "$VPS_KEY_PATH" "$VPS_SSH_USER@$VPS_HOST" "cd /home/discbot/discbot && bash scripts/update.sh --branch master". Surf the exit code so CI/terminal can detect failure.
  • Modified function behavior (script): scripts/update.sh
    • Already correct. No code change required. It stays the canonical VPS-side updater; deploy.sh simply calls it. Optionally add a guard at the top: abort if git status --porcelain shows uncommitted changes on master, to keep deploys deterministic.
  • Removed functions: the phase dispatch inside vps_deploy.py / vps_diag.py (check/update/manual/logs/smoke/verify) — retired with the script deletion. Migration strategy: the manual and update phases map 1:1 to bash scripts/update.sh --branch master; the check/smoke/logs phases are trivially reproduced via the SSH command in deploy.sh (journalctl/systemctl). Document this mapping in the VPS install doc.

[Classes] No class changes. The only structural units are the bash scripts above; the Python VPS helper classes (Paramiko connect()/run()) are deleted with their scripts. No replacement class is introduced — SSH via native ssh client replaces Paramiko, removing a dependency and the plaintext-password vector.

[Dependencies] No new runtime packages.

  • Python: removes paramiko usage from active tooling (it stays only in the legacy sshvenv, unused). No requirements.txt change.
  • System: requires ssh/git on the local machine (already present per detected CLI tools) and git/bash on the VPS (present). A deploy-only SSH key is the new secure auth primitive, replacing password auth.

[Testing] Validation is operational, not unit-test.

  • Local dry-run of deploy.sh with --no-restart semantics honored on the remote via update.sh flags.
  • One live deploy cycle against the VPS: run deploy.sh; confirm scripts/update.sh reports "Already up to date" on a second run.
  • Post-deploy smoke: ssh ... "systemctl is-active discbot discbot-dashboard lavalink" all active; curl -s http://localhost:18080/api/health and :12333/version respond.
  • Security check: grep the workspace and D:\Vault\Projects\DiscBot\ for the root password string → zero matches after deletion.

[Implementation Order] Single coherent sequence to avoid a half-migrated state.

  1. Add VPS_HOST, VPS_SSH_USER, VPS_KEY_PATH to .env.example and to local .env.
  2. Write scripts/deploy.sh with the push + remote-update logic and set executable bit.
  3. Hardening prep on VPS: create deploy-only SSH key, install public key into authorized_keys, scope to discbot user.
  4. Retire and delete the three plaintext-credential VPS scripts from D:\Vault\Projects\DiscBot\vps-scripts\.
  5. Update docs/HOSTINGER_VPS_INSTALL.md: replace file-upload guidance with git-based deploy, document the old-phase → update.sh mapping.
  6. Update AGENTS.md deployment section + resolve the VPS-sync TODO in repo memory stubs.
  7. Run deploy.sh end-to-end; verify services + smoke endpoints; re-run to confirm idempotent "already up to date".
  8. Grep to confirm the plaintext password is gone from workspace + Vault scripts; rotate the VPS root password to close the exposed-credential gap regardless.