> For the complete documentation index, see [llms.txt](https://docs.observal.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.observal.io/self-hosting/upgrades.md).

# Upgrades

Safe upgrade flow for the Observal server stack.

## Quick upgrade (recommended)

If you installed Observal via `observal server start` (the embedded stack), the CLI handles upgrades automatically:

```bash
observal server upgrade --dry-run --output json
observal server upgrade --version 0.9.0 --force --output json
```

This pulls new Docker images, backs up PostgreSQL, recreates containers, and runs health checks. If the health check fails, it requests the previous image version again. Local shell and Docker access authorize the operation; the command does not require a reachable API or API role.

See [`observal server upgrade`](/cli-reference/server.md#observal-server-upgrade) for full details.

### Server-package upgrades

If you installed with `install-server.sh`, rerun the installer for the target release. Setup detects the existing `.env`. Choose the default **No** response when asked to replace configuration so custom values and existing direct credentials remain unchanged. The upgrade records the prior bind address when an older install has no `OBSERVAL_BIND_ADDRESS` setting.

Back up `.env`, `secrets/`, and the `apidata` and `pgdata` volumes first. Choosing **Yes** intentionally rebuilds the general configuration from the new template; core application, PostgreSQL, ClickHouse, Grafana, and demo credentials are preserved or migrated into restricted files, but unrelated custom environment entries must be reapplied.

## Before a manual upgrade

1. **Back up `pgdata`** and **`apidata`**. See [Backup and restore](/self-hosting/backup-and-restore.md). Backing up `chdata` is nice-to-have; losing telemetry is painful but not catastrophic.
2. **Read the** [**CHANGELOG**](https://github.com/Observal/Observal/blob/main/CHANGELOG.md) for the releases you're jumping across. Note any breaking changes.
3. **Pin the version you're upgrading to**: don't `git pull main` blindly. Check out a release tag or a known-good commit.

## Standard upgrade

```bash
cd Observal

# Fetch and check out the target version
git fetch --tags
git checkout v0.9.1

# Rebuild images
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml up --build -d

# Verify
docker compose -f docker/docker-compose.yml ps
curl http://localhost/health
```

The init container applies pending Postgres Alembic migrations and ClickHouse SQL migrations before the API starts. Watch the init logs for migration output:

```bash
docker logs -f observal-init
# Running database migrations...
# Running ClickHouse migrations...
```

## Zero-downtime upgrade (small teams)

If you run a single instance and have a \~30-second maintenance window:

1. Back up `pgdata`, `apidata`, `chdata`.
2. Stop the API and worker: `docker compose stop observal-api observal-worker`.
3. Apply migrations out of band with `alembic upgrade head` and `python -m services.clickhouse.migrations` from `observal-server`, or run the init container once.
4. Pull/rebuild new images: `docker compose pull && docker compose build observal-api observal-worker`.
5. Start: `docker compose up -d`.
6. Smoke test: `observal auth status --output json && observal ops telemetry status --output json`.

Web UI, Postgres, ClickHouse, Redis stay up throughout. Users see a brief API outage (\~15–30 s).

## Zero-downtime at scale

For blue/green upgrades on large deployments:

1. Run a second stack (`docker-compose.yml` with different project name and host ports) behind a reverse proxy.
2. Apply migrations before traffic cutover. Alembic handles Postgres and `services.clickhouse.migrations` handles ClickHouse. Additive migrations should work with API N-1 and N during the rollout.
3. Bring up the green stack pointing at the same `pgdata` / `chdata` / `apidata` volumes.
4. Flip the reverse proxy to green.
5. Decommission blue.

If a migration is **not** additive (rare, but happens: column drops, type changes), it gets called out in the CHANGELOG and requires a brief outage. Plan the window.

## Rolling back

If the new version breaks:

1. `docker compose -f docker/docker-compose.yml down`
2. `git checkout <previous-version>`
3. `docker compose -f docker/docker-compose.yml up --build -d`

**The catch:** if the failing version already applied a migration, downgrading to the previous API version may leave you running against a schema it doesn't know about. Options:

* **If the migration is additive** (most are): the previous version works fine against the newer schema.
* **If the migration is destructive**: restore from the pre-upgrade `pgdata` backup. This is why the backup is step 1.

## CLI upgrades

CLI upgrades are independent of server upgrades. Users:

```bash
observal self upgrade
```

The CLI speaks a stable contract with the server. A newer CLI works against an older server and vice versa, within a release or two.

On the first command after upgrading from a release that generated `observal-shim` entries, the CLI restores the original MCP command in known home and current-project config files. It writes a `.pre-unshim.bak` copy before each change. A malformed wrapped entry stops the command with a visible migration error rather than guessing at the original executable.

## Zero-downtime for the web UI

The web UI is a static Vite build and restarts instantly. Users see a brief reload if they are on the page during the deploy. No special handling required.

## Next

→ [Backup and restore](/self-hosting/backup-and-restore.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.observal.io/self-hosting/upgrades.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
