# Updates and backups

At the end, your runner runs the newest release, you can go back to the one before, and you have a backup of everything it keeps.

## At a glance

**Time:** 5 minutes for an update or a backup.

**You need:**

- The runner from [Any Linux box](any-box.md)
- A Terminal on the box, in the `loopgate` folder (`cd ~/loopgate`)

## Update

Each release of Loopgate is a new `compose.yaml`. An update downloads only what changed, and your settings are kept.

1. **Keep a copy of the current file**, so you can go back.

   ```sh
   cp compose.yaml compose.previous.yaml
   ```

2. **Download the new one.**

   ```sh
   curl -fsSLO https://loopgate.dev/runner/compose.yaml
   ```

3. **Pull and restart.**

   ```sh
   docker compose pull && docker compose up -d
   ```

   You should see: each container `Started` or `Running`, and `Runner ready at …` in `docker compose logs runner`.

## Undo an update

1. **Put the previous file back.**

   ```sh
   cp compose.previous.yaml compose.yaml
   ```

2. **Restart.**

   ```sh
   docker compose up -d
   ```

   You should see: each container `Started` or `Running`.

## Back up

A backup copies everything the runner keeps: its runs and settings, your code on the box, and the coding tools' sign-ins. It holds those sign-ins, so store it like a password.

1. **Stop the runner.**

   ```sh
   docker compose stop
   ```

2. **Copy everything into one file.**

   ```sh
   docker run --rm -v loopgate-runner_data:/data -v loopgate-runner_repos:/repos -v loopgate-runner_home:/home/node -v "$PWD":/backup debian:bookworm-slim tar czf /backup/loopgate-runner.tgz /data /repos /home/node
   ```

   You should see: a file `loopgate-runner.tgz` in the folder. Copy it off the box to somewhere safe.

3. **Start it again.**

   ```sh
   docker compose start
   ```

## Good to know

- Browsers stay signed in across a restart. A temporary address changes, so on one each person opens the runner from the portal again.
- A step that was working when the runner restarted shows as interrupted, with **Retry**.
- Stop one task with **Stop** on the task in the workbench or in its Slack thread, or with `docker compose exec runner loopgate cancel <run>` (the run's id is in its workbench address).
- Shut the door for everyone: revoke the runner in the portal's **Devices** page, or run `docker compose exec runner loopgate logout`. Within a minute nobody can open it. Tasks already working carry on until they need a person or end.
- `docker compose logs runner` reads the runner's lines, and `docker compose logs slack` the Slack worker's.

## If something is off

- **`Runner ready at https://…`.** All is well. `(temporary address)` after it is the quick tunnel's, which changes at a restart.
- **`This runner is signed out. Run loopgate login on its host.`** Paste a fresh line from the portal's Devices → Add a runner, or run `docker compose exec runner loopgate login --no-open`.
- **`The install token was refused: …`.** The rest of the line says why. Paste a fresh line from Devices → Add a runner.
- **`The runner is fetching its org policy.`** It is starting. Wait a minute.
- **`This runner belongs to another org. Give it a fresh data directory.`** The box was signed in to a different Loopgate org before. Ask us for help.
- **`This data directory has runs from before it was a runner. Give it a fresh one.`** The box's data predates the runner. Ask us for help.
- **`Loopgate Slack worker is connected for T…`.** The Slack worker is working. Settings → Slack says the same, or the worker's error in one sentence.
- **`No Loopgate daemon answers in /data: …`.** The runner is not up. Check `docker compose ps` and the runner's lines.
- **"This link expired. Open the runner from the portal again."** The portal's pass lasts one minute and works once. Press **Open** in **Devices** again.
- **"Not a current member of this org."** The person is not a member of your Loopgate org, or was removed. An owner or admin adds them in the portal; a new member gets in within about two minutes.
- **"Ask an owner or admin of your org to … on this runner."** Signing in engines, saving GitHub or Slack and adding workspaces on a runner are an owner's or admin's.
- **Still stuck.** Write to us where we shared these docs with you, with what you did, what you expected, `docker compose logs --tail 50 runner` and `docker compose ps`. Never send a token, a key, `runner.env`, `slack.env`, `tunnel.env` or a backup file.

## Next

- [By hand](by-hand.md)
- [Connect Slack](slack-connect.md)
