{"id":50270697,"url":"https://github.com/jobordu/just-akash","last_synced_at":"2026-05-27T17:30:25.359Z","repository":{"id":350651281,"uuid":"1207725735","full_name":"jobordu/just-akash","owner":"jobordu","description":"CLI to deploy and manage Akash Network deployments — with lease-shell WebSocket transport (no SSH required)","archived":false,"fork":false,"pushed_at":"2026-05-09T13:44:04.000Z","size":494,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-09T15:41:28.683Z","etag":null,"topics":["akash","akash-network","blockchain","cloud-computing","deployment","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jobordu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-11T10:11:04.000Z","updated_at":"2026-05-09T13:44:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jobordu/just-akash","commit_stats":null,"previous_names":["jobordu/just-akash"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/jobordu/just-akash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jobordu%2Fjust-akash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jobordu%2Fjust-akash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jobordu%2Fjust-akash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jobordu%2Fjust-akash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jobordu","download_url":"https://codeload.github.com/jobordu/just-akash/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jobordu%2Fjust-akash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33577630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["akash","akash-network","blockchain","cloud-computing","deployment","websocket"],"created_at":"2026-05-27T17:30:24.567Z","updated_at":"2026-05-27T17:30:25.353Z","avatar_url":"https://github.com/jobordu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# just-akash\n\nJustfile recipes + Python CLI for deploying on [Akash Network](https://akash.network) via the Console API.\n\nSelf-contained — clone, configure `.env`, and run.\n\n## What's New in v1.6.0\n\n- **Tiered provider selection** — preferred + backup allowlists with a 3-phase bid-selection state machine (`AKASH_PROVIDERS_BACKUP` env var, `--provider` / `--backup-provider` CLI flags). See [Bid Selection](#bid-selection).\n- **BME migration** — bid-price denom defaults updated from `uakt` (legacy) to `uact`.\n- **Hardened e2e cleanup** — `robust_destroy()` with retry + audit, SIGINT/SIGTERM-safe handler, no-leak guarantee on multi-deployment runs.\n- **653 tests** (109 new); `just_akash/deploy.py` and `just_akash/_e2e.py` at 100% line coverage.\n\n## Prerequisites\n\n- Python 3.10+\n- [`uv`](https://docs.astral.sh/uv/) (Python package runner)\n- [`just`](https://github.com/casey/just) command runner (optional, but recommended)\n\n## Setup\n\n```bash\ngit clone https://github.com/jobordu/just-akash\ncd just-akash\ncp .env.example .env\n# Edit .env — add your API key, providers, SSH pubkey\nuv sync --dev           # install package + dev tools (ruff)\nuv run pre-commit install   # install gitleaks + ruff hooks\n```\n\n## Usage\n\n### With `just` (recommended)\n\n| Command | Usage | Purpose |\n|---|---|---|\n| `just deploy [sdl] [image]` | `just deploy` | Deploy with custom SDL/image |\n| `just up [tag]` | `just up my-web-app` | Deploy SSH instance + optional tag |\n| `just connect [dseq] [transport]` | `just connect 12345 ssh` | Connect to a running instance (lease-shell default) |\n| `just exec [dseq] \"cmd\" [transport]` | `just exec 12345 \"ls -la\"` | Execute a remote command |\n| `just inject [dseq] [env-file] [transport]` | `just inject 12345 .env.secrets` | Inject secrets (lease-shell default) |\n| `just destroy [dseq]` | `just destroy 12345` | Destroy an instance |\n| `just destroy-all` | `just destroy-all` | Destroy all instances |\n| `just list` | `just list` | List active instances |\n| `just status [dseq]` | `just status 12345` | Show instance details |\n| `just tag [dseq] [name]` | `just tag 12345 my-db` | Tag a deployment with a name |\n| `just test-shell` | `just test-shell` | E2E lease-shell transport test (deploy/exec/inject/cleanup) |\n| `just test-secrets` | `just test-secrets` | E2E secrets injection test (SSH inject + lease-shell cross-check) |\n| `just lint` | `just lint` | Ruff lint + format check |\n| `just secrets` | `just secrets` | Gitleaks secret scan |\n\nTransport: `connect`, `exec`, and `inject` default to `lease-shell`. Pass `ssh` as the last argument to force SSH: `just exec 12345 \"cmd\" ssh`.\n\n### DSEQs vs Tags\n\n**DSEQ** (Deployment Sequence) is the unique numeric ID assigned by Akash when you create a deployment.\n\n**Tags** are human-readable names you can assign to DSEQs for easier management.\n\n```bash\njust up my-web-app         # Deploy and tag as \"my-web-app\"\njust status my-web-app     # Check status using tag\njust connect my-web-app    # Connect in using tag\njust destroy my-web-app    # Destroy using tag\n```\n\n### Secrets Injection\n\nInject secrets into a running deployment — **no SSH required** (lease-shell is the default).\n\n```bash\n# From a file (lease-shell, default)\njust inject \"\" .env.secrets\n\n# Force SSH transport\njust inject 12345 .env.secrets ssh\n\n# Or with inline CLI args\nuv run just-akash inject --dseq 12345 --env SECRET_KEY=abc --env DB_PASS=xyz\n\n# From a file\nuv run just-akash inject --dseq 12345 --env-file .env.secrets\n```\n\nSecrets are written to `/run/secrets/.env` (or custom `--remote-path`) with `chmod 600`.\n\n### With `uv run` (direct CLI)\n\n```bash\n# Deploy\nuv run just-akash deploy --sdl sdl/cpu-backtest-ssh.yaml\n\n# Deploy with env vars (provider-visible)\nuv run just-akash deploy --sdl sdl/cpu-backtest-ssh.yaml --env REGION=us-east\n\n# Connect / exec / inject\nuv run just-akash connect --dseq 12345\nuv run just-akash exec --dseq 12345 \"echo hello\"\nuv run just-akash inject --dseq 12345 --env-file .env.secrets\n\n# Force SSH transport\nuv run just-akash exec --dseq 12345 --transport ssh \"echo hello\"\nuv run just-akash inject --dseq 12345 --transport ssh --env-file .env.secrets\n\n# List / status / destroy\nuv run just-akash list\nuv run just-akash status --dseq 12345\nuv run just-akash destroy --dseq 12345\nuv run just-akash tag --dseq 12345 --name my-job\n```\n\n## Environment Variables\n\n| Variable | Required | Description |\n|---|---|---|\n| `AKASH_API_KEY` | Yes | Console API key |\n| `AKASH_PROVIDERS` | No | Comma-separated allowlist of **preferred** provider addresses (empty = accept any) |\n| `AKASH_PROVIDERS_BACKUP` | No | Comma-separated allowlist of **backup** providers used only when no preferred bids arrive |\n| `SSH_PUBKEY` | For SSH SDL | SSH public key (injected into container) |\n| `AKASH_CONSOLE_URL` | No | Console API base URL (default: `https://console-api.akash.network`) |\n| `AKASH_DEBUG` | No | Set to `1` for verbose API/deploy logging |\n\n## Transports\n\n`exec`, `inject`, and `connect` support two transports:\n\n### Lease-shell (default)\n\nUses the Akash Console WebSocket proxy (`wss://console.akash.network/provider-proxy-mainnet`) to relay commands to the provider. **No SSH required.** The proxy connects to the provider using a JWT with provider-scoped permissions.\n\n```bash\njust exec 12345 \"echo hello\"              # lease-shell (default)\njust inject 12345 .env.secrets          # lease-shell (default)\n```\n\n### SSH\n\nTraditional SSH connection to the container. Requires an SSH-enabled SDL and `SSH_PUBKEY` configured.\n\n```bash\njust exec 12345 \"echo hello\" ssh        # force SSH\njust inject 12345 .env.secrets ssh      # force SSH\n```\n\n## Bid Selection\n\nDeployments use a three-phase tiered bid-selection state machine. Bids stream\nin from `t=0` regardless of tier (Akash's auction is open; the tier is a\nclient-side filter).\n\n| Phase | Window | Behavior on bid arrival | Decision at window end |\n|---|---|---|---|\n| 1. Preferred-only patience | `[0, T1]` (`--bid-wait`, default 60s) | Collect all bids; do not select yet | If any **preferred** bid collected → pick **cheapest preferred** and stop |\n| 2. Preferred-grace | `[T1, T1+T2]` (`--bid-wait-retry`, default 120s) | Continue collecting; the moment a **preferred** bid appears, accept it **immediately** (first-wins) | If still no preferred → fall through |\n| 3. Backup fallback | end of phase 2 | — | Pick **cheapest backup** from bids collected across phases 1+2 |\n\nProperties:\n\n- **Cheapest-when-healthy.** Preferred providers responsive → cheapest preferred wins.\n- **Bounded patience.** Preferred slow but alive → wait at most `T1+T2`, then snap to first preferred.\n- **Graceful degradation.** Preferred fully down → cheapest backup wins, no extra round trip.\n\n### Tiered providers\n\nTwo tiers configure which providers are eligible:\n\n```bash\n# env-var form\nexport AKASH_PROVIDERS=akash1pref1,akash1pref2          # preferred (tier 1)\nexport AKASH_PROVIDERS_BACKUP=akash1back1,akash1back2   # backup (tier 2)\n\n# CLI override (repeatable, overrides env when set)\nuv run just-akash deploy \\\n  --provider akash1pref1 --provider akash1pref2 \\\n  --backup-provider akash1back1\n```\n\nWhen `AKASH_PROVIDERS_BACKUP` is unset, deploy behaves identically to the\nsingle-tier allowlist (zero regression). With no allowlist at all (neither\npreferred nor backup), the cheapest bid from any provider wins.\n\nEach bid is tagged in the log as `[PREFERRED]`, `[BACKUP]`, or `[FOREIGN]`,\nand the selection log line names which phase chose the winner.\n\n## Logs\n\nEvery `just` recipe writes timestamped logs to `.logs/just/` with start/end metadata, exit codes, and full output.\n\n## Secret Scanning\n\nThree layers of secret detection run on every push/PR:\n\n- **Gitleaks** — pre-commit hook + CI (full history on schedule)\n- **TruffleHog** — CI (verified secrets only)\n- **detect-secrets** — baseline diff check in CI\n\n## License\n\n[MIT](LICENSE) — Jonathan Borduas\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjobordu%2Fjust-akash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjobordu%2Fjust-akash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjobordu%2Fjust-akash/lists"}