Deploying Jobs
This guide covers how to get a job running on a cloud GPU and the common patterns around it: environment, CI, chaining, exec, and debugging.
Deployment Workflows
Two ways to get your code onto a remote VM.
Use the decorator for fast Python iteration on code you'll change often — no image rebuild between runs. Use a prebuilt image + submit for non-Python workloads or hermetic CI-built images.
Function Decorator (Python SDK)
What it is: The @anycloud.function() decorator uses git-based code sync — your repo is cloned at the current commit on the remote VM. Think of it as COPY . /app in your Dockerfile, but always up to date. Your image holds dependencies (PyTorch, CUDA, etc.); your code comes from git. No rebuild between runs, and function arguments are passed directly — no argparse wiring.
When to use: Python workloads where you iterate on code frequently and want to skip the rebuild loop entirely.
Requirements: Python SDK, code committed and pushed to GitHub, git installed in the image.
Example:
@anycloud.function(image="ghcr.io/acme/base:latest", gpu="h100:8")
def train(learning_rate: float, epochs: int = 100):
# Your code is synced here via git — not baked into the image
...
job = train.submit(0.001, epochs=50)
See Python SDK — Function Decorator for the full API.
Prebuilt Image + Submit (CLI, Python SDK)
What it is: The standard Docker workflow — your code is baked into the image via COPY in a Dockerfile, pushed to a registry, then submitted. The running container is a hermetic artifact pinned to a specific image digest, so the same build is reproducible across runs.
When to use: Non-Python workloads or CI/CD pipelines where one image is deployed many times.
Requirements: A pullable image reference. Public registries work without auth; for private images, use GHCR — anycloud login authenticates via GitHub OAuth and anycloud uses the token to pull on the VM.
Examples:
# CLI — submit an image you've already built and pushed to GHCR
anycloud submit ghcr.io/you/repo:latest --credentials my-aws --gpu-type h100
# Python
client.submit("ghcr.io/you/repo:latest", gpu="h100")
How They Relate
The decorator is built on top of submit. Under the hood, @anycloud.function() calls Client.submit() with your image plus a bootstrap script that clones your repo at the exact commit. Either way, you build and push the image yourself — locally or in GitHub Actions (recommended for repeatable builds) — and anycloud pulls it from the registry to run.
GPUs & Resource Limits
Pick GPUs by type (--gpu-type / gpu=) and let anycloud choose the instance, or pin an exact --vm-type. Pass standard Docker runtime flags for shared memory, memory, CPUs, and IPC.
# CLI
# 8 H100 GPUs; anycloud picks the instance.
# Expose all GPUs and give PyTorch DataLoader workers more shared memory.
anycloud submit ghcr.io/you/train:latest \
--credentials my-aws \
--gpu-type h100:8 \
--gpus all \
--shm-size 8g \
--disk-size 200
# Python
job = ac.submit(
"ghcr.io/you/train:latest",
gpu="h100:8", # 8× H100; anycloud picks the instance
docker_options={"shmSize": "8g"},
cloud_config=CloudConfig(credentials="my-aws", disk_size_gb=200),
)
Full lists: Docker runtime options and CloudConfig parameters.
Environment & CI
Environment Variables
# Single variable
anycloud submit my-image -e API_KEY=secret123
# Read from current shell
anycloud submit my-image -e API_KEY
# From .env file
anycloud submit my-image --env-file .env
# Combine (flags take precedence over file)
anycloud submit my-image --env-file .env -e API_KEY=override
CI Pipeline
Every CLI command is flag- and env-driven — there are no prompts to navigate. In CI, pass the GitHub token and credentials name via env vars and the rest as flags:
GITHUB_TOKEN=ghp_... ANYCLOUD_CREDENTIALS_NAME=my-aws \
anycloud submit ghcr.io/user/my-app:latest \
--gpu-type h100 \
--spot
| Env Var | Description |
|---|---|
GITHUB_TOKEN | GitHub token for auth |
ANYCLOUD_CREDENTIALS_NAME | Named credentials to use (alternative to --credentials) |
Chaining Jobs
Chain jobs by waiting for each step before submitting the next:
prep = ac.submit("prep:latest")
prep.wait()
train = ac.submit("train:latest", gpu="h100:8")
train.wait()
eval_job = ac.submit("eval:latest")
eval_job.wait()
For parallel fan-out / fan-in, see Python SDK — JobGroup. To pass data between jobs via buckets (including fan-in to a shared output bucket and cross-cloud storage), see Bucket Sync. For copy-pasteable versions of these patterns, see Examples.
Running Commands
Run commands in your job's execution environment:
job = ac.submit("train:latest", gpu="h100:8", persist=True)
job.wait()
print(job.exec("nvidia-smi")) # run a command in the job environment
print(job.exec("python --version"))
See Python SDK — Job Methods and CLI — anycloud exec.
Debugging a Job
Use status for lifecycle and error details. While the job execution
environment is still available, use exec for targeted inspection commands:
anycloud status <deployment-id> --verbose
anycloud exec <deployment-id> "pwd && ls -la"
For @anycloud.function() jobs, the logs label where a failure happened:
ERROR: git …(e.g.git is not installed in this container image.,git clone failed:) — the VM couldn't fetch your repo. Check that the image hasgitinstalled and that your commit is pushed.ERROR: anycloud could not set up your code:— the repo was fetched, but anycloud couldn't check out the commit, import your module, or find the function. Usually a path or module-name mismatch.ERROR: your function '<name>' raised an exception:— your function ran; the traceback below is from your own code.
For other failure modes — credential and quota errors, jobs stuck in queued, or GPU-vs-VM confusion — see Troubleshooting.