# Updates

You update Lalabase by pulling the new image and running migrations.

## Before updating

<div class="docs-callout docs-callout--warning">
  <div class="docs-callout__title">Always back up first</div>
  <p>Take a fresh <a href="https://lalabase.com/docs/en/self-hosting/operation/backups">backup</a> before every update. Database migrations are not always backward-compatible.</p>
</div>

## Performing the update

```bash
# Pull the new version
docker compose pull

# Restart containers with the new image
docker compose up -d

# Run migrations
docker compose exec web bin/rails db:migrate
```

## Data tasks after the migration

Some updates ship a **one-off data task** alongside the migrations. It is kept separate
because it rewrites data rather than schema, and it belongs immediately after `db:migrate`.
All of these tasks are idempotent: a second run costs nothing.

**This update ships two.** The operator switch for code indexing is now called
`code_indexing_enabled`; it used to be named after a surface that no longer exists. The
task copies the old value into the new column:

```bash
docker compose exec web bin/rails organisations:backfill_code_indexing DRY_RUN=1
docker compose exec web bin/rails organisations:backfill_code_indexing
```

<div class="docs-callout docs-callout--warning">
  <div class="docs-callout__title">Skip this run and code indexing switches itself off</div>
  <p>The rename spans three versions. The middle one reads both columns so nothing falls over. Skip the run and install the version after that, and your organisations lose code indexing silently: the new column is empty and the old one is no longer read. Running the task fixes that at any later point, and a second run costs nothing.</p>
</div>

**Codebase imports.** The mappings of a CodebaseHQ import now belong to the organisation
that imported. Before, one organisation's import could pick up tickets, billing groups and
people of another organisation when both had loaded the same export. The task assigns the
existing mappings and lists imported time entries that an earlier import linked across
organisations; it does not change those entries:

```bash
docker compose exec web bin/rails codebase_import:scope_mappings DRY_RUN=1
docker compose exec web bin/rails codebase_import:scope_mappings
```

<div class="docs-callout docs-callout--warning">
  <div class="docs-callout__title">Run it before the next import</div>
  <p>Until this run a new import does not see the old mappings and creates already imported tickets again. People who cannot be assigned to exactly one organisation stay unassigned; running the user import again in that organisation maps them by e-mail.</p>
</div>

## Mind the architecture

Lalabase runs on x86_64. If you build your own images, always build them on the **target
architecture** — native extensions are not portable between ARM and x86_64.

## Rollback

If something goes wrong, roll back to the previous image tag and restore the backup if
needed. In production, pin specific version tags instead of `latest` so rollbacks stay
reproducible.

One exception concerns the help texts the assistant reads. Lalabase never syncs them back to
older files by itself, so that a process of the old version cannot turn them back during an
update. After a rollback the assistant therefore keeps reading the newer texts until you sync
them:

```bash
docker compose exec web bin/rails product_knowledge:sync
```
