Update
This guide covers updating a IntraCord 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 IntraCord/ directory if you used setup_remote.sh).
There are three update flows depending on how you deployed:
- Remote, prebuilt mode (most users) — use
update_remote.shbelow. - Local Docker — pull images and restart; see Local deployment.
- Remote, build mode (you have a
docker-compose.override.yaml) — update via git; see Updating a source build.
Find an image version
IntraCord publishes two images — IntraCord-api and IntraCord-ui — to both container registries:
- GitHub Container Registry — github.com/orgs/IntraCord-hq/packages
- Docker Hub — hub.docker.com/u/IntraCordai
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.
| Where | Tag format | Example | When to use |
|---|---|---|---|
| GitHub release tag | IntraCord-vX.Y.Z | IntraCord-v1.28.0 | Use when copying the version from a GitHub release |
| Docker image tag (semver) | X.Y.Z | 1.28.0 | Stable, recommended for production |
Docker image tag (latest) | latest | latest | Tracks the most recent release tag |
Remote, prebuilt mode (recommended)
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.yamlat that version and pins bothapianduiimages to it. - Refreshes the remote helper bundle (
remote_up.shplus shared templates/helpers). - Synchronizes the canonical remote keys in
.envand validates the runtime config thatIntraCord-initwill render from it. - Backs up every file it changes with a
.bak.<timestamp>suffix.
From your install directory:
cd IntraCord
curl -o update_remote.sh https://raw.githubusercontent.com/IntraCord-hq/IntraCord/main/scripts/update_remote.sh
bash 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 (IntraCord-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 IntraCord_UPDATE_YES=1 bash update_remote.sh
After the script finishes, apply the update through the validated startup wrapper:
./remote_up.sh
Local deployment
For local Docker installs (the Quick Start flow or setup_local.sh / setup_local.ps1), refresh docker-compose.yaml and the startup script, stop the stack, then run the startup script. 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:
curl -o docker-compose.yaml https://raw.githubusercontent.com/IntraCord-hq/IntraCord/main/docker-compose.yaml
curl -o start_docker.sh https://raw.githubusercontent.com/IntraCord-hq/IntraCord/main/scripts/start_docker.sh && chmod +x start_docker.sh
docker compose down
./start_docker.sh
Invoke-WebRequest -OutFile docker-compose.yaml https://raw.githubusercontent.com/IntraCord-hq/IntraCord/main/docker-compose.yaml; Invoke-WebRequest -OutFile start_docker.ps1 https://raw.githubusercontent.com/IntraCord-hq/IntraCord/main/scripts/start_docker.ps1; docker compose down; .\start_docker.ps1
To pin a specific version instead of latest, edit docker-compose.yaml and change both image: lines for api and ui to the same tag (e.g. :1.28.0 — Docker image tags use bare semver, no v prefix), then run the commands above.
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 IntraCord
for f in docker-compose.yaml nginx.conf turnserver.conf .env remote_up.sh scripts/run_IntraCord_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.
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 IntraCord
git fetch
# Track latest main:
git pull
# Or pin to a specific release (git tag format is IntraCord-vX.Y.Z):
git checkout IntraCord-v1.28.0
# Pick up pipecat and other submodule bumps
git submodule update --init --recursive
# Rebuild and restart
sudo docker compose --profile remote build
sudo docker compose --profile remote up -d
If you maintain a fork with local customizations on top of upstream, merging conflicts in docker-compose.yaml, remote_up.sh, scripts/run_IntraCord_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.