Why Grist instead of Google Sheets or Airtable
Google Sheets is a spreadsheet: it stores data flat, calculations are limited to sheet functions, and relations between sheets rely on fragile VLOOKUPs. Airtable solves this with relational bases but at $20 per user per month, the bill adds up fast for an agency or technical team.
Grist combines both worlds: a familiar spreadsheet interface over a real relational database. Each document contains tables with typed columns (text, numeric, date, reference, attachment), explicit relations between tables via reference columns, and Python formulas that run server-side — not in the browser. On your VPS, Grist costs $0 extra per month.
What Grist does that Google Sheets cannot
- Relations between tables: a reference column in
Orderspoints toCustomers— not a breakable VLOOKUP, a real foreign key with autocomplete. - Server-side Python formulas:
import datetime,import re,import uuid— and any pure-Python library. Formulas execute in a server sandbox, not the browser. - Automatic REST API: every document exposes
/api/docs/<id>/tables/<table>/recordswithout configuration. Integrate Grist with n8n, Make or any HTTP client. - Multiple views on the same data: grid, card, chart, calendar, custom widget — each view is filtered and configured independently without duplicating data.
- Per-row, per-column access rules: restrict read or write access to a row based on user attributes — granular enough for multi-tenant documents.
Single-container Docker architecture
Grist deploys as a single gristlabs/grist:latest container that bundles Node.js (server), Python (formula sandbox) and SQLite (document storage). A named volume /persist stores .grist files — one file per document. No external service required: no PostgreSQL, no Redis, no Celery.
One environment variable drives initial authentication: [email protected] automatically logs in the user without SMTP or email verification. For multi-user deployments with real authentication, Grist supports OIDC (GRIST_OIDC_*) — Google Workspace, Authentik, Keycloak.
Deploy Grist on a VPS in 4 steps
Prepare the VPS and Docker
A 1 GB RAM VPS is sufficient. SSH in, install Docker (curl -fsSL https://get.docker.com | sh), create the stack folder: mkdir -p /opt/stacks/grist && cd /opt/stacks/grist.
Create the docker-compose.yml
Define the service from the gristlabs/grist:latest image, mount the /persist volume, expose port 8484, and set a random GRIST_SESSION_SECRET (openssl rand -hex 32). Add [email protected] for automatic access without SMTP.
Launch and verify
Start with docker compose up -d and wait for the Node.js boot (~10 s). Check with curl -sI http://localhost:8484/ — you should get HTTP 200 or a 302 redirect to home. Grist is running.
Create your first document
Open http://your-vps-ip:8484 — Grist connects you directly. Click '+ Add document', define your tables and columns, then explore Python formulas by typing = in a cell. To import existing data: File → Import from file (CSV, Excel, .grist).
Add a reverse proxy and HTTPS
Put Caddy in front of Grist: grist.yourdomain.com { reverse_proxy grist:8484 }. Caddy obtains and renews the Let's Encrypt certificate automatically. Update GRIST_ALLOWED_HOSTS=grist.yourdomain.com and restart the container.
Logging in for the first time
Grist redirects you to a "boot" login screen that asks for an installation key — enter the key provided. You then go through a quick configuration wizard, after which you reach your documents as the administrator ([email protected]).
To automate Grist document backups, mount the /persist/docs/ volume into a Backrest job (also in the ServOrbit catalogue): Backrest snapshots the folder via restic and pushes encrypted increments to S3, Backblaze B2 or SFTP — without stopping Grist. Grist itself keeps a per-document snapshot history (Document menu → History), handy for restoring a previous version without leaving the interface.