Talkr AI
Enterprise Deployment

Docker

Deploy Talkr AI using Docker for local development and remote server environments

Enterprise Deployment is for running Talkr on your own infrastructure instead of the hosted platform. Access to the Talkr repository is provisioned per customer — your Talkr contact will grant you access and confirm the branch/release to deploy from. Everything below assumes you have a local checkout of that repository.

Talkr can be deployed using Docker in two main configurations. Choose the option that best fits your needs:

  • Option 1: For local development and testing on your own machine
  • Option 2: For remote server deployment with HTTPS (using IP address). If you also have a custom domain, you can first deploy Talkr stack on your server using steps in this document and then proceed to the Custom Domain section.

Option 1: Local Docker Deployment

For local development and testing, you can run Talkr directly on your machine using Docker with a small startup script.

Quick Start

From your repository checkout, run the starter script — it downloads nothing external, it just orchestrates the docker-compose.yaml already in the repo:

chmod +x scripts/start_docker.sh && ./scripts/start_docker.sh
.\scripts\start_docker.ps1

This setup:

  • Downloads the latest docker-compose.yaml
  • Creates OSS_JWT_SECRET, REDIS_PASSWORD, and MinIO credentials in .env if they do not already exist
  • Creates POSTGRES_PASSWORD for brand-new .env files and syncs retained local Postgres volumes to that value before startup
  • Prompts before running Docker Compose
  • Starts all required services including PostgreSQL, Redis, MinIO, API, and UI
  • Pulls the latest images automatically

Access the Application

Once running (first startup takes 2-3 minutes), open:

http://localhost:3010

You can disable telemetry by setting ENABLE_TELEMETRY=false before running ./start_docker.sh or .\start_docker.ps1.

Troubleshooting WebRTC Connectivity

The Quick Start above relies on direct peer-to-peer WebRTC between your browser and the API container. On most single-machine setups this works without any extra configuration. If you hit any of the following, you likely need a TURN server in the path:

  • The call connects but no audio flows in either direction
  • The browser console reports iceConnectionState: failed
  • You are testing from a browser on your smartphone or another device on your LAN against the laptop running Docker
  • A VPN, corporate firewall, or strict NAT sits between the browser and Docker

For these cases, use the alternate local setup script which configures a coturn TURN server alongside the rest of the stack:

chmod +x scripts/setup_local.sh && ./scripts/setup_local.sh
.\scripts\setup_local.ps1

The script will prompt you for:

  • Whether to enable coturn (answer y)
  • The host browsers should use to reach TURN (press Enter for 127.0.0.1; use your LAN IP if testing from another device on the same network)
  • A shared secret for the TURN server (press Enter to generate a random one)

It creates docker-compose.yaml, a .env file with JWT and TURN credentials, and the small helper bundle that talkr-init uses to render coturn config at startup. Start the stack with the local-turn profile so coturn comes up alongside the other services:

docker compose --profile local-turn --profile tunnel up --pull always

The application is still available at http://localhost:3010.

To verify that media is actually traversing TURN (and not silently falling back to a direct path), set FORCE_TURN_RELAY=true in .env and restart the API. The browser will then only use relay ICE candidates — if TURN is misconfigured or unreachable, the call fails cleanly with ICE failed in the console instead of appearing to work. Set it back to false once you have verified connectivity.

Option 2: Remote Server Deployment

Deploy Talkr on a remote server to make it accessible from anywhere. If your server has a public IP, setup obtains a free, trusted HTTPS certificate automatically via sslip.io and Let's Encrypt — no domain name or DNS configuration required, and no browser warning. On a private/reserved IP it falls back to a self-signed certificate. We need to serve the application over HTTPS, since modern browsers only allow microphone permissions for websites being served over HTTPS.

We highly recommend you set up the platform on a fresh server, so that there are less chances of confliciting dependencies, and ports from other applications.

Prerequisites

  • A server with Docker and Docker Compose installed. It should have minimum of 8 GB RAM and 4 vCPUs.
  • Root (sudo) access on the server — the setup script must be run as root and exits early otherwise.
  • Public IP address for your server. You can also access the server using a local IP address in your VPC as long as its reachable from your browser.
  • TCP Ports 80, 443, 3478, 5349 and UDP Ports 3478, 5349 and 49152:49200 reachable from Internet (Port 80 and 443 to access the UI and rest of the ports for WebRTC Signaling)
IMPORTANT: Please double check the ports on your firewall. Please refer to your server hosting provider's documentaion on how you can open these ports in the firewall of the server.

Quick Setup

From your repository checkout on the server, run the automated setup script that will configure everything for you:

chmod +x scripts/setup_remote.sh && sudo ./scripts/setup_remote.sh

