SSH & Remote Work
SSH keys, tmux, tunnels, and bastion jumps - how Python developers reach staging APIs, tail journald logs, and port-forward databases without leaving sensitive keys on shared machines.
Search across all documentation pages
SSH keys, tmux, tunnels, and bastion jumps - how Python developers reach staging APIs, tail journald logs, and port-forward databases without leaving sensitive keys on shared machines.
ssh -A -J bastion@jump.acme.com deploy@staging-api.internal
tmux new -s triage
sudo journalctl -u billing-api -fWhen to reach for this:
uv run migration with disconnect-safe tmux# ~/.ssh/config
Host bastion
HostName jump.acme.com
User ubuntu
IdentityFile ~/.ssh/id_ed25519
Host staging-api
HostName 10.0.2.15
User deploy
ProxyJump bastion
LocalForward 15432 staging-db.internal:5432
# Connect and forward DB for local psql
ssh staging-api
# other terminal:
psql "postgresql://user@localhost:15432/billing"
# tmux session survives laptop sleep
tmux new -s migrate
uv run alembic upgrade head
# detach: Ctrl-b dWhat this demonstrates:
ProxyJump via bastion without manual double sshLocalForward maps remote DB to localhost-A forwards agent for git pull on remote - use cautiously.| Step | Command |
|---|---|
| Test connect | ssh -G staging-api dry config |
| Start session | tmux new -s work |
| Follow logs | journalctl -f |
| Copy artifact | scp -J bastion file deploy@host:/tmp/ |
# Remote one-liner health check
ssh staging-api 'curl -sf http://localhost:8000/health'
# Sync env file securely (avoid if secrets in file - use vault)
scp -J bastion .env.example deploy@staging-api:/opt/billing-api/-A on prod unless required.127.0.0.1:15432:....rsync -e ssh for large artifact sync.| Alternative | Use When | Don't Use When |
|---|---|---|
| AWS SSM Session Manager | No SSH keys on VMs | On-prem only SSH |
| Teleport / Boundary | Audited privileged access | Tiny team bastion OK |
| GitHub Codespaces | Cloud dev environment | Prod data access forbidden |
| VPN | Whole subnet access | Just one DB forward needed |
Ed25519 default for new keys - shorter, secure; RSA for legacy systems only.
Keychain integration --apple-use-keychain stores passphrase securely.
tmux modern default; same persistence goal.
mosh UDP roaming - nice for travel; requires server package.
ssh -R 8080:localhost:8000 exposes local FastAPI temporarily - security risk, time-box it.
Uses same SSH config; ensure remote has uv and project cloned.
sftp interactive; scp one-shot - rsync better for deploy dirs.
Host github.com-work with IdentityFile in ssh config per org.
Some compliance requires script or teleport session recording on prod.
Explicit AddressFamily inet if v6 routing broken in corp network.
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026