Skip to main content

Tutorial: Deploying Your First App

This tutorial guides you through the process of deploying, managing, and deleting an application using Flyte. You will learn how to define an application specification, deploy it to a Kubernetes cluster via Knative, and verify its status.

Prerequisites

Before starting, ensure your environment meets the following requirements:

  • Flyte is running with the App service enabled.
  • Knative Serving is installed in your Kubernetes cluster.
  • The flyte namespace exists (this is the default namespace where Flyte deploys applications).
  • You have a Go environment set up with the necessary Flyte IDL dependencies.

Step 1: Define the Application Specification

To deploy an application, you must first define its metadata and container specification. Flyte uses the App message to encapsulate the project, domain, and the container image to run.

import (
flyteapp "github.com/flyteorg/flyte/v2/gen/go/flyteidl2/app"
flytecoreapp "github.com/flyteorg/flyte/v2/gen/go/flyteidl2/core/app"
)

func createMyFirstApp() *flyteapp.App {
return &flyteapp.App{
Metadata: &flyteapp.Meta{
Id: &flyteapp.Identifier{
Project: "my-project",
Domain: "development",
Name: "nginx-app",
},
},
Spec: &flyteapp.Spec{
AppPayload: &flyteapp.Spec_Container{
Container: &flytecoreapp.Container{
Image: "nginx:latest",
},
},
// Set the desired state to STARTED to ensure it runs immediately
DesiredState: flyteapp.Spec_DESIRED_STATE_STARTED,
},
}
}

In this step, you define a flyteapp.App with a Spec_Container payload. Note that while the IDL supports Spec_Pod, Flyte currently only implements Container payloads.

Step 2: Deploy the Application

Use the AppService to create the application. The AppService acts as the control plane, proxying the request to the internal data plane which interacts with Kubernetes.

import (
"context"
"connectrpc.com/connect"
"github.com/flyteorg/flyte/v2/app/service"
)

func deploy(ctx context.Context, svc *service.AppService, app *flyteapp.App) error {
req := connect.NewRequest(&flyteapp.CreateRequest{
App: app,
})

_, err := svc.Create(ctx, req)
if err != nil {
return fmt.Errorf("failed to deploy app: %w", err)
}

fmt.Println("Application deployment initiated successfully.")
return nil
}

When you call Create, the AppK8sClientInterface (implemented by AppK8sClient) creates a Knative Service (KService) in the flyte namespace. The KService name is derived from your project, domain, and app name.

Step 3: Verify Deployment and Retrieve Ingress

After deployment, you can poll the application status to check if it is ready and retrieve its public URL.

func verify(ctx context.Context, svc *service.AppService) {
id := &flyteapp.Identifier{
Project: "my-project",
Domain: "development",
Name: "nginx-app",
}

req := connect.NewRequest(&flyteapp.GetRequest{
Id: id,
})

resp, _ := svc.Get(ctx, req)
app := resp.Msg.App

// Check the deployment status
if app.Status != nil {
fmt.Printf("Deployment Status: %s\n", app.Status.State)

if app.Status.Ingress != nil {
fmt.Printf("Public URL: %s\n", app.Status.Ingress.PublicUrl)
}
}
}

The AppService uses a per-instance LRU cache (configured via CacheTTL) to speed up Get requests. The Status field is the authoritative source for the live state of the application on the cluster.

Step 4: Stop the Application

To stop an application without deleting its configuration, update its DesiredState to STOPPED. This triggers the AppK8sClientInterface.Stop method, which scales the Knative Service to zero and makes it cluster-local.

func stopApp(ctx context.Context, svc *service.AppService, app *flyteapp.App) {
app.Spec.DesiredState = flyteapp.Spec_DESIRED_STATE_STOPPED

req := connect.NewRequest(&flyteapp.UpdateRequest{
App: app,
})

svc.Update(ctx, req)
fmt.Println("Application stopped (scaled to zero).")
}

Stopping an app preserves the KService resource but terminates the underlying pods. This is useful for saving resources while keeping the application ready for a quick restart.

Step 5: Delete the Application

When you no longer need the application, use the Delete method to remove all associated Kubernetes resources.

func cleanup(ctx context.Context, svc *service.AppService) {
id := &flyteapp.Identifier{
Project: "my-project",
Domain: "development",
Name: "nginx-app",
}

req := connect.NewRequest(&flyteapp.DeleteRequest{
Id: id,
})

svc.Delete(ctx, req)
fmt.Println("Application deleted.")
}

The Delete call invokes AppK8sClientInterface.Delete, which removes the KService CRD entirely. Unlike Stop, this action is not reversible without re-creating the application from scratch.

Summary

You have successfully:

  1. Defined a Flyte application using flyteapp.App.
  2. Deployed it using AppService.Create.
  3. Verified its status and ingress URL via AppService.Get.
  4. Managed its lifecycle by stopping and deleting it.

For more advanced use cases, you can explore AppK8sClientInterface.GetReplicas to inspect individual pods or AppK8sClientInterface.Subscribe to watch for real-time status updates.