Skip to main content

lium up

Create a new pod.

lium up [NODE_ID] [OPTIONS]

Arguments​

  • NODE_ID — Node UUID, HUID, or index from the last lium ls. Optional: when you omit it, the filter flags below narrow the list and the best node is picked automatically, with no menu — the only prompt is the confirmation before renting, which --yes skips.

Options​

Selection & naming​

FlagEffect
--name, -n NAMECustom pod name (auto-generated if not specified)
--template_id, -t IDSpecify template ID directly (skips template prompt)
--gpu TYPEFilter nodes by GPU type (e.g. H200, A6000)
--count, -c NUMFilter by number of GPUs per pod
--country CODEFilter nodes by ISO country code (US, FR, …)
--min-cpus NOnly nodes that report at least N CPU threads (the CPUs column of lium ls) (since 0.0.40)
--ports, -p NUMOnly consider nodes with at least NUM available ports, and request NUM ports on the pod
--yes, -ySkip confirmation prompt
--no-sshCreate the pod and return to the shell; no SSH session is opened

By default a successful lium up ends by opening an interactive SSH session to the new pod (in --image mode it streams the container logs instead). Pass --no-ssh when you want the command to return — in a script, or when you plan to connect later with lium ssh.

Verification​

Since 0.0.34

The GPU-count check and both flags shipped in lium 0.0.34. Since 0.0.35 a rent without --count is checked against the node's free GPUs (0.0.34 compared it with the host's total, which failed a correct pod on a partly rented split node). Since 0.0.39 (lium#209) a lium up --gpu <type> rent on a backend that offers rent_by_spec (lium.io does) asks the server for one GPU unless you pass --count, and the check uses the count the server rented; the free-GPU rule stays for lium up <node>. 0.0.33 reports success as soon as the pod is RUNNING with an SSH command, so on that version a silent downgrade (fewer GPUs billed than requested) or phantom GPUs (billed for more than the container exposes) is only visible from inside the pod.

Once the pod is ready — and after any --ttl/--until schedule is set — up compares the GPU count the API bills the pod for with the count you asked for: --count; without it, the node's free GPUs for lium up <node>, or (since 0.0.39) the count the server rented for lium up --gpu <type>, one GPU. When the /pods row carries no GPU count for the pod, that comparison is skipped and up reports success; pass --verify-gpus if you need the count proven — it then checks what nvidia-smi sees against the count you asked for. A mismatch prints GPU count mismatch: requested N, pod is billed for M (node <id>), leaves the pod running (remove it with 'lium rm <pod>') and exits 1 with the code gpu_count_mismatch. The two flags go further:

FlagEffect
--verify-gpusAlso count the GPUs nvidia-smi -L sees over SSH inside the pod and compare with the billed count; a mismatch exits 1 with both numbers (pod is billed for 8, nvidia-smi reports 4). The connection is retried for about 90 s while sshd comes up; when it never answers in that window, or the command itself fails (nvidia-smi missing, driver not loaded), the pod is kept and up exits 1 with gpu_verification_failed (since 0.0.34)
--strict-gpusRemove the pod automatically on a mismatch of either check, so a scripted lium up … && python train.py never pays for a pod that is not what was asked for; a pod that could not be checked over SSH is kept (since 0.0.34)

Auto-termination​

FlagEffect
--ttl DURATIONAuto-terminate this long after the rent (e.g. 6h, 45m, 2d)
--until WHENAuto-terminate at local time (today 23:00, tomorrow 01:00, 2026-05-08 15:30)

The schedule is set the moment the rent returns a pod id, before up waits for the pod to become ready (since 0.0.42; earlier versions set it only once the pod was RUNNING). So it holds when the wait runs out (--timeout, --ready-timeout) or the pod never starts: the exit message names the removal time (Auto-termination is scheduled for 2026-09-10 08:40 UTC (in 2.0h): the pod is removed then even if it never becomes ready), and lium schedules lists it while the pod is still PENDING. If the schedule call itself fails right after the rent, up says so, waits, and tries once more when the pod is ready; the pod is kept either way. When that wait then runs out too, the pod has no end time — the exit message says Auto-termination (--ttl/--until) was NOT scheduled and points at lium rm <pod> --in <duration> to set one.

Use lium schedules to view and cancel an existing schedule.

Waiting​

Since 0.0.35

Everything in this section shipped in lium 0.0.35 (lium#214). On 0.0.33 and 0.0.34 lium up polls every 10 s with no time limit and prints nothing until the pod is ready.

FlagEffect
--timeout SECONDSTime budget for the whole command — finding the node, renting it and waiting for the pod (default 900). When it runs out before the rent, up exits 1 with no pod created (a --volume new: volume is kept); when it runs out while the pod is still starting, up exits 1 and names the pod, which keeps running and billing; remove it with lium rm if you do not want it (since 0.0.35)
--ready-timeout SECONDSBound only the wait for the pod to become ready: exit 1 with the pod named, pod left running. Default: whatever --timeout leaves (so up to 900 s). A pod that reaches FAILED/STOPPED or disappears fails immediately, exit 3 (pod_start_failed), with its last recorded status, whatever the timeout (since 0.0.35)

While it waits, up prints a line when the pod's status or phase changes, and at least every 30 s — waiting for <pod>… <STATUS> (<n> s), followed by the backend's estimate when it sends one: waiting for eager-owl-7c… PENDING (12 s) · est. ready in ~18 s (phase: pulling image). The lines appear on a terminal and behind a pipe alike, so a scripted caller can see whether the pod is in PENDING, pulling its image or already RUNNING. A pod that reaches a terminal state (TERMINAL_POD_STATUSES: FAILED, STOPPED, ERROR, TERMINATED, DELETED, REMOVED, CANCELLED, CREATION_FAILED, BROKEN, REBOOT_FAILED, DELETING) or disappears fails immediately — exit 3, pod_start_failed — with the cause the backend recorded (for example Container creation failed … (failure_step: ssh_connect)). --ready-timeout caps only the wait for readiness; --timeout caps everything.

How often it looks (since 0.0.35): up checks the pod list every 2 s for the first 90 s of the wait and every 10 s after that — 0.0.34 checked every 10 s throughout — so a pod the backend marks RUNNING at ~22 s is reported within 2 s. A pod that does not appear in the list at all is reported as missing 20 s after the first check, whatever the cadence, and also when the --timeout budget ends at that same moment.

Container​

FlagEffect
--image IMAGEDocker image to run (e.g. pytorch/pytorch:2.0, nvidia/cuda:12.0, or name@sha256:<digest> to pin one exact build)
--dockerfile PATHBuild the pod image from a local Dockerfile (custom build). Mutually exclusive with --image and --template_id.
--internal-ports LISTInternal ports to expose (comma-separated, e.g. 22,8000,8080)
-e, --env KEY=VALEnvironment variable; can be repeated
--entrypoint CMDOverride container entrypoint
--cmd CMDOverride container command
--jupyterInstall Jupyter Notebook (auto-selects an available port)
--ssh-name NAMEName for a freshly registered SSH key (default: cli-<user>@<hostname>)

Custom Dockerfile builds (--dockerfile): the image is built on the node from your Dockerfile — no build context is uploaded, so the Dockerfile must be self-contained: the Dockerfile is the only file the build sees. COPY or ADD of files next to it (COPY app.py /app/, ADD ./data /data) would fail there with not found (COPY --from=<stage> and heredoc COPY <<EOF need no local files and work). A check in lium up that refuses such a Dockerfile before renting and lists the lines is not released yet; lium 0.13.4 and earlier rent the pod and the build then fails. Fetch those files in a RUN step (git clone, pip install), or build and push the image yourself and run it with --image. The build runs in an isolated container with public internet access (cloud metadata and private network ranges are blocked), and ADD <url> / ADD ${var} directives are rejected. Keep the file under 64 KiB. The pod is SSH-accessible once the build finishes, just like a template-based pod. The --env, --entrypoint, --cmd, and --internal-ports flags don't apply here — define those in the Dockerfile itself.

If the build fails, the cause that lium up prints (and the executor-rent.failed entry in GET /pods/{id}/events) ends with Build output (last lines): followed by the last 25 non-empty lines the build printed, cut to 2000 characters. A line that carries a credential — a token=, secret=, password= or key= assignment such as ARG HF_TOKEN=…, an ENV or ARG with such a name and a value (ENV API_KEY value), or a URL with a user (https://TOKEN@…, https://user:password@…) — is replaced by [line redacted: it contains a credential]. That redaction is by pattern, not a guarantee: a token printed on its own line stays visible to everyone who can read the pod's events, so keep secrets out of the Dockerfile and out of anything it prints. An older validator reports only the failing step, for example (failure_step: docker_build).

Volumes​

FlagEffect
--volume, -v SPECVolume spec — see below
--volume-encryption / --no-volume-encryptionEncrypt the local volume where the node supports it. Enabled by default.

Volume spec forms:

  • id:<HUID> — attach an existing volume by HUID
  • new:name=<NAME>[,desc=<DESC>] — create and attach a new volume

Restore from a backup​

FlagEffect
--restore-backup BACKUP_IDCompleted backup to restore after the pod starts
--restore-to PATHNew or empty directory below the pod's local volume mount

The two restore flags must be used together. The pod becomes running and accessible before restoration finishes. Do not modify the restore directory until lium bk restore-logs reports completion.

Examples​

# Basic
lium up # Auto-picks the best node, asks to confirm
lium up cosmic-hawk-f2 # Specific node by HUID
lium up 1 # Node #1 from last ls
lium up --name dev-pod # Custom name

# Filtering nodes
lium up --gpu H200
lium up --gpu A6000 -c 2
lium up --gpu H200 --country FR
lium up --ports 5

# Verify the GPU count inside the pod too (exit 1 on mismatch; --strict-gpus also removes the pod) — since 0.0.34
lium up --gpu H200 --count 8 --verify-gpus --yes
lium up --gpu H200 --count 8 --verify-gpus --strict-gpus --yes

# Auto-terminate
lium up --gpu H200 --ttl 6h # Stop after 6h
lium up --gpu H200 --until "tomorrow 09:00" # Stop tomorrow morning

# Container customization
lium up 1 --image pytorch/pytorch:2.0
lium up 1 --image my-image -e API_KEY=xyz -e DEBUG=1
lium up 1 --internal-ports 22,8000,8080
lium up 1 --jupyter # Spin up with Jupyter

# Custom Dockerfile build (image built remotely from your Dockerfile)
lium up --gpu A6000 --dockerfile ./Dockerfile
lium up 1 --dockerfile ./Dockerfile --name my-build

# Volumes
lium up 1 --volume id:brave-fox-3a
lium up 1 --volume new:name=my-data,desc="Training data"

# Create a pod and restore a backup after it starts
lium up 1 --restore-backup 8fbb30f6 --restore-to /root/restored

# Bound the whole command (exit 1 and name the pod if it is still starting after 5 min) — since 0.0.35
lium up --gpu RTX5090 --yes --no-ssh --timeout 300

# Direct template + skip prompt
lium up 1 --template_id abc123
lium up --gpu H200 --yes

See also​