App environment settings

[[AppEnvironment]]s control how your apps run in Flyte, including images, resources, secrets, startup behavior, and autoscaling.

Shared environment settings

[[AppEnvironment]]s share many configuration options with [[TaskEnvironment]]s:

  • Images: See Container images for details on creating and using container images
  • Resources: See Resources for CPU, memory, GPU, and storage configuration
  • Secrets: See Secrets for injecting secrets into your app
  • Environment variables: Set via the env_vars parameter (same as tasks)
  • Cluster pools: Specify via the cluster_pool parameter

App-specific environment settings

type

The type parameter is an optional string that identifies what kind of app this is. It’s used for organizational purposes and may be used by the UI or tooling to display or filter apps.

app_env = flyte.app.AppEnvironment(
    name="my-fastapi-app",
    type="FastAPI",
    # ...
)

When using specialized app environments like FastAPIAppEnvironment, the type is automatically set. For custom apps, you can set it to any string value.

port

The port parameter specifies which port your app listens on. It can be an integer or a Port object.

# Using an integer (simple case)
app_env = flyte.app.AppEnvironment(name="my-app", port=8080, ...)

# Using a Port object (more control)
app_env = flyte.app.AppEnvironment(
    name="my-app",
    port=flyte.app.Port(port=8080),
    # ...
)

The default port is 8080. Your app should listen on this port (or the port you specify).

Ports 8012, 8022, 8112, 9090, and 9091 are reserved and cannot be used for apps.

args

The args parameter specifies arguments to pass to your app’s command. This is typically used when you need to pass additional arguments to the command specified in command, or when using the default command behavior.

app_env = flyte.app.AppEnvironment(
    name="streamlit-app",
    args="streamlit run main.py --server.port 8080",
    port=8080,
    # ...
)

args can be either a string (which will be shell-split) or a list of strings:

# String form (will be shell-split)
args="--option1 value1 --option2 value2"

# List form (more explicit)
args=["--option1", "value1", "--option2", "value2"]

Environment variable substitution

Environment variables are automatically substituted in args strings when they start with the $ character. This works for both:

  • Values from env_vars
  • Secrets that are specified as environment variables (via as_env_var in flyte.Secret)

The $VARIABLE_NAME syntax will be replaced with the actual environment variable value at runtime:

# Using env_vars
app_env = flyte.app.AppEnvironment(
    name="my-app",
    env_vars={"API_KEY": "secret-key-123"},
    args="--api-key $API_KEY",  # $API_KEY will be replaced with "secret-key-123"
    # ...
)

# Using secrets
app_env = flyte.app.AppEnvironment(
    name="my-app",
    secrets=flyte.Secret(key="AUTH_SECRET", as_env_var="AUTH_SECRET"),
    args=["--api-key", "$AUTH_SECRET"],  # $AUTH_SECRET will be replaced with the secret value
    # ...
)

This is particularly useful for passing API keys or other sensitive values to command-line arguments without hardcoding them in your code. The substitution happens at runtime, ensuring secrets are never exposed in your code or configuration files.

For most AppEnvironments, use args instead of command to specify the app startup command in the container. This is because args will use the fserve command to run the app, which unlocks features like local code bundling and file/directory mounting via parameter injection.

command

The command parameter specifies the full command to run your app. If not specified, Flyte will use a default command that runs your app via fserve, which is the Python executable provided by flyte to run apps.

# Explicit command
app_env = flyte.app.AppEnvironment(
    name="streamlit-hello",
    command="streamlit hello --server.port 8080",
    port=8080,
    # ...
)

# Using default command (recommended for most cases)
# When command is None, Flyte generates a command based on your app configuration
app_env = flyte.app.AppEnvironment(name="my-app", ...)  # command=None by default

For most apps, especially when using specialized app environments like FastAPIAppEnvironment, you don’t need to specify command as it’s automatically configured. Use command when you need to specify the raw container command, e.g. when running a non-Python app or when you have all of the dependencies and data used by the app available in the container.

