Running Grist on your own computer is pretty easy. Hosting it to share with others requires a few more steps, such as hooking up an authentication method, wrangling certificates, and configuring a reverse proxy. I wanted to show one complete recipe for doing so.
Here is a docker-compose.yml
file that does the following:
- Uses the
letsencrypt
service to get a certificate for your domain. - Runs Grist behind a reverse proxy called traefik.
- Connects Grist to authentication middleware called traefik-forward-auth. You can configure this middleware to perform Google/OpenID oauth based login.
version: '3'
services:
reverse-proxy:
# Use Traefik for routing and certificate handling.
image: traefik:v2.6
command:
- --providers.docker
- --certificatesResolvers.letsencrypt.acme.email=${EMAIL}
- --certificatesResolvers.letsencrypt.acme.storage=/acme/acme.json
- --certificatesResolvers.letsencrypt.acme.tlschallenge=true
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
ports:
- "80:80"
- "443:443"
volumes:
# You may want to put state somewhere other than /tmp :-)
- /tmp/grist/acme:/acme
# Traefik needs docker access when configured via docker labels.
- /var/run/docker.sock:/var/run/docker.sock
traefik-forward-auth:
# Authentication middleware.
# See https://github.com/thomseddon/traefik-forward-auth for
# options for configuring it.
image: thomseddon/traefik-forward-auth:2
environment:
PROVIDERS_GOOGLE_CLIENT_ID: your-google-client-id
PROVIDERS_GOOGLE_CLIENT_SECRET: your-google-client-secret
SECRET: something-random
LOGOUT_REDIRECT: "https://${DOMAIN}/signed-out"
labels:
traefik.http.services.traefik-forward-auth.loadbalancer.server.port: 4181
traefik.http.middlewares.traefik-forward-auth.forwardauth.address: "http://traefik-forward-auth:4181"
traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders: "X-Forwarded-User"
grist:
image: gristlabs/grist
environment:
GRIST_FORWARD_AUTH_HEADER: X-Forwarded-User
GRIST_FORWARD_AUTH_LOGOUT_PATH: _oauth/logout
GRIST_SINGLE_ORG: grist # alternatively, GRIST_ORG_IN_PATH: "true" for multi-team operation
GRIST_DEFAULT_EMAIL: ${EMAIL}
APP_HOME_URL: https://${DOMAIN}
ports:
- "8484:8484"
volumes:
# You may want to put state somewhere other than /tmp :-)
- /tmp/grist/data:/persist
labels:
traefik.http.services.grist.loadbalancer.server.port: 8484
# When logging in, use traefik-forward-auth middleware.
traefik.http.routers.login.rule: Host(`${DOMAIN}`) && PathPrefix(`/auth/login`)
traefik.http.routers.login.middlewares: traefik-forward-auth
traefik.http.routers.login.service: grist
# Comment out each line with "letsencypt" in it if your domain is not publically
# accessible and you want to use a self-signed certificate.
traefik.http.routers.login.tls.certresolver: letsencrypt
# traefik-forward-auth middleware itself has some internal endpoints.
traefik.http.routers.auth.rule: Host(`${DOMAIN}`) && PathPrefix(`/_oauth`)
traefik.http.routers.auth.middlewares: traefik-forward-auth
traefik.http.routers.auth.service: grist
traefik.http.routers.auth.tls.certresolver: letsencrypt
# Otherwise, the middleware is not needed and would prevent
# public shares. Grist will redirect to login when needed.
traefik.http.routers.general.rule: Host(`${DOMAIN}`)
traefik.http.routers.general.service: grist
traefik.http.routers.general.tls.certresolver: letsencrypt
The template expects you to set DOMAIN
and EMAIL
environment variables. The email you set will be used when auto-applying for a certificate, and will also be configured as the initial site owner. If using Google logins, you’ll need to set PROVIDERS_GOOGLE_CLIENT_ID
and PROVIDERS_GOOGLE_CLIENT_SECRET
with your own values, see provider setup documentation.
Once you are satisfied, you can just run docker-compose up
to bring up the containers, and Grist should become available at your domain.
Other tweaks you can do when it is working:
- Change where you want to store data in the volumes sections (probably not
/tmp
like in this template!). - Turn on sandboxing by adding
GRIST_SANDBOX_FLAVOR=gvisor
in the environment section for Grist if you plan on working with untrusted documents.
A lot more authentication options are possible by using Grist’s support for SAML via Authentik, Keycloak, Auth0 etc. There are some notes for Authentik at Grist core multi user docker setup. There is more flexibilty but more opportunities for misconfiguration than this (relatively) short traefik-based template.