Talkr AI
Enterprise Deployment

Update

Update your self-hosted Talkr stack to a newer image version

This guide covers updating a Talkr stack you've already deployed with Docker or a custom domain. You run commands from the same directory that contains your docker-compose.yaml (this is the talkr/ directory if you used setup_remote.sh).

There are three update flows depending on how you deployed:

  • Remote, build mode (most users today — you have a docker-compose.override.yaml) — update via git; see Updating a source build.
  • Local Docker — pull the latest source and restart; see Local deployment.
  • Remote, prebuilt mode — use update_remote.sh below, once your Talkr contact has confirmed a published image registry for your deployment.

Remote, prebuilt mode

This flow pulls versioned talkr-api/talkr-ui images from a container registry. Use it only once your Talkr contact has confirmed a registry is published for your deployment — otherwise use Updating a source build below, which works today for every deployment.

Each release is published under release tags. Note the formats differ between GitHub releases and Docker image tags — update_remote.sh understands both and normalizes for you.

WhereTag formatExampleWhen to use
GitHub release tagtalkr-vX.Y.Ztalkr-v1.28.0Use when copying the version from a GitHub release
Docker image tag (semver)X.Y.Z1.28.0Stable, recommended for production
Docker image tag (latest)latestlatestTracks the most recent release tag

Always update talkr-api and talkr-ui to the same tag. The two images are built from the same commit and the UI expects API responses in a matching shape — mixing versions will break the app. update_remote.sh handles this for you automatically.

update_remote.sh is the supported path for updating a stack created with setup_remote.sh. In one shot it:

  • Asks for a target version (defaults to the latest release tag on GitHub).
  • Pulls docker-compose.yaml at that version and pins both api and ui images to it.
  • Refreshes the remote helper bundle (remote_up.sh plus shared templates/helpers).
  • Synchronizes the canonical remote keys in .env and validates the runtime config that talkr-init will render from it.
  • Backs up every file it changes with a .bak.<timestamp> suffix.

From your install directory:

cd talkr
bash scripts/update_remote.sh

You'll be prompted for the target version, defaulting to the most recent release. Accepted forms: bare semver (1.28.0), v-prefixed (v1.28.0), the full GitHub tag (talkr-v1.28.0), or main to refresh deployment files from the default branch — the script normalizes them. Non-interactive callers can set it via environment variable and skip the confirmation prompt:

TARGET_VERSION=1.28.0 TALKR_UPDATE_YES=1 bash update_remote.sh

After the script finishes, apply the update through the validated startup wrapper:

./remote_up.sh

The script overwrites docker-compose.yaml and the remote helper bundle (remote_up.sh, scripts/run_talkr_init.sh, scripts/lib/setup_common.sh, and deploy/templates/*) from the shared upstream deployment bundle. If you've made local edits to any of these, check the .bak.<timestamp> files after the update and re-apply your edits.

Local deployment

For local Docker installs (the Quick Start flow or setup_local.sh / setup_local.ps1), pull the latest source, stop the stack, then run the startup script again. The script preserves existing .env secrets, creates REDIS_PASSWORD and MinIO credentials if they are missing, and only creates POSTGRES_PASSWORD for brand-new .env files. If a retained local Postgres volume already exists, it syncs the database user's password to .env before starting the full stack:

git pull
git submodule update --init --recursive
docker compose down
./scripts/start_docker.sh
git pull
git submodule update --init --recursive
docker compose down
.\scripts\start_docker.ps1

Verify the update

Check the running image tags:

docker compose ps --format "table {{.Service}}\t{{.Image}}"

You should see the API and UI both running the tag you pinned.

Hit the health endpoint to confirm the API is responding:

curl -k https://YOUR_SERVER_IP/api/v1/health      # remote
curl http://localhost:8000/api/v1/health           # local

Roll back

update_remote.sh saves backups of every file it touched. To roll back, restore them and recreate the stack — the exact commands (including the timestamp it used) are printed at the end of the script's output. The generic form:

cd talkr
for f in docker-compose.yaml nginx.conf turnserver.conf .env remote_up.sh scripts/run_talkr_init.sh scripts/lib/setup_common.sh deploy/templates/nginx.remote.conf.template deploy/templates/turnserver.remote.conf.template; do
    [[ -f "$f.bak.<timestamp>" ]] && cp "$f.bak.<timestamp>" "$f"
done
./remote_up.sh

Your Postgres data volume persists across down/up cycles, so agents and call history are preserved.

Rolling back across a database migration is not always safe — if the newer release ran a schema migration, downgrading may leave the DB in a state the older API doesn't understand. If in doubt, contact your Talkr admin before rolling back.

Updating a source build

If you deployed in build mode (you'll have a docker-compose.override.yaml in your install directory), update_remote.sh deliberately refuses to run — you already have the full repo locally and update via git:

cd talkr
git fetch

# Track latest main:
git pull
# Or pin to a specific release (git tag format is talkr-vX.Y.Z):
git checkout talkr-v1.28.0

# Pick up pipecat and other submodule bumps
git submodule update --init --recursive

# Rebuild
sudo docker compose --profile remote build

# Wait for in-progress calls to finish, then restart
./scripts/drain_docker.sh
sudo docker compose --profile remote up -d

If you update the pipecat submodule, you must run git submodule update --init --recursive before rebuilding, or the Docker build will not pick up pipecat changes.

Restarting the API cuts off calls that are in progress. Recreating the container sends SIGTERM to its workers, which force-closes live call WebSockets — the caller is disconnected mid-sentence, not eased out. scripts/drain_docker.sh waits until every worker reports zero active calls first. It needs TALKR_DEVOPS_SECRET set in .env; without it the script can't tell a busy worker from an idle one and only pauses briefly. See Draining calls before a restart.

If you maintain a fork with local customizations on top of upstream, merging conflicts in docker-compose.yaml, remote_up.sh, scripts/run_talkr_init.sh, deploy/templates/*, or setup_remote.sh is up to you — resolve them as you would any other git merge. Leave OSS_JWT_SECRET, TURN_SECRET, POSTGRES_PASSWORD, REDIS_PASSWORD, MINIO_ROOT_USER, and MINIO_ROOT_PASSWORD in .env unchanged across updates to preserve sessions, WebRTC auth, and service credentials.

The same migration warning above applies: rolling back across a schema change can leave the DB in a state the older API can't read.

On this page