Loading...
Loading...
Deploy and operate services on Lightning AI - run Docker containers or HuggingFace models (vLLM) behind autoscaled HTTPS endpoints, manage replicas, releases, endpoint auth, and logs. Use when the user wants to deploy an API, model server, or container to lightning.ai, or manage an existing deployment.
npx skill4agent add lightning-ai/skills lightning-deployments--image--model--studio# Use the Lightning AI CLI from the current env; install or upgrade it there if it's missing or older than 2026.9.18
v=$(lightning --version 2>/dev/null | sed -n 's/^Lightning CLI version //p')
[ -n "$v" ] && [ "$(printf '%s\n' 2026.9.18 "$v" | sort -V | head -1)" = 2026.9.18 ] \
|| uv pip install -U lightning-sdk || python3 -m pip install -U lightning-sdk
lightning --version # must print "Lightning CLI version …"; if not, see the table below
lightning login # browser flow; or headless:
export LIGHTNING_API_KEY=... LIGHTNING_USER_ID=... # USER_ID optional: with it Basic auth, without it the key is a Bearer tokenlightning …| Symptom | Fix |
|---|---|
Both installs fail: no active env, or pip refuses with | Install it on its own instead: |
| |
| The CLI is older than this skill expects: |
| The upgrade fails on a version conflict with the project's own pins | Don't fight the pins: install it outside the project with |
| Installing is blocked (read-only env or home, agent sandbox) | Skip it and run each command as |
Every call fails on SSL/certificates, even | A |
lightning_sdkpythonuvxuv run --with lightning-sdk python script.pylightning-sdkuv addpoetry add--teamspace owner/teamspaceteamspace="owner/teamspace"org=user=LIGHTNING_ORGLIGHTNING_TEAMSPACElightning config get teamspacelightning api /v1/memberships | jq -r '.memberships[] | [.ownerType, .name, .projectId] | @tsv'lightning config set teamspace <owner>/<teamspace>/v1/memberships--teamspace/v1/orgsjqorganization.memberships[0]ownerType: organizationownerType: userprojectIdnameuserownerId/v1/orgsM=$(lightning api /v1/memberships)
ROW=$(echo "$M" | jq -c '[.memberships[] | select(.ownerType=="organization")][0] // .memberships[0]')
TS=$(echo "$ROW" | jq -r .name) # teamspace
OWNER=$(lightning api "/v1/orgs/$(echo "$ROW" | jq -r .ownerId)" | jq -r .name) # owner (org) slug
lightning config set teamspace "$OWNER/$TS" # every command now defaults here; or pass --teamspace "$OWNER/$TS"createlistinspectupdatedeletelogslogs downloadreload-weightsenvsecretlistsetdeletestopupdate --min-replicas 0 --max-replicas 0# container deployment (a --port is required for non-model deployments)
lightning deployment create my-api --teamspace owner/teamspace \
--image nginx:latest --machine CPU --port 80 --replicas 1 --api-key-auth
# HuggingFace model via vLLM (GPU machine required; port defaults to 8000)
lightning deployment create llama --teamspace owner/teamspace \
--model meta-llama/Llama-3.1-8B-Instruct --machine L40S \
[--hf-token-secret <secret-name>] [--tensor-parallel-size 2] [--max-model-len 8192] \
[--quantization fp8] [--dtype bfloat16] [--dry-run] [--force]
# cloud account — if you pass none, the SDK picks one (config `cloud-account`, then
# LIGHTNING_CLUSTER_ID, then the teamspace's default binding) and prints which on stderr.
# Other deployments in the same teamspace may sit on a different account, which
# `deployment list` shows in its last column; match it with --cloud when relevant.
lightning deployment create ... --cloud gcp-lightning-public-prod
# autoscaling / env / secrets
lightning deployment create ... \
--min-replicas 0 --max-replicas 4 --autoscale-metric GPU --autoscale-threshold 90 \
-e KEY=VALUE --secret MY_LIGHTNING_SECRET --interruptible # CHECK THE SPOT PRICE FIRST — see Gotchas
# endpoint auth — mutually exclusive; OMITTING ALL THREE MAKES THE ENDPOINT PUBLIC
# Run `lightning auth whoami` first: --api-key-auth only accepts *user* keys.
--api-key-auth # require a Lightning USER API key (Bearer) — see Gotchas
--basic-auth USER:PASS
--token-auth TOKEN # any bearer string you choose; use this from a scoped key
# operate
lightning deployment list --teamspace owner/teamspace [--all] [--sort-by state]
lightning deployment inspect my-api --teamspace owner/teamspace # full JSON incl. endpoint URLs
lightning deployment logs my-api --teamspace owner/teamspace [-f] [--tail 100] [--timestamps]
lightning deployment logs my-api --teamspace owner/teamspace --query timeout --severity error # filter server-side
lightning deployment logs my-api --teamspace owner/teamspace --since 30m --until 5m # window (replicas merged + labelled)
lightning deployment update my-api --teamspace owner/teamspace --max-replicas 8
lightning deployment update my-api --teamspace owner/teamspace --min-replicas 0 --max-replicas 0 # "stop"
lightning deployment update my-api --teamspace owner/teamspace --image myimg:v2 [--max-surge 1] [--max-unavailable 0] # new release, rolling update
lightning deployment reload-weights llama --teamspace owner/teamspace # hot-reload BYOM weights
lightning deployment delete my-api --teamspace owner/teamspace --yesfrom lightning_sdk import Deployment, Machine
from lightning_sdk.api.deployment_api import (
ApiKeyAuth, BasicAuth, TokenAuth, AutoScaleConfig, Env, Secret,
RollingUpdateReleaseStrategy, HttpHealthCheck,
)
dep = Deployment("my-api", teamspace="my-org/my-teamspace") # owner/teamspace, same as the CLI; org=/user= are deprecated
dep.start(
image="nginx:latest",
machine=Machine.CPU,
ports=[80], # REQUIRED for non-model deployments; a LIST, not an int
autoscale=AutoScaleConfig(min_replicas=0, max_replicas=4, metric="CPU", threshold=90),
env=[Env("MODE", "prod"), Secret("HF_TOKEN")], # or a plain dict for env vars
auth=ApiKeyAuth(), # None => PUBLIC endpoint
health_check=HttpHealthCheck(path="/health", port=80),
spot=False, # True = interruptible replicas
)
print(dep.urls) # endpoint URL(s); no .status property — use replica counts
print(dep.running_replicas, dep.pending_replicas, dep.failing_replicas)
r = dep.get(path="/health") # convenience HTTP; auto-auths only for ApiKeyAuth
# changing image/command/env/entrypoint/spot/... creates a NEW RELEASE and needs a release strategy
dep.update(image="nginx:1.27", release_strategy=RollingUpdateReleaseStrategy(max_surge=1, max_unavailable=0))
dep.update(min_replicas=1, max_replicas=8) # scaling: no new release, no strategy needed
dep.stop() # scales to 0; blocks until replicas reach 0dep.start(model="meta-llama/...", machine=Machine.L40S, ports=[8000], hf_token_secret="...")imagestudioportsV1JobSpec.image_secret_refSECRET_TYPE_DOCKER_REGISTRYDeployment.start()500Exception: The jobs_service_create_deployment_with_http_info request failed to reach the server, response: 500.from lightning_sdk.lightning_cloud.openapi.api import jobs_service_api
_create = jobs_service_api.JobsServiceApi.jobs_service_create_deployment_with_http_info
def _with_image_secret(self, body, project_id, **kwargs):
if getattr(body, "spec", None) is not None:
body.spec.image_secret_ref = "MY_REGISTRY_SECRET"
return _create(self, body, project_id, **kwargs)
jobs_service_api.JobsServiceApi.jobs_service_create_deployment_with_http_info = _with_image_secretPROJECT_ID=$(lightning api /v1/memberships | jq -r '.memberships[] | select(.name=="<teamspace>") | .projectId')
lightning api "/v1/projects/${PROJECT_ID}/secrets" | jq -r '.secrets[] | "\(.name) \(.type)"'nginx:latestdep.delete()dep.get()dep.post()DELETElightning deployment delete NAME --yeslightning auth whoami # `user` → --api-key-auth is callable by you; `scoped-api-key` → use --token-auth
lightning deployment create hello-api --teamspace my-org/my-teamspace \
--image nginx:latest --machine CPU --port 80 --min-replicas 0 --max-replicas 1 --api-key-auth
lightning deployment inspect hello-api --teamspace my-org/my-teamspace # JSON: status, endpoint URL
URL=<endpoint URL from the inspect output above>
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $LIGHTNING_API_KEY" "$URL/" # verify the ENDPOINT, not the Studiofrom lightning_sdk import Deployment
dep = Deployment("hello-api", teamspace="my-org/my-teamspace")
print(dep.urls) # e.g. ['https://80-dep-<id>-d.cloudspaces.litng.ai'] — available even while scaled to zero
print(dep.get(path="/").status_code) # sends the caller's Lightning API key for ApiKeyAuthlightning deployment delete hello-api --teamspace my-org/my-teamspace --yeslightning deployment create qwen-served --teamspace my-org/my-teamspace \
--model Qwen/Qwen2.5-7B-Instruct --machine L40S --min-replicas 0 --max-replicas 1 --api-key-auth --dry-run
# review the model spec it prints, then re-run without --dry-run; if the real create reports
# unacknowledged warnings, re-run with --ack <code> (repeatable) or --force
lightning deployment logs qwen-served --teamspace my-org/my-teamspace -f # watch it come upbase_urldep.urls[0]lightning deployment update hello-api --teamspace my-org/my-teamspace --min-replicas 1 --max-replicas 4 # keep warm
lightning deployment update hello-api --teamspace my-org/my-teamspace --min-replicas 0 --max-replicas 0 # stop (scale to zero)
lightning deployment update hello-api --teamspace my-org/my-teamspace --image nginx:1.27 # new release, rolling by defaultPROJECT_ID=$(lightning api /v1/memberships | jq -r '.memberships[] | select(.name=="<teamspace>") | .projectId' | head -1)
lightning api "/v1/projects/${PROJECT_ID}/deployments" -q '.deployments[].name' # plain GET; -f/-F without -X would send a POST
lightning api "/v1/projects/${PROJECT_ID}/deployments/${DEPLOYMENT_ID}"
lightning api "/v1/projects/${PROJECT_ID}/deployments/${DEPLOYMENT_ID}" -X DELETE--min-replicas >= 1--max-replicaslightning-cost-estimationlightning auth whoami--api-key-authuserApiKey: trueAuth type: scoped-api-key--token-auth <token>--api-key-authdeployment inspect--interruptiblelightning-cost-estimationmin(cost, spotPrice)min_replicas=0min_replicas >= 1AutoScaleConfig(idle_threshold_seconds=...)deployment createdeployment updateHttpHealthCheck(path=..., port=...)--health-check-path--readiness-probeRuntimeErrorDeployment.start()ValueError--modelportsTypeError: 'int' object is not iterableportsAutoScaleConfigmetricstart()ValueError: The autoscaling metric is required. Currently supported metrics are ['GPU', 'CPU', 'RPM']metric=start()image_secret_ref500Secret("NAME")namedeployment inspect{"from_secret": "NAME", "name": "", "value": ""}envdeployment logs--yesDeployment deleteddeployment listlist --allPENDINGdeletedAt: Nonelistdeletedeployment logs-f--tail 25--follow-fdeployment inspecttotal_cost0.0total_cost--modelDeployment has unacknowledged warnings: ... Re-run with --ack <code> (repeatable) or --force.--dry-runserved_model_nameweight_source--model403deployment create ... --model <hf-id>Exception: The jobs_service_create_deployment_with_http_info request failed to reach the server, response: 403.LIGHTNING_DEBUG=1--imageteamspace="owner/teamspace"org=user=DeprecationWarningValueError