Run with sudo — the script must run as root (it provisions Docker, binds ports 80/443, and installs a Let's Encrypt certificate with a system renewal hook) and exits early if it isn't. On a public IP it obtains and auto-renews a trusted certificate; on a private IP it falls back to a self-signed one, since Let's Encrypt can't validate a private address. Optional environment-variable overrides: CERT_MODE=self-signed forces a self-signed cert, ACME_DOMAIN_SUFFIX=nip.io switches to the nip.io pool if sslip.io is rate-limited, and LETSENCRYPT_EMAIL=you@example.com sets the address for expiry notices.

The script will prompt you for:

  • Your server's public IP address
  • A password for the TURN server (optional, press Enter for default)
  • Deployment mode — pick build to compile images from your repository checkout. (The script also offers a prebuilt mode that pulls pre-published images; use it only if your Talkr contact has confirmed a published image registry for your deployment — by default, build from source.)
  • Number of FastAPI workers (uvicorn processes nginx will load-balance) — press Enter for the default of 4, or pick a value that suits your server's CPU count. See Scaling for sizing guidance and how to change this on a running stack.

It will automatically:

  • Download the validated remote deployment helper bundle
  • Obtain a free trusted Let's Encrypt certificate via sslip.io and configure auto-renewal (public IP), or generate a self-signed certificate (private IP / no root)
  • For a public IP, also start the stack and print your ready-to-use https://…sslip.io URL
  • Create an environment file with TURN server configuration
  • Validate the runtime config that talkr-init will render from .env
  • Write a docker-compose.override.yaml with build directives (build mode only)

Start the Application

Please ensure that Docker Compose is installed on your machine before proceeding further. You can check whether its installed by running docker compose version command. If its not installed, please install it by following your server provider documentation.

After the setup script completes, start Talkr. For a public-IP install the trusted-certificate flow already started the stack and printed your https://…sslip.io URL — you can skip to Access Your Application. For a self-signed install, start it yourself (the script prints the exact command at the end — it differs slightly between modes):

cd talkr
./remote_up.sh
cd talkr
./remote_up.sh --build

First boot in build mode takes several minutes — Docker has to build both the API and UI images before the stack comes up.

Access Your Application

Your application will be available at the URL the setup script printed at the end:

  • Public IP (trusted certificate): https://<your-ip-with-dashes>.sslip.io — for example https://203-0-113-10.sslip.io. No browser warning.
  • Self-signed (private IP): https://YOUR_SERVER_IP

With a self-signed certificate your browser shows a security warning you can safely accept. With the sslip.io Let's Encrypt certificate there is no warning.

You should be able to create and test a voice agent now.

Configuration Notes

  • The remote deployment includes an nginx reverse proxy for HTTPS termination
  • File downloads (transcripts, recordings) are automatically routed through nginx
  • WebSocket connections for real-time features are properly proxied
  • Public-IP installs get a trusted Let's Encrypt certificate (via sslip.io) that renews automatically; private-IP installs use a self-signed certificate (browser warning)
  • The TURN server (coturn) is configured for WebRTC NAT traversal
  • For production deployments with proper SSL and domain names, see the Custom Domain documentation

Files Created

The setup script creates the following files in the talkr/ directory:

FilePurpose
docker-compose.yamlMain Docker Compose configuration
docker-compose.override.yamlBuild directives for api and ui (build mode only)
remote_up.shValidated startup wrapper for the remote stack
scripts/run_talkr_init.shOne-shot init renderer/validator used by Docker Compose
scripts/lib/setup_common.shShared deployment helper library
deploy/templates/nginx and coturn runtime config templates
generate_certificate.shScript to regenerate SSL certificates
certs/local.crtSSL certificate (Let's Encrypt via sslip.io, or self-signed)
certs/local.keySSL private key
.envSingle source of truth for deployment settings (TURN secret, JWT secret, FastAPI worker count, public host/base URL)

Building from source

Build mode is the default and recommended path today — pick it when the setup script prompts for deployment mode.

In this mode the script:

  1. If you run the script from inside an existing talkr checkout (recommended — see Quick Setup above), offers to use that checkout instead of cloning. Otherwise it will ask for a repository source (owner/name and branch) to clone from — this requires the repository access your Talkr contact has granted you.
  2. Generates a docker-compose.override.yaml next to docker-compose.yaml that swaps the image: directives for local build: directives. Docker Compose auto-loads the override file — you don't need to pass any -f flags.

Updating after a code change

Whenever the codebase changes — a git pull, a local edit, or a submodule bump — rebuild the api and ui images and recreate the running containers so they pick up the new code.

TL;DR (rebuilds both services and restarts in one shot):

cd talkr
sudo docker compose --profile remote up -d --build

--build rebuilds any service whose build: context has changed (both api and ui are wired through the docker-compose.override.yaml written by setup_remote.sh), and up -d recreates the affected containers so they run off the new image.

Step-by-step — use this when you're pulling fresh code from a remote, or want to be explicit:

cd talkr

# 1. Pull the latest source.
git pull
git submodule update --init --recursive   # picks up pipecat submodule bumps

# 2. Rebuild both images.
sudo docker compose --profile remote build api ui

# 3. Recreate the running containers so they use the new images.
sudo docker compose --profile remote up -d
If you update pipecat submodule, you must do git submodule update --init --recursive, or the Docker build step will not pick up pipecat changes

Rebuild a single service — faster when you only changed one side:

sudo docker compose --profile remote build api      # or: build ui
sudo docker compose --profile remote up -d api      # or: up -d ui

Force a clean rebuild — needed when a base image changed, a pip install was added, or you suspect a stale layer:

sudo docker compose --profile remote build --no-cache api ui
sudo docker compose --profile remote up -d

Verify the containers were actually recreated — check the CREATED column shows a recent timestamp, not minutes/hours ago:

sudo docker compose --profile remote ps

To revert to pulling official images, delete docker-compose.override.yaml and start the stack with --pull always as in the prebuilt flow.

Build mode is for self-hosters who want to deploy customized images — it is not tuned for active development on the code itself (no hot-reload).

Next Steps

Now that you are able to create and test a voice agent, you can setup a custom domain and setup SSL using letsencrypt. Checkout Custom Domain for instructions on how to do that.

On this page