Skip to main content
Field Guides

Deploy LiveKit Agents with GitHub Actions

Automate agent deployments using the LiveKit deploy-action GitHub Action for CI/CD workflows.

Last Updated:


The LiveKit CLI is great for manual deployments, but production teams need CI/CD automation. The deploy-action GitHub Action lets you create, deploy, and monitor agents directly from your workflow files.

Prerequisites

Before setting up GitHub Actions, you need:

  • A LiveKit Cloud project
  • A working agent with a livekit.toml config file (created via lk agent create)
  • Repository secrets configured for authentication

Required secrets

Add these secrets to your repository (Settings → Secrets and variables → Actions):

SecretDescription
LIVEKIT_URLYour LiveKit Cloud URL (e.g., wss://your-project.livekit.cloud)
LIVEKIT_API_KEYYour LiveKit Cloud API key
LIVEKIT_API_SECRETYour LiveKit Cloud API secret
SECRET_LISTComma-separated list of agent secrets (e.g., OPENAI_API_KEY=sk-xxx,AUTH_TOKEN=abc123)

Deploy on push to main

The most common pattern: deploy your agent whenever code changes are pushed to your main branch.

name: Deploy agent on changes
on:
push:
branches:
- main
paths:
- 'my-agent/**'
- '!my-agent/livekit.toml'
- '!my-agent/**/*.md'
jobs:
deploy:
runs-on: ubuntu-latest
environment: my-agent
concurrency:
group: ${{ github.workflow }}-my-agent
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
- name: Deploy LiveKit Cloud Agent
uses: livekit/deploy-action@v2
env:
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
SECRET_LIST: ${{ secrets.SECRET_LIST }}
with:
OPERATION: deploy
WORKING_DIRECTORY: my-agent

The paths filter ensures deployments only trigger when agent code changes—not when you update docs or config files.

Create a new agent

Use manual dispatch to create new agents:

name: Create LiveKit Cloud Agent
on:
workflow_dispatch:
inputs:
working_directory:
description: 'Working directory for the agent'
required: true
type: string
default: '.'
jobs:
create-agent:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.working_directory }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write
pull-requests: write
actions: read
steps:
- uses: actions/checkout@v4
- name: Create LiveKit Cloud Agent
uses: livekit/deploy-action@v2
env:
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
SECRET_LIST: ${{ secrets.SECRET_LIST }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
OPERATION: create
WORKING_DIRECTORY: ${{ github.event.inputs.working_directory }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
add-paths: |
${{ github.event.inputs.working_directory }}/livekit.toml
token: ${{ secrets.GITHUB_TOKEN }}
branch: cloud-agent-${{ github.run_id }}
title: "Add LiveKit agent config"
commit-message: "Add LiveKit agent config"
body: "This PR adds the LiveKit agent configuration"
base: main
delete-branch: true

Creating an agent automatically deploys it—you don't need a separate deploy step.

Monitor agent status

Set up scheduled status checks with optional Slack notifications:

name: Monitor Agent Status
on:
schedule:
- cron: '*/30 * * * *'
jobs:
check-status:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
- name: Check Agent Status
uses: livekit/deploy-action@v2
env:
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
with:
OPERATION: status
SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL: "#monitoring"

Use status-retry instead of status if you want the action to poll until the agent reaches the Running state or times out:

- name: Wait for Running Status
uses: livekit/deploy-action@v2
env:
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
with:
OPERATION: status-retry
WORKING_DIRECTORY: my-agent
TIMEOUT: 5m

Deploy to multiple environments

For teams with separate dev, staging, and production environments, use GitHub environments and branch-based triggers. See Structuring development and test environments for the recommended project layout.

Create separate LiveKit Cloud projects for each environment, then configure environment-specific secrets:

name: Deploy to Environment
on:
push:
branches:
- main
- staging
- develop
paths:
- 'voice-agent/**'
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.ref_name == 'main' && 'production' || github.ref_name == 'staging' && 'staging' || 'development' }}
concurrency:
group: deploy-${{ github.ref_name }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
- name: Deploy to ${{ github.ref_name }}
uses: livekit/deploy-action@v2
env:
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
SECRET_LIST: ${{ secrets.SECRET_LIST }}
with:
OPERATION: deploy
WORKING_DIRECTORY: voice-agent

Each GitHub environment (production, staging, development) should have its own set of secrets pointing to the corresponding LiveKit Cloud project. This keeps credentials isolated and lets you enforce approval rules for production deployments.

Action inputs reference

InputDescriptionRequiredDefault
OPERATIONOperation to perform: create, deploy, status, status-retryYesstatus
WORKING_DIRECTORYDirectory containing the agent configurationNo.
REGIONRegion to deploy to (defaults to nearest region)No""
SLACK_TOKENSlack Bot Token for notificationsNo-
SLACK_CHANNELSlack channel for notificationsNo-
TIMEOUTTimeout for status-retry operationNo5m

Best practices

  • Use concurrency controls. Always include concurrency in your jobs to prevent multiple deployments from running simultaneously on the same agent.
  • Filter by paths. Avoid unnecessary deployments by excluding non-code files like README.md and livekit.toml from your triggers.
  • Separate environments. Use different LiveKit Cloud projects for dev, staging, and production—each with their own GitHub environment and secrets.
  • Pin action versions. Use a major version tag (e.g., @v2) rather than @main to get the latest stable releases while avoiding breaking changes.