This guide covers Docker. On a cPanel or Linux server, use the server install guide; on a Windows PC, the Windows install guide.

Before you start

You will need three things:

You do not need Node.js. The image carries its own runtime.

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.

Firewall and network access

Docker publishes ports straight past your firewall.

On Linux, Docker writes its own iptables rules, and they are consulted before the ones ufw manages. A container published with -p 3000:3000 is reachable from the internet even while ufw status reports that port as denied.

If anything terminates TLS in front of the container — and on anything internet-facing it should — publish to loopback only. In your compose file, change:

ports:
  - "${GWSB_PORT:-3000}:3000"    # reachable from anywhere

ports:
  - "127.0.0.1:${GWSB_PORT:-3000}:3000"    # reachable only through your proxy

Outbound, the container needs a great deal: Google’s APIs, our licence server, whichever storage destination you have configured — and, up to v0.9613 only, SSH out to any Linux server you protect (Linux server backup was retired in v0.9700). The full list, with the reason for each entry, is on the requirements page.

If you filter outbound traffic by hostname, allow googleusercontent.com as well as googleapis.com — Drive serves the actual file content from there.

Fresh installation

1 Make a directory and put the two files in it. Download them from the download page and rename them:

mkdir gwsbackup && cd gwsbackup

mv ~/Downloads/gwsbackup-docker-0.9610-compose.yml docker-compose.yml
mv ~/Downloads/gwsbackup-docker-0.9610-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. If it is lost, they cannot be recovered — by us or by anyone. Keep a copy of .env somewhere safe and separate from this server, and never change ENCRYPTION_KEY on an install that already holds data.

If the container ever refuses to boot over a missing key, 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 keeps updating a decision you make.

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.

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.