Connect to Vast.ai GPU instances: sync SSH configs, set up your project, and open your IDE.
Project description
Vastly
Connect to Vast.ai GPU instances from your terminal: sync SSH configs, set up your project remotely, and open your IDE in one command.
Install
Requires the Vast.ai CLI (pip install vastai && vastai set api-key YOUR_KEY) and VS Code or Cursor with the Remote-SSH extension.
pip install vastly
This gives you two equivalent commands: vastly and vst (shorthand).
Quick Start
cd your-project # any local git repo
vst # syncs SSH, sets up remote, opens IDE
Why Vastly
Without vastly, you repeat this for every new instance:
# without vastly
# 1. Copy SSH command from Vast.ai dashboard
# 2. VSCode → Remote-SSH: Connect to Host → paste command
# 3. On the remote instance:
cd /workspace && git clone ... # clone your project
pip install -r requirements.txt # install deps
git config user.name ... # configure git identity
# set up git auth
# copy over .env, config files, etc. that aren't in git
# fix "Permission denied (publickey)" because you forgot -A
# with vastly
vst
vst does all of this for you -- syncs SSH configs with agent forwarding, clones your repo, installs deps, activates your Python environment, copies configured files not in git, and opens your IDE. On repeat runs, setup is skipped.
- Named instances --
1xRTX4090-TWinstead of IPs (duplicates get the instance ID appended); pick from a list when you have multiple; assign custom aliases withvst name - Auto-start -- if no running instances,
vststarts a stopped one and connects - Environment auto-detection -- activates conda/venv on Vast.ai images, auto-detects uv, pip, or setup.py for dependency install
- SSH agent forwarding -- authenticate with git hosts without copying keys to the instance
- File transfer --
vst cp up .env/vst cp down results/without remembering IPs - Per-project config --
.vastly.jsonin your repo root for project-specific settings
Commands
vst # connect to your instance and open IDE
vst [name] # connect by name or alias
vst --all # connect to all running instances
vst -f # re-run remote setup even if already done
vst -n # open IDE without cloning or installing
vst list # list all instances (running, stopped, etc.)
vst start [name | --all] # start a stopped instance, wait, then connect
vst start -n # start without connecting
vst stop [name | --all] [-y] # stop an instance (or all)
vst destroy [name | --all] [-y] # destroy an instance (irreversible)
vst ssh [name] [command...] # SSH into an instance or run a remote command
vst cp up|down <paths...> # copy files to/from remote
vst name <alias> [-i inst] [--clear] # assign a custom name to an instance
vst config # show current configuration
Use -v / --verbose with any command for debug output.
When you have multiple instances, commands that target a single instance prompt you to pick one. You can skip the prompt by passing a name or alias directly.
Configuration
On first run, vastly creates ~/.vastly/config.json with defaults:
{
// "code" or "cursor" (auto-detected on first run; overridden when run inside an IDE terminal)
"ide": "code",
// Path to SSH private key. null = use your SSH config or ssh-agent
"sshKeyPath": null,
// SSH user on remote instances
"sshUser": "root",
// Ports to forward to localhost. Set to [] to disable
// Local ports auto-increment when multiple instances are running
"portForwards": [
{ "local": 8080, "remote": 8080 }
],
// Remote directory where projects are cloned
"workspace": "/workspace",
// Creates ~/.no_auto_tmux to prevent auto-tmux on Vast images
"disableAutoTmux": false,
// Which git remote to read the repo URL from
"gitRemote": "origin",
// Commands to run after dependency install
// e.g. ["curl -fsSL https://claude.ai/install.sh | bash"]
"postInstall": [],
// Override auto-detected install method
// null = auto-detect (uv.lock/pyproject[tool.uv] -> pyproject[project] -> requirements*.txt -> setup.py)
// e.g. "uv sync", "pip install -e '.[dev]'", "conda env update -f environment.yml"
"installCommand": null,
// Files/directories to copy from local repo to remote after setup
// Paths are relative to the repo root. Directories are copied recursively
// e.g. [".claude/", ".env.template"]
"copyFiles": []
}
Per-project config
You can create a .vastly.json in your repo root to set project-specific configuration. Project config overrides the global config for these keys only:
postInstallinstallCommandworkspaceportForwardscopyFilesgitRemote
User-specific keys (ide, sshKeyPath, sshUser, disableAutoTmux) are always read from the global ~/.vastly/config.json and ignored in project configs.
Note:
postInstallandinstallCommandrun as shell commands on your remote instance during setup. Review.vastly.jsonbefore runningvstin unfamiliar repositories, just as you would review aMakefileorpackage.jsonscripts.
// .vastly.json (in repo root)
{
"postInstall": ["make setup"],
"copyFiles": [".claude/"]
}
Authentication
To clone private repos or push to any repo, you need to authenticate with your git host:
- SSH remotes (
git@github.com:...): Vastly enables SSH agent forwarding automatically. Your local SSH key is used for the duration of the connection -- never copied to the instance. Make sure your key is loaded in your SSH agent (ssh-add -lto check). - HTTPS remotes (
https://github.com/...): Public repos clone without authentication, but pushing requires a personal access token. You can configure one on the instance, or switch to an SSH remote:git remote set-url origin git@github.com:user/repo.git.
Troubleshooting
"Missing: vastai CLI" -- pip install vastai, then vastai set api-key <key>.
SSH connection timeout -- Instance may still be booting. Setup retries 3 times. Run vastai show instances to check status.
"Not in a git repo" -- vastly reads the remote URL from your local repo. Run from inside a git repo, or use vst --no-setup.
"Cannot access repo" -- For SSH remotes, check that your SSH agent is running and your key is loaded (ssh-add -l). For HTTPS remotes, you may need a personal access token or to switch to SSH (see Authentication above).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vastly-0.4.0.tar.gz.
File metadata
- Download URL: vastly-0.4.0.tar.gz
- Upload date:
- Size: 63.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
109949b636dd21d8e72f600a0ab267f86fba835eb6dea72122c4367b5c45452d
|
|
| MD5 |
0a5ff2f9c006804f6586924757c70103
|
|
| BLAKE2b-256 |
47355a71f716ead3f4213d91a2a1080cda1132d99b3dc21dfcdd83b5c987eee3
|
File details
Details for the file vastly-0.4.0-py3-none-any.whl.
File metadata
- Download URL: vastly-0.4.0-py3-none-any.whl
- Upload date:
- Size: 37.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
423682aaf27a510455de18e3ef59dc4857d159e6b14e3391353546e2324102bc
|
|
| MD5 |
32a68dcdb16985260a13bc4a7c75e515
|
|
| BLAKE2b-256 |
5e145ab1feee57e5b5794d4b3153fdb3bf80e5b32f243a6cf17f7d05126e92f9
|