requires_auth

The requires_auth parameter controls whether the app requires authentication to access. By default, apps require authentication (requires_auth=True).

# Public app (no authentication required)
app_env = flyte.app.AppEnvironment(
    name="public-dashboard",
    requires_auth=False,
    # ...
)

# Private app (authentication required - default)
app_env = flyte.app.AppEnvironment(
    name="internal-api",
    requires_auth=True,
    # ...
)  # Default

When requires_auth=True, users must authenticate with Flyte to access the app. When requires_auth=False, the app is publicly accessible (though it may still require API keys or other app-level authentication).

domain

The domain parameter specifies a custom domain or subdomain for your app. Use flyte.app.Domain to configure a subdomain or custom domain.

app_env = flyte.app.AppEnvironment(
    name="my-app",
    domain=flyte.app.Domain(subdomain="myapp"),
    # ...
)

The links parameter adds links to the App UI page. Use flyte.app.Link objects to specify relative or absolute links with titles.

app_env = flyte.app.AppEnvironment(
    name="my-app",
    links=[
        flyte.app.Link(path="/docs", title="API Documentation", is_relative=True),
        flyte.app.Link(path="/health", title="Health Check", is_relative=True),
        flyte.app.Link(path="https://www.example.com", title="External link", is_relative=False),
    ],
    # ...
)

include

The include parameter specifies files and directories to include in the app bundle. Use glob patterns or explicit paths to include code files needed by your app.

app_env = flyte.app.AppEnvironment(
    name="my-app",
    include=["*.py", "models/", "utils/", "requirements.txt"],
    # ...
)

Learn more about including additional files in your app deployment here.

parameters

The parameters parameter passes parameters to your app at deployment time. Parameters can be primitive values, files, directories, or delayed values like RunOutput or AppEndpoint.

app_env = flyte.app.AppEnvironment(
    name="my-app",
    parameters=[
        flyte.app.Parameter(name="config", value="foo", env_var="BAR"),
        flyte.app.Parameter(name="model", value=flyte.io.File(path="s3://bucket/model.pkl"), mount="/mnt/model"),
        flyte.app.Parameter(name="data", value=flyte.io.File(path="s3://bucket/data.pkl"), mount="/mnt/data"),
    ],
    # ...
)

Learn more about passing parameters to your app at deployment time here.

scaling

The scaling parameter configures autoscaling behavior for your app. Use flyte.app.Scaling to set replica ranges and idle TTL.

app_env = flyte.app.AppEnvironment(
    name="my-app",
    scaling=flyte.app.Scaling(
        replicas=(1, 5),
        scaledown_after=300,  # Scale down after 5 minutes of idle time
    ),
    # ...
)

Learn more about autoscaling apps here.

depends_on

The depends_on parameter specifies environment dependencies. When you deploy an app, all dependencies are deployed first.

backend_env = flyte.app.AppEnvironment(name="backend-api", ...)

frontend_env = flyte.app.AppEnvironment(
    name="frontend-app",
    depends_on=[backend_env],  # backend-api will be deployed first
    # ...
)

Learn more about app environment dependencies her e.

App startup

There are two ways to start up an app in Flyte:

  1. With a server function using @app_env.server
  2. As a container command using command or args

Server decorator via @app_env.server

The server function is a Python function that runs the app. It is defined using the @app_env.server decorator.

fastapi-server-example.py
app = fastapi.FastAPI()

env = FastAPIAppEnvironment(
    name="configure-fastapi-example",
    app=app,
    image=flyte.Image.from_uv_script(__file__, name="configure-fastapi-example"),
    resources=flyte.Resources(cpu=1, memory="512Mi"),
    requires_auth=False,
    port=8080,
)

@env.server
def server():
    print("Starting server...")
    uvicorn.run(app, port=8080)


@app.get("/")
async def root() -> dict:
    return {"message": "Hello from FastAPI!"}

