Skip to main content

Custom Docker Template

Use a template when you want pods to start from a specific Docker image with predefined ports, environment variables, volume paths, and a startup command.

This example creates a private template from a known PyTorch image, starts a Python HTTP server from the template's startup command, prints the mapped public URL, checks an environment variable, and stops the pod.

#!/usr/bin/env python3
"""Create a custom template, launch a pod from it, and inspect runtime settings."""

from datetime import datetime, timezone

from lium.sdk import Lium

lium = Lium()
ready_pod = None
created_pod_id = None

template_name = "sdk-custom-template-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")

try:
template = lium.create_template(
name=template_name,
docker_image="daturaai/pytorch",
docker_image_tag="2.4.0-py3.11-cuda12.4.1-devel-ubuntu22.04",
ports=[22, 8000],
start_command="python -m http.server 8000 --bind 0.0.0.0 --directory /workspace",
environment={
"LIUM_EXAMPLE_MODE": "custom-template",
},
volumes=["/workspace"],
description="Private SDK example template",
is_private=True,
)

template = lium.wait_template_ready(template.id, timeout=600)
if template is None:
raise RuntimeError("Template did not verify before the timeout")

executors = lium.ls(
gpu_type="A100",
gpu_count=1,
min_cuda_version=12.4,
)
if not executors:
raise RuntimeError("No matching executor is currently available")

executor = min(executors, key=lambda item: item.price_per_hour)

pod = lium.up(
executor_id=executor.id,
template_id=template.id,
name="sdk-custom-template-demo",
ports=2,
)
created_pod_id = pod["id"]

ready_pod = lium.wait_ready(pod, timeout=600)
if ready_pod is None:
raise RuntimeError("Pod did not become ready before the timeout")

details = lium.pod(ready_pod.id)
ports_mapping = details["ports_mapping"]
app_port = ports_mapping.get("8000")
if app_port is None:
raise RuntimeError(f"Port 8000 was not exposed: {ports_mapping}")

result = lium.exec(ready_pod, command="printenv LIUM_EXAMPLE_MODE")
if not result["success"]:
raise RuntimeError(result["stderr"] or result["stdout"])
print(result["stdout"].strip())

print(f"Open http://{ready_pod.host}:{app_port}/")

finally:
pod_to_stop = ready_pod
if pod_to_stop is None and created_pod_id:
pod_to_stop = next((p for p in lium.ps() if p.id == created_pod_id), None)

if pod_to_stop is not None:
lium.down(pod_to_stop)
print(f"Stopped pod {pod_to_stop.name} ({pod_to_stop.huid})")

What Each Field Does​

  • docker_image and docker_image_tag choose the container image for the template.
  • ports declares internal container ports that Lium should expose. Include 22 for SSH access, plus application ports such as 8000 for an API server.
  • start_command is the command run when the container starts. This example starts Python's built-in HTTP server on 0.0.0.0:8000 so the service can be reached through Lium's public port mapping.
  • environment sets container environment variables.
  • volumes declares mount paths inside the container.
  • is_private=True keeps the template scoped to your account.

When you create a pod, request enough public ports for the SSH port and the application port. Fetch the pod with lium.pod(...) and read ports_mapping to see the assigned host ports.