# Run and deploy tasks

> **📝 Note**
>
> An LLM-optimized bundle of this entire section is available at [`section.md`](https://www.union.ai/docs/v2/union/user-guide/task-deployment/section.md).
> This single file contains all pages in this section, optimized for AI coding agent context.

You have seen how to configure and build the tasks that compose your project.
Now you need to decide how to execute them on your Flyte backend.

Flyte offers two distinct approaches for getting your tasks onto the backend:

**Use `flyte run` when you're iterating and experimenting:**
- Quickly test changes during development
- Try different parameters or code modifications
- Debug issues without creating permanent artifacts
- Prototype new ideas rapidly

**Use `flyte deploy` when your project is ready to be formalized:**
- Freeze a stable version of your tasks for repeated use
- Share tasks with team members or across environments
- Move from experimentation to a more structured workflow
- Create a permanent reference point (not necessarily production-ready)

This section explains both approaches and when to use each one.

## Ephemeral deployment and immediate execution

The `flyte run` CLI command and the `flyte.run()` SDK function are used to **ephemerally deploy** and **immediately execute** a task on the backend in a single step.
The task can be re-run and its execution and outputs can be observed in the **Runs list** UI, but it is not permanently added to the **Tasks list** on the backend.

Let's say you have the following file called `greeting.py`:

```python
# greeting.py

import flyte

env = flyte.TaskEnvironment(name="greeting_env")

@env.task
async def greet(message: str) -> str:
    return f"{message}!"
```

### Programmatic

You can run the task programmatically using the `flyte.run()` function:

```python
# greeting.py

import flyte

env = flyte.TaskEnvironment(name="greeting_env")

@env.task
async def greet(message: str) -> str:
    return f"{message}!"

if __name__ == "__main__":
    flyte.init_from_config()
    result = flyte.run(greet, message="Good morning!")
    print(f"Result: {result}")
```

Here we add a `__main__` block to the `greeting.py` file that initializes the Flyte SDK from the configuration file and then calls `flyte.run()` with the `greet` task and its argument.
Now you can run the `greet` task on the backend just by executing the `greeting.py` file locally as a script:

```bash
python greeting.py
```

### CLI

The general form of the command for running a task from a local file is:

```bash
flyte run <file_path> <task_name> <args>
```

So, to run the `greet` task defined in the `greeting.py` file, you would run:

```bash
flyte run greeting.py greet --message "Good morning!"
```

This command:
1. **Temporarily deploys** the task environment named `greeting_env` (held by the variable `env`) that contains the `greet` task.
2. **Executes** the `greet` function with argument `message` set to `"Good morning!"`. Note that `message` is the actual parameter name defined in the function signature.
3. **Returns** the execution results and displays them in the terminal.

For more details on how `flyte run` and `flyte.run()` work under the hood, see [How Run Works](https://www.union.ai/docs/v2/union/user-guide/task-deployment/how-task-run-works/page.md).

## Persistent deployment

The `flyte deploy` CLI command and the `flyte.deploy()` SDK function are used to **persistently deploy** a task environment (and all its contained tasks) to the backend.
The tasks within the deployed environment will appear in the **Tasks list** UI on the backend and can then be executed multiple times without needing to redeploy them.

### Programmatic

You can deploy programmatically using the `flyte.deploy()` function:

```python
# greeting.py

import flyte

env = flyte.TaskEnvironment(name="greeting_env")

@env.task
async def greet(message: str) -> str:
    return f"{message}!"

if __name__ == "__main__":
    flyte.init_from_config()
    deployments = flyte.deploy(env)
    print(deployments[0].summary_repr())
```

Now you can deploy the `greeting_env` task environment (and therefore the `greet()` task) just by executing the `greeting.py` file locally as a script.

```bash
python greeting.py
```

### CLI

The general form of the command for deploying a task environment from a local file is:

```bash
flyte deploy <file_path> <task_environment_variable>
```

So, using the same `greeting.py` file as before, you can deploy the `greeting_env` task environment like this:

```bash
flyte deploy greeting.py env
```

This command deploys the task environment *assigned to the variable `env`* in the `greeting.py` file, which is the `TaskEnvironment` named `greeting_env`.

Notice that you must specify the *variable* to which the `TaskEnvironment` is assigned (`env` in this case), not the name of the environment itself (`greeting_env`).

Deploying a task environment deploys all tasks defined within it. Here, that means all functions decorated with `@env.task`.
In this case there is just one: `greet()`.

For more details on how `flyte deploy` and `flyte.deploy()` work under the hood, see [How Deployment Works](https://www.union.ai/docs/v2/union/user-guide/task-deployment/how-task-deployment-works/page.md).

## Running already deployed tasks

If you have already deployed your task environment, you can run its tasks without redeploying by using the `flyte run` CLI command or the `flyte.run()` SDK function in a slightly different way. Alternatively, you can always initiate execution of a deployed task from the UI.

### Programmatic

You can run already-deployed tasks programmatically using the `flyte.run()` function.
For example, to run the previously deployed `greet` task from the `greeting_env` environment:

```python
# greeting.py

import flyte

env = flyte.TaskEnvironment(name="greeting_env")

@env.task
async def greet(message: str) -> str:
    return f"{message}!"

if __name__ == "__main__":
    flyte.init_from_config()
    flyte.deploy(env)
    task = flyte.remote.Task.get("greeting_env.greet", auto_version="latest")
    result = flyte.run(task, message="Good morning!")
    print(f"Result: {result}")
```

When you execute this script locally, it will:

- Deploy the `greeting_env` task environment as before.
- Retrieve the already-deployed `greet` task using `flyte.remote.Task.get()`, specifying its full task reference as a string: `"greeting_env.greet"`.
- Call `flyte.run()` with the retrieved task and its argument.

For more details on how running already-deployed tasks works, see [How task Run works > SDK: Running deployed tasks](https://www.union.ai/docs/v2/union/user-guide/task-deployment/how-task-run-works/page.md#running-deployed-tasks).

### CLI

To run a permanently deployed task using the `flyte run` CLI command, use the special `deployed-task` keyword followed by the task reference in the format `{environment_name}.{task_name}`. For example, to run the previously deployed `greet` task from the `greeting_env` environment:

```bash
flyte run deployed-task greeting_env.greet --message "World"
```

Notice that now that the task environment is deployed, you use its name (`greeting_env`), not by the variable name to which it was assigned in source code (`env`).
The task environment name plus the task name (`greet`) are combined with a dot (`.`) to form the full task reference: `greeting_env.greet`.
The special `deployed-task` keyword tells the CLI that you are referring to a task that has already been deployed. In effect, it replaces the file path argument used for ephemeral runs.

When executed, this command will run the already-deployed `greet` task with argument `message` set to `"World"`. You will see the result printed in the terminal. You can also, of course, observe the execution in the **Runs list** UI.

To execute a deployed task in a different project or domain than your configured defaults, use `--run-project` and `--run-domain`:

```bash
flyte run --run-project prod-project --run-domain production deployed-task greeting_env.greet --message "World"
```

For all `flyte run` options, see [Run command options](https://www.union.ai/docs/v2/union/user-guide/task-deployment/run-command-options/page.md).

## Configuring runs with `flyte.with_runcontext()`

Both `flyte run` and `flyte.run()` accept a range of invocation-time parameters that control where the run executes, where outputs are stored, caching behavior, and more.
Programmatically, these are set with `flyte.with_runcontext()` before calling `.run()`.
Inside a running task, `flyte.ctx()` provides read access to the same context.

For the full parameter reference, see [Run context](https://www.union.ai/docs/v2/union/user-guide/task-deployment/run-context/page.md).

<!--
TODO: Add link to Flyte remote documentation when available
For details on Flyte remote functionality, see the [Flyte remote]().
-->

## Subpages

- [How task run works](https://www.union.ai/docs/v2/union/user-guide/task-deployment/how-task-run-works/page.md)
  - Ephemeral deployment + run: The development shortcut
  - Programmatic
  - CLI
  - Running deployed tasks
  - Programmatic
  - CLI
  - Local execution
  - Programmatic
  - CLI
  - Running tasks through the Union UI
  - Accessing task execution in the Union UI
  - Execution flow and architecture
  - Fast registration architecture
  - Ephemeral preparation logic
  - Execution modes comparison
- [Interact with runs and actions](https://www.union.ai/docs/v2/union/user-guide/task-deployment/interacting-with-runs/page.md)
  - Understanding runs and actions
  - Key concepts
  - Working with runs
  - Retrieving a run
  - Programmatic
  - CLI
  - Watching run progress
  - Getting detailed run information
  - Working with actions
  - Retrieving an action
  - Programmatic
  - CLI
  - Nested actions
  - Getting detailed action information
  - Retrieving inputs and outputs
  - Programmatic
  - CLI
  - Handling failures
  - Understanding data storage
  - Accessing large data from cloud storage
  - S3 storage access
  - GCS storage access
  - Azure Blob Storage access
  - Complete example
  - API reference
  - Key classes
  - CLI commands
  - Storage configuration
- [Work with local data](https://www.union.ai/docs/v2/union/user-guide/task-deployment/work-with-local-data/page.md)
  - Local execution
  - Uploading local data to remote runs
  - Uploading DataFrames
  - Uploading files
  - Uploading directories
  - Passing outputs between runs
  - Performance considerations
  - Summary
- [Run command options](https://www.union.ai/docs/v2/union/user-guide/task-deployment/run-command-options/page.md)
  - `--project`, `--domain`
  - `--run-project`, `--run-domain`
  - `--local`
  - When to use local execution
  - `--copy-style`
  - Copy style options
  - `--root-dir`
  - `--raw-data-path`
  - Use cases
  - `--service-account`
  - Use cases
  - `--name`
  - Benefits of custom names
  - `--follow`
  - Behavior
  - `--image`
  - Image mapping formats
  - `--no-sync-local-sys-paths`
  - Task argument passing
  - SDK options
- [How task deployment works](https://www.union.ai/docs/v2/union/user-guide/task-deployment/how-task-deployment-works/page.md)
  - 1. Module loading and task environment discovery
  - Single file (default)
  - `--all` option
  - `--recursive` option
  - 2. Task analysis and serialization
  - 3. Task environment dependency resolution
  - 4. Code bundle creation and upload
  - `--copy_style loaded_modules` (default)
  - `--copy_style all`
  - `--copy_style none`
  - `--root-dir` option
  - 5. Image building
  - Local image building
  - Remote image building
  - Understanding option relationships
- [Deploy command options](https://www.union.ai/docs/v2/union/user-guide/task-deployment/deploy-command-options/page.md)
  - `--project`, `--domain`
  - `--version`
  - When versions are used
  - `--dry-run`
  - `--all` and `--recursive`
  - `--copy-style`
  - `--copy-style loaded_modules` (default)
  - `--copy-style all`
  - `--copy-style none`
  - `--root-dir`
  - Default behavior (without `--root-dir`)
  - Common use cases
  - How it works
  - Example with complex project structure
  - `--image`
  - Named image mappings
  - Default image mapping
  - How it works
  - `--ignore-load-errors`
  - `--no-sync-local-sys-paths`
  - Default behavior (path synchronization enabled)
  - When to disable path synchronization
  - Use cases for disabling
  - How it works
  - SDK deployment options
- [Packaging](https://www.union.ai/docs/v2/union/user-guide/task-deployment/packaging/page.md)
  - Quick comparison
  - Code bundling
  - How it works
  - Automatic code bundling
  - Manual code bundling
  - Controlling the root directory
  - Code bundling examples
  - When to use code bundling
  - Container-based deployment
  - How it works
  - Configuration
  - Image source copying methods
  - Complete container-based example
  - Using externally built images
  - Container-based best practices
  - When to use container-based deployment
  - Choosing the right approach
  - Decision tree
  - Hybrid approach
  - Troubleshooting
  - Import errors
  - Code changes not reflected
  - Files missing in container
  - Container build failures
  - Version conflicts
- [Running Tasks via Webhooks](https://www.union.ai/docs/v2/union/user-guide/task-deployment/invoke-webhook/page.md)
  - How passthrough authentication works
  - Setting up passthrough authentication
  - Initialize with `flyte.init_passthrough()`
  - Passing authentication metadata
  - Complete example
  - Calling the webhook
  - Best practices
  - Troubleshooting
  - "FLYTE_ENDPOINT environment variable not set"
  - "Authentication credentials required"
  - "Task not found"
  - Tasks run with wrong permissions
- [Deployment patterns](https://www.union.ai/docs/v2/union/user-guide/task-deployment/deployment-patterns/page.md)
  - Overview of deployment patterns
  - Simple file deployment
  - Example structure
  - Deployment commands
  - When to use
  - Custom Dockerfile deployment
  - Example structure
  - Alternative: Dockerfile in different directory
  - Key considerations
  - When to use
  - PyProject package deployment
  - Example structure
  - Business logic modules
  - Flyte orchestration layer
  - Entrypoint configuration
  - Dependencies and configuration
  - Key features
  - Key learning points
  - Usage patterns
  - What this example demonstrates
  - When to use
  - Package structure deployment
  - Example structure
  - Key concepts
  - Running with root directory
  - How `--root-dir` works
  - Alternative: Using a Python project
  - When to use
  - Full build deployment
  - Overview
  - Key configuration
  - Local dependency example
  - Critical configuration components
  - Configuration options
  - Version management best practices
  - Performance considerations
  - When to use
  - Troubleshooting
  - Python path deployment
  - Example structure
  - Implementation
  - Task environment dependencies
  - Key considerations
  - CLI vs Direct Python execution
  - Best practices
  - Common pitfalls
  - When to use
  - Dynamic environment deployment
  - Domain-based environment selection
  - Why this pattern works
  - How it works
  - Important constraints
  - Alternative: Environment variable approach
  - Usage patterns
  - When to use dynamic environments
  - Best practices
  - Project organization
  - Image management
  - Configuration management
  - Development workflow
  - Choosing the right pattern
- [Run context](https://www.union.ai/docs/v2/union/user-guide/task-deployment/run-context/page.md)
  - Configuring a run with `flyte.with_runcontext()`
  - Execution target
  - Storage
  - Caching
  - Identity and resources
  - Logging
  - Code bundling
  - Context propagation
  - Reading context inside a task with `flyte.ctx()`
  - `TaskContext` fields
  - `ActionID` fields
  - Naming external resources

---
**Source**: https://github.com/unionai/unionai-docs/blob/main/content/user-guide/task-deployment/_index.md
**HTML**: https://www.union.ai/docs/v2/union/user-guide/task-deployment/
