# Back up and restore

Keep a copy of everything GoRunner holds, and put it back on the same server or a new one.

A backup is four things, taken together. Missing any one loses data.

## What a backup holds

- **The database**: Accounts, workflows, settings, runs, and what Storage and Queue steps keep.
- **The file storage**: What every step read and wrote. Without it, runs show no data.
- **Redis**: Who is signed in. Without it, everyone signs in again.
- **The `.env` file**: Its `ENCRYPTION_KEY` opens every stored password and connection. A restore needs the same key.

On Kubernetes, back up your own database, Redis and bucket with your provider’s tools, and keep `ENCRYPTION_KEY` apart from them. The chart’s bundled stores have no backups.

## 1. Take a backup

In the install folder, paste the whole block into one terminal. GoRunner can keep running.

You should see three files named after the date and time, such as `gorunner-2026-10-25-0200.dump`.

Copy them off the server, then delete them here. Take a backup every night and before every update.

```bash
cd gorunner
umask 077                         # the files are readable by you alone
stamp=$(date +%Y-%m-%d-%H%M)

# 1. The database
docker compose exec -T postgres \
  pg_dump -U gorunner -Fc gorunner > gorunner-$stamp.dump

# 2. The file storage
docker compose exec -T seaweedfs \
  tar czf - -C /data . > seaweed-$stamp.tgz

# 3. Redis: save to disk, wait for the save, then copy it
docker compose exec -T redis sh -c '
  redis-cli -a "$REDIS_PASSWORD" --no-auth-warning BGSAVE &&
  while redis-cli -a "$REDIS_PASSWORD" --no-auth-warning \
    INFO persistence | grep -q rdb_bgsave_in_progress:1
  do sleep 1; done'
docker compose exec -T redis \
  tar czf - -C /data . > redis-$stamp.tgz
```

## 2. Keep .env apart

Keep `.env` in your password manager or secret store, never next to the three files. A backup kept with its key is a copy anyone can read.

Keep `.gorunner-stores`, `.env.previous-stores` (if there is one) and `certs/` with it.

## 3. Restore on the same server

This replaces everything GoRunner holds. Copy the three files into the install folder, set `stamp` to their date and time, and run the block.

The `ENCRYPTION_KEY` in `.env` must be the one from when the backup was taken.

If `pg_restore` can’t connect, the database is still starting. Run that line again.

```bash
stamp=2026-10-25-0200   # replace: your backup's date and time
docker compose down
docker compose run --rm --no-deps -T --entrypoint sh seaweedfs \
  -c 'rm -rf /data/* && tar xzf - -C /data' < seaweed-$stamp.tgz
docker compose run --rm --no-deps -T --entrypoint sh redis \
  -c 'rm -rf /data/* && tar xzf - -C /data' < redis-$stamp.tgz
docker compose up -d postgres
docker compose exec -T postgres pg_restore -U gorunner \
  -d gorunner --clean --if-exists < gorunner-$stamp.dump
docker compose up -d
```

## 4. Check the restore

In **Connections**, open a connection and press **Test**. If it works, the key and the database match.

In **Runs**, open a finished run and select a step. If its data shows, the file storage matches too.

> **Warning** `docker compose down` keeps your data. `docker compose down -v` deletes all of it: the database, the file storage, Redis and the certificates. There is no undo.

## Restore on a new server

1. Follow [Install with Docker](https://docs.gorunner.io/self-host/install-docker) to step 3, with the domain pointed at the new server. Download the version the backup came from: the `GORUNNER_TAG` line in your `.env` says which.
2. Don’t run `./setup.sh`. Put your saved `.env` in the install folder and run `chmod 600 .env`.
3. Run the restore block above. With automatic HTTPS, Caddy gets the new server’s certificate by itself.

**What if the database, Redis or storage is my own?**

Back each one up with its own tools, and leave its lines out of the blocks above.

- **Database:** your provider’s snapshots, or `pg_dump` from a machine that reaches it. Restore it before GoRunner starts.
- **Redis:** keep its persistence on. Losing it signs everyone out, but loses no run.
- **Bucket:** versioning or replication. Back it up close in time to the database, or some runs show no data.
- **No file storage:** step data is in the database, so its backup holds it.

On a new server, put the saved `.env` in an install folder of the same version, restore the stores, then run `docker compose up -d`. The check runs first.

**Which installation do the commands back up?**

The one in the folder you run them in. `docker compose` finds that folder’s own containers, so the commands are right even on a server with two installations. Its volumes start with `gorunner_` unless the setup was given another `--project`.

## Related

- [Update](https://docs.gorunner.io/self-host/update): Move to a new version, and go back · 5 min
- [Your own database, Redis and storage](https://docs.gorunner.io/self-host/own-stores): Managed stores instead of the built-in ones · 10 min
- [Settings (.env)](https://docs.gorunner.io/self-host/settings): Every setting, with its default

Source: https://docs.gorunner.io/self-host/backups
