Before you start

You will need three things:

You do not need Node.js. The image carries its own runtime, which is the main reason to choose Docker over the server install: there is no version to check and no dependency to get wrong.

Security first: where to run it

The container publishes the console on a plain HTTP port. That is fine on a machine only you can reach, and not fine facing the internet.

Use an address that cannot be guessed, for the same reason the server install asks for a random subdomain: bots scan the obvious names looking for admin panels.

Fresh installation

1 Make a directory and put the two files in it. Download them from the download page and rename them — the version prefix is there so you can tell releases apart, not because the files need it:

mkdir gwsbackup && cd gwsbackup

mv ~/Downloads/gwsbackup-docker-0.96-compose.yml docker-compose.yml
mv ~/Downloads/gwsbackup-docker-0.96-env.example .env

2 Generate the two secrets and put them into .env:

openssl rand -hex 32 # paste as ENCRYPTION_KEY
openssl rand -base64 32 # paste as NEXTAUTH_SECRET

While you are in there, set NEXTAUTH_URL to the address you will reach the console on. Leave it blank only if that is plain localhost.

3 Start it. The image is pulled for you; there is nothing to build:

docker compose up -d

Check it came up healthy:

docker compose ps

The status column should read Up (healthy) within about half a minute. If it says Restarting, go to Troubleshooting — the logs will name the reason.

4 Finish setup in the browser. Open the console, create your administrator account, and save the recovery key it shows you — it is displayed once. Then paste in your licence key, and follow the in-app wizard to connect your first Google Workspace.

Files you must protect

.env holds ENCRYPTION_KEY, and it is not recoverable.

That key decrypts every stored client credential — service accounts, Drive OAuth tokens, S3 and Azure secrets. If it is lost, those credentials cannot be recovered by us or by anyone, and every client connection has to be set up from scratch. Backups already taken remain in your storage, but the app can no longer reach the accounts that made them.

Keep a copy of .env somewhere safe and separate from this server. Never change ENCRYPTION_KEY on an install that already holds data.

The container refuses to start rather than quietly generating a replacement key, so a mistake here appears as a container that will not boot — not as silent data loss. If you see that refusal, restore the original .env; do not work around it.

Where your data lives

Inside a Docker named volume, not inside the container:

This is why updating does not touch your data: the container is replaced, the volume is not. Your backups are not here at all — they go to the destination you configure, whether that is Google Drive, S3-compatible storage, Azure or a local disk.

If you swap the named volume for a host folder, chown it to uid 1000 first. The container runs as an unprivileged user, and a host directory keeps its own ownership — which surfaces as SQLITE_READONLY, an error that mentions nothing about permissions.

Backing up the databases

Stop the container first. Copying a live SQLite database can produce a file that will not open:

docker compose stop

docker run --rm -v gwsbackup_gwsbackup-data:/data -v "$PWD:/out" \
  alpine tar czf /out/gwsbackup-data.tar.gz -C /data .

docker compose start

The volume name is your directory name plus _gwsbackup-data. Confirm it with docker volume ls.

Updating an existing installation

Set GWSB_VERSION in .env to the new version, then:

docker compose pull
docker compose up -d

Your databases, licence and settings are untouched. Pinning the version is worth doing: it makes updating a decision you make, rather than something that happens the next time the container restarts.

Troubleshooting

Start with the logs. They are almost always explicit:

docker compose logs --tail=50

“REFUSING TO START — Missing required environment”

.env is missing, or the secrets are still blank. See step 2.

“REFUSING TO START — ENCRYPTION_KEY is missing, but this install has a database that already holds data”

The key that encrypted this data is not being supplied. Restore the original .env. Do not generate a new key unless you accept losing every stored credential — the message is the software preventing that, not obstructing you.

SQLITE_READONLY, or permission errors on /app/data

You have replaced the named volume with a host bind mount. Chown the directory to uid 1000, or go back to the named volume.

Connecting a Google Workspace fails, or OAuth never returns

NEXTAUTH_URL is unset or wrong. It must be the address your browser actually uses, including https:// if you are behind a proxy.

Status shows “unhealthy”

The health check simply asks the console for its login page. If it is failing, the app is not serving — the logs will say why.

What we can and cannot do for you

We can help with the application: installing it, connecting a workspace, backups, restores, anything it does or fails to do. Email support@gwsbackup.com and a person reads it.

We cannot administer your Docker host, your reverse proxy or your firewall — we have no access to them and would not want it. If the container starts and the console loads, the rest is yours; if it does not, that is ours, and we would like to hear about it.