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.tomlconfig file (created vialk agent create) - Repository secrets configured for authentication
Required secrets
Add these secrets to your repository (Settings → Secrets and variables → Actions):
| Secret | Description |
|---|---|
LIVEKIT_URL | Your LiveKit Cloud URL (e.g., wss://your-project.livekit.cloud) |
LIVEKIT_API_KEY | Your LiveKit Cloud API key |
LIVEKIT_API_SECRET | Your LiveKit Cloud API secret |
SECRET_LIST | Comma-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 changeson: 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 Agenton: 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 Statuson: 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 Environmenton: 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
| Input | Description | Required | Default |
|---|---|---|---|
OPERATION | Operation to perform: create, deploy, status, status-retry | Yes | status |
WORKING_DIRECTORY | Directory containing the agent configuration | No | . |
REGION | Region to deploy to (defaults to nearest region) | No | "" |
SLACK_TOKEN | Slack Bot Token for notifications | No | - |
SLACK_CHANNEL | Slack channel for notifications | No | - |
TIMEOUT | Timeout for status-retry operation | No | 5m |
Best practices
- Use concurrency controls. Always include
concurrencyin 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.mdandlivekit.tomlfrom 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@mainto get the latest stable releases while avoiding breaking changes.