Skip to main content
This guide walks you through deploying Skyvern using Docker Compose. By the end, you’ll have a working Skyvern instance with the API server, browser, database, and web UI running on your machine.

Prerequisites

  • Docker and Docker Compose v2 installed (Get Docker). All commands use docker compose (with a space). If you have an older installation, replace with docker-compose.
  • 4GB+ RAM available
  • An LLM API key (OpenAI, Anthropic, Azure, Gemini, or Bedrock)

Quick start

1. Clone the repository

2. Configure environment variables

Copy the example environment file and configure your LLM provider:
Open .env and set your LLM provider. Here’s an example for OpenAI:
.env
For other providers, see LLM Configuration.

3. Configure the frontend

Copy the frontend environment file:
The default values work for local development. Docker Compose mounts the generated local credentials into the UI container, so you can leave VITE_SKYVERN_API_KEY as YOUR_API_KEY for the first startup.

4. Start the services

This pulls the images and starts three services:
  • postgres: Database on port 5432 (internal only)
  • skyvern: API server on port 8000
  • skyvern-ui: Web interface on port 8080
First startup takes 1-2 minutes as it runs database migrations and creates your organization.

5. Get your API key

Wait for all services to be healthy before continuing:
All three services should show healthy in the STATUS column. The skyvern container runs database migrations and generates credentials on first startup. This takes 1-2 minutes. Once healthy, retrieve your API key:
This file is auto-generated by Skyvern on first startup. The credentials inside are standard Skyvern API keys. You’ll see output like:
The host value uses the Docker-internal hostname skyvern. From your machine, use http://localhost:8000 instead. You only need the cred value. This is your API key.

6. Verify the installation

Open http://localhost:8080 in your browser. You should see the Skyvern dashboard. Test the API by listing workflows (should return an empty array on fresh install):
The API accepts requests on both /v1/ and /api/v1/. The frontend uses /api/v1 for backward compatibility. New integrations should use /v1/.

Understanding the services

The Docker Compose file defines three services that work together: The skyvern container includes Playwright with Chromium. The browser runs inside the same container as the API server. No separate browser service is needed.

Data volumes

Docker Compose mounts several directories for persistent storage:

Environment variables reference

The .env file controls the Skyvern server. Here are the most important variables grouped by purpose.

Environment files

docker-compose.yml uses TWO sources for service environment:
  1. Inline environment: block — compose-network values that depend on the docker network topology. Examples: DATABASE_STRING=postgresql+psycopg://skyvern:skyvern@postgres:5432/skyvern (the postgres hostname only resolves inside the compose network), BROWSER_TYPE, BROWSER_STREAMING_MODE, ENABLE_CODE_BLOCK.
  2. env_file: .env — user secrets (LLM API keys, etc.).
Do not move DATABASE_STRING from compose into .env. The .env.example shipped with the repo uses a localhost host that points at the backend container itself when used inside compose — moving that value into .env will break the database connection. If you have an existing .env from a pre-1.0.32 skyvern quickstart run, it may contain a leftover DATABASE_STRING=postgresql+psycopg://skyvern@localhost/skyvern line. Remove it:

LLM Configuration

Configure at least one LLM provider. See LLM Configuration for all providers.

Browser settings

Task execution

Database

The database connection is set in docker-compose.yml, not .env:
To use an external database, update this connection string and remove the postgres service.

Common operations

View logs

Restart after configuration changes

Stop all services

Update to latest version

Reset everything (including database)

This deletes all data including task history, credentials, and recordings.

Exposing to the network

By default, Skyvern only accepts connections from localhost. To expose it on your network:

Option 1: Bind to all interfaces

Edit docker-compose.yml to change the port bindings:

Option 2: Use a reverse proxy

For production deployments, put Skyvern behind nginx or Traefik:
Update the frontend environment to use your domain:
skyvern-frontend/.env
If exposing Skyvern to the internet, add authentication at the reverse proxy layer or use a VPN.

Troubleshooting

Check the logs for the failing service:
Common causes:
  • Missing or invalid LLM API key: look for LLM-related errors in logs
  • Database connection failed: check if postgres service is healthy with docker compose ps
The API key is missing, malformed, or doesn’t match the organization. Verify:
  1. The x-api-key header is included in your request
  2. The key matches exactly what’s in .skyvern/credentials.toml
  3. No extra whitespace or newlines in the key
The API key format is invalid (JWT decode failed). This usually means:
  • The key was truncated or corrupted during copy-paste
  • You’re using an API key from a different Skyvern installation
Regenerate credentials by resetting the installation:
Check that skyvern-frontend/.env has the correct values:
After updating, restart the UI:
The BROWSER_TYPE environment variable has an invalid value. Valid options:
  • chromium-headful: Browser with visible window (default)
  • chromium-headless: No visible window
  • cdp-connect: Connect to external Chrome
The page content is too large for the LLM. Try:
  • Simplifying your prompt
  • Starting from a more specific URL
  • Using a model with a larger context window

Next steps

LLM Configuration

Configure OpenAI, Anthropic, Azure, Ollama, and other providers

Browser Configuration

Customize browser settings, locales, and connect to external Chrome

Storage Configuration

Store artifacts in S3 or Azure Blob instead of local disk

Proxy Setup

Configure proxies to avoid bot detection