# Startup and ready commands
<subtitle>Define running processes for the sandbox</subtitle>

## Start command

The start command specifies a process to run at the end of the template build - not when the sandbox is created. During a build, UCloud Sandbox executes a startup command, waits for [readycommand](#readycommand) to confirm that the process has started, and then takes a [snapshot](/docs/agent-sandbox/template/how-it-works.md) of the entire sandbox, including running processes.

When you later create a sandbox from this template, the snapshot process is already running - there is no startup wait time. This is how you make a server, seeded database, or any long-running process immediately available when you build a sandbox using the SDK.

> **Launch command does not run on sandbox creation**
>
> The start command is run once during the template build and captured into a snapshot. It will not be re-executed each time the sandbox is created. If you need to run the command every time the sandbox is created, use `sandbox.commands.run()` after creating the sandbox.
>
> This also means that the [environment variables passed to `Sandbox.create()`](/docs/agent-sandbox/sandbox/environment-variables.md#1 - Global Environment Variables) are not available to start the command process - it is already running during the build. If your startup command requires environment variables, use `set_envs()` to set them in the template definition.

You can view the complete build process [here](/docs/agent-sandbox/template/how-it-works.md).

## Ready command

The ready command determines when the sandbox is ready before creating a [snapshot](/docs/agent-sandbox/template/how-it-works.md). It executes in an infinite loop until a successful exit code 0 is returned. This lets you control how long the build waits for [start_command](#start_command) or any other system state to be ready.

## `set_start_cmd`

Use `set_start_cmd` when you want to run a process during template building and wait for it to be ready. This method accepts **two parameters**: the startup command and the ready command.

```python
from ucloud_sandbox import Template, wait_for_port, wait_for_url, wait_for_timeout

# Start the Python HTTP server and wait for it to listen on port 8000
template = (
    Template()
    .from_ubuntu_image("22.04")
    .apt_install(["curl", "python3"])
    .set_start_cmd("python3 -m http.server 8000", wait_for_port(8000))
)
```

You can also pass a custom shell command as a ready command instead of using a helper function:

```python
# Start command with custom ready command
template.set_start_cmd("npm start", "curl -s http://localhost:3000/health")
```

More examples:

```python
from ucloud_sandbox import Template, wait_for_url, wait_for_port

# Next.js application - wait for development server URL
template.set_start_cmd("npx next --turbo", wait_for_url("http://localhost:3000"))

# Python HTTP server - wait for port 8000
template.set_start_cmd("python -m http.server 8000", wait_for_port(8000))

# VNC Desktop - Waiting for VNC port
template.set_start_cmd("/start_command.sh", wait_for_port(6080))
```

## `set_ready_cmd`

Use `set_ready_cmd` when you don't need a launch command but still want to control when sandbox snapshots are taken. This method accepts only one parameter: the ready command.

This is useful when your template's build step (e.g., `run_cmd`) already starts a background process, or you just need extra time for the system to stabilize before taking a snapshot.

```python
from ucloud_sandbox import Template, wait_for_timeout, wait_for_port, wait_for_file

# Wait for nginx to start listening before taking a snapshot
template = (
    Template()
    .from_ubuntu_image("22.04")
    .run_cmd("apt-get install -y nginx && service nginx start")
    .set_ready_cmd(wait_for_port(80))
)
```

More examples:

```python
# Wait for the background process to create the file
template.set_ready_cmd(wait_for_file("/tmp/ready"))

# Wait for a fixed period of time for the system to stabilize
template.set_ready_cmd(wait_for_timeout(10_000))

# Custom readiness check
template.set_ready_cmd("curl -s http://localhost:8080/health")
```

## Ready command helper function

The SDK provides helper functions for common ready command modes. These can be used with `set_start_cmd` and `set_ready_cmd`.

```python
from ucloud_sandbox import wait_for_port, wait_for_url, wait_for_process, wait_for_file, wait_for_timeout

# Wait for port to be available
wait_for_port(3000)

# Wait for the URL to return a specific status code (default is 200)
wait_for_url("http://localhost:3000/health")
wait_for_url("http://localhost:3000/health", 200)

# Wait for the process to run
wait_for_process("node")

# Wait for the file to exist
wait_for_file("/tmp/ready")

# Wait for the specified time
wait_for_timeout(10_000) # 10 seconds
```