The @app_env.server decorator allows you to define a synchronous or asynchronous function that runs the app, either with a server start command like uvicorn.run, HTTPServer.serve_forever, etc.

Generally the [[FastAPIAppEnvironment]] handles serving automatically under the hood, the example above just shows how the @app_env.server decorator can be used to define a server function that runs the app.

Startup hook

The server function is called after the app is started up, and before the app is shut down. It is defined using the @app_env.on_startup decorator. This is useful if you need to load any state or external connections needed to run the app before it starts.

fastapi-server-example.py
state = {}

@env.on_startup
async def app_startup():
    print("App started up")
    state["data"] = ["Here's", "some", "data"]

Shutdown hook

The server function is called before the app instance shuts down during scale down. It is defined using the @app_env.on_shutdown decorator. This is useful if you need to clean up any state or external connections in the container running the app.

fastapi-server-example.py
@env.on_shutdown
async def app_shutdown():
    print("App shut down")
    state.clear()  # clears the data

Container command via command vs args

The difference between args and command is crucial for properly configuring how your app starts.

  • command: The full command to run your app, for example, "streamlit hello --server.port 8080". For most use cases, you don’t need to specify command as it’s automatically configured, and uses the fserve executable to run the app. fserve does additional setup for you, like setting up the code bundle and loading parameters if provided, so it’s highly recommended to use the default command.
  • args: Arguments to pass to your app’s command (used with the default Flyte command or your custom command). The fserve executable takes in additional arguments, which you can specify as the arguments needed to run your app, e.g. uvicorn run main.py --server.port 8080.

Default startup behavior

When you don’t specify a command, Flyte generates a default command that uses fserve to run your app. This default command handles:

  • Setting up the code bundle
  • Configuring the version
  • Setting up project/domain context
  • Injecting parameters if provided

The default command looks like:

fserve --version <version> --project <project> --domain <domain> -- <args>

So if you specify args, they’ll be appended after the -- separator.

Using args with the default command

When you use args without specifying command, the args are passed to the default Flyte command:

app-startup-examples.py
# Using args with default command
app_env = flyte.app.AppEnvironment(
    name="streamlit-app",
    args="streamlit run main.py --server.port 8080",
    port=8080,
    include=["main.py"],
    # command is None, so default Flyte command is used
)

This effectively runs:

fserve --version ... --project ... --domain ... -- streamlit run main.py --server.port 8080

Using an explicit command

When you specify a command, it completely replaces the default command:

app-startup-examples.py
# Using explicit command
app_env2 = flyte.app.AppEnvironment(
    name="streamlit-hello",
    command="streamlit hello --server.port 8080",
    port=8080,
    # No args needed since command includes everything
)

This runs exactly:

streamlit hello --server.port 8080

Using a command with args

You can combine both, though this is less common:

app-startup-examples.py
# Using command with args
app_env3 = flyte.app.AppEnvironment(
    name="custom-app",
    command="python -m myapp",
    args="--option1 value1 --option2 value2",
    # This runs: python -m myapp --option1 value1 --option2 value2
)

FastAPIAppEnvironment example

When using FastAPIAppEnvironment, the command is automatically configured to run uvicorn:

app-startup-examples.py
# FastAPIAppEnvironment automatically sets command
from flyte.app.extras import FastAPIAppEnvironment
from fastapi import FastAPI

app = FastAPI()

env = FastAPIAppEnvironment(
    name="my-api",
    app=app,
    # You typically don't need to specify command or args, since the
    # FastAPIAppEnvironment automatically uses the bundled code to serve the
    # app via uvicorn.
)

The FastAPIAppEnvironment automatically:

  1. Detects the module and variable name of your FastAPI app
  2. Uses an internal server function to start the app via uvicorn.run.
  3. Handles all the startup configuration for you

Shared settings

For more details on shared settings like images, resources, and secrets, refer to the task configuration documentation.