Upgrading Trinity
Apply code changes safely to a running Trinity instance. The procedure below keeps agent containers running throughout the upgrade — only the platform services are restarted.
When to Run This
Run this procedure before or after every git pull that includes changes to platform code (backend, frontend, MCP server, scheduler). Skip it for documentation-only changes.
Pre-flight Checklist
- Back up the database (Step 1 below — do this first, always)
- Confirm at least 2 GB disk free: df -h /
- Note the current Git SHA: git rev-parse HEAD
- Check that no critical agent tasks are running: docker ps --filter "label=trinity.platform=agent"
- Confirm Docker is running: docker info >/dev/null 2>&1
Step 1: Back Up the Database
The database is the critical state. Back it up before every upgrade.
Development (named volume)
docker run --rm \
-v trinity_trinity-data:/data \
-v ~/backups:/backup \
alpine cp /data/trinity.db /backup/trinity-$(date +%Y%m%d-%H%M%S).dbProduction note: On a server using docker-compose.prod.yml, the database lives in a bind-mount directory (e.g., /srv/trinity-data/), not in the named volume. Adjust accordingly:
cp /srv/trinity-data/trinity.db ~/backups/trinity-$(date +%Y%m%d-%H%M%S).dbVerify the backup is readable:
sqlite3 ~/backups/trinity-<timestamp>.db ".tables"
# Expected: a list of table names, no errorsStep 2: Pull Latest Changes
git pull origin mainReview what changed:
git log --oneline -10
git diff HEAD~1 HEAD --statIf docker/base-image/Dockerfile appears in the diff, see Step 5: Base Image Upgrade below.
Step 3: Rebuild Platform Services
# Development
docker compose build --no-cache backend frontend mcp-server scheduler
# Production
docker compose -f docker-compose.prod.yml build --no-cache backend frontend mcp-server schedulerThe trinity-agent-base image is not rebuilt by this command. It changes much less often, and rebuilding it forces every agent to be re-deployed. Rebuild it only when docker/base-image/Dockerfile itself changes.
Step 4: Restart Platform Services
Use docker compose restart, not down/up. docker compose down removes the trinity-agent-network, orphaning every running agent container — they keep running but lose their network.
# Development
docker compose restart backend frontend mcp-server scheduler
# Production
docker compose -f docker-compose.prod.yml restart backend frontend mcp-server schedulerServices restart in parallel. The backend typically takes 10–20 seconds to become healthy.
Step 5: Verify
Run the six-probe verification. All must pass before you declare the upgrade complete:
# 1. Backend
curl -s http://localhost:8000/health
# Expected: {"status":"healthy",...}
# 2. Scheduler
curl -s http://localhost:8001/health
# Expected: {"status":"healthy","active_schedules":N}
# 3. Frontend (HTTP 200)
curl -s -o /dev/null -w '%{http_code}' http://localhost
# Expected: 200
# 4. Redis
docker exec trinity-redis redis-cli ping
# Expected: PONG
# 5. MCP Server
curl -s http://localhost:8080/health
# Expected: 200 OK
# 6. Vector (log aggregation)
docker exec trinity-vector wget -q -O - http://localhost:8686/health
# Expected: non-empty responseConfirm the new version is live. After the probes pass, check that the backend is actually running the build you just deployed:
curl -s http://localhost:8000/api/version
# Expected: {"version":"0.6.0","git_commit_short":"<sha>","git_branch":"...","build_date":"..."}The git_commit_short, git_branch, git_commit_subject, and build_date fields come from build-time provenance baked into the image. If they read "unknown", the image was built without the deploy script's build args — rebuild with scripts/deploy/start.sh to populate them. The same metadata is visible in the UI via the version chip in the navigation bar (click it for the Build Info dialog) and in Settings.
Note: JWT tokens are invalidated when the backend restarts. Users with active web UI sessions will need to log in again. MCP clients (Claude Code) will need to reconnect — run /mcp in your Claude Code session or restart the client.
Base Image Upgrade (if needed)
Rebuild the base image only when docker/base-image/Dockerfile changes:
./scripts/deploy/build-base-image.shAfter the base image is rebuilt, existing agent containers continue using the old image until they are individually stopped and recreated. There is no automatic roll-forward — agents pick up the new base image the next time they are (re)created.
Rollback
If something goes wrong after the upgrade:
1. Stop platform services
# Development
docker compose stop backend frontend mcp-server scheduler
# Production
docker compose -f docker-compose.prod.yml stop backend frontend mcp-server scheduler2. Restore the database backup
# Development (named volume)
docker run --rm \
-v trinity_trinity-data:/data \
-v ~/backups:/backup \
alpine cp /backup/trinity-<timestamp>.db /data/trinity.db
# Production (bind mount)
cp ~/backups/trinity-<timestamp>.db /srv/trinity-data/trinity.db3. Check out the previous version
git checkout <previous-sha>
# or
git checkout <previous-tag>4. Rebuild and restart
docker compose build --no-cache backend frontend mcp-server scheduler
docker compose restart backend frontend mcp-server scheduler5. Run the six-probe verification to confirm rollback succeeded.