Installing with Docker

Before release day: the installation files and the image are published when HouseGRC 2.0.0 is released, very soon. This guide describes them as they will be.

HouseGRC is one container image, ghcr.io/kerbe42/housegrc, started with Docker Compose together with a small web server (Caddy) that serves it over HTTPS.

Before you start

  • A 64-bit Linux server or VM with Docker Engine and the Compose plugin. See the system requirements.
  • A DNS name for it, such as grc.example.com, that resolves to the server for everyone who will use it.
  • Ports 80 and 443 free on the server (or an existing reverse proxy; see below).

The files

mkdir housegrc && cd housegrc
curl -fsSLO https://housegrc.com/install/docker-compose.yml
curl -fsSLO https://housegrc.com/install/Caddyfile
curl -fsSL https://housegrc.com/install/env.example -o .env
chmod 600 .env

Settings

Edit .env; each setting is explained in the file. No passwords or keys go in it: HouseGRC generates its encryption keys itself. The ones that matter:

Setting What it is
HOUSEGRC_HOSTNAME The name users type, such as grc.example.com. Passkeys and links use it, so choose it before people enrol.
HOUSEGRC_VERSION The version to run, such as 2.0.0. Change it to upgrade.
HOUSEGRC_TLS How the certificate is obtained: internal (an authority of its own, for trying it out), an email address (a free Let's Encrypt certificate), or the paths of your own certificate and key. See Certificates.

Start it

docker compose up -d
docker compose logs -f housegrc

On its first start HouseGRC creates its databases, generates its encryption keys on the secret volume and loads the framework and regulation catalogues. Once the image is downloaded that takes about half a minute. When it is done it prints

HouseGRC 2.0.0 is ready at https://grc.example.com

with your version and name. Press Ctrl+C to stop following the log; HouseGRC keeps running. Then create the first administrator (it asks for a password):

docker compose exec -u app housegrc python -m housegrc.cli create-superadmin --username admin

Open https:// and your name in a browser, sign in, and set up multi-factor sign-in when it asks.

Certificates

HOUSEGRC_TLS in .env takes one of three forms:

  • internal: Caddy creates its own certificate authority and issues the certificate from it. Nothing has to be reachable from the internet, but browsers warn until they trust that authority. Copy its root certificate out and install it as a trusted root on the machines that use HouseGRC:

docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt housegrc-root.crt

The authority lives in the housegrc_caddy_data volume; if that volume is deleted, a new one is created and must be trusted again.

  • An email address, such as [email protected]: a free certificate from Let's Encrypt, renewed automatically. The name must resolve publicly to this server, and ports 80 and 443 must be reachable from the internet.

  • HOUSEGRC_TLS=/certs/cert.pem /certs/key.pem: your own certificate. Put the certificate (with its chain) and the private key in a certs folder next to docker-compose.yml. Caddy runs without the capability to read other users' files, so make them root's: sudo chown -R root:root certs && sudo chmod 600 certs/key.pem. When you renew them, restart Caddy with docker compose restart caddy.

After changing HOUSEGRC_TLS, run docker compose up -d again.

HouseGRC must be served on the standard HTTPS port, 443: the interface connects back to the server on the address the page came from, without a port.

Behind an existing reverse proxy

If your organisation already has a reverse proxy or load balancer, it can take Caddy's place:

  1. In docker-compose.yml, delete the caddy service (and the caddy_data and caddy_config volumes).
  2. Publish the housegrc service's port 3100 to the proxy only. Replace expose: ["3100"] with ports: ["127.0.0.1:3100:3100"] when the proxy runs on the same server, or with ports: ["3100:3100"] and a firewall rule that admits only the proxy when it does not. Run docker compose up -d --remove-orphans.
  3. Have the proxy: - serve HouseGRC's name (HOUSEGRC_HOSTNAME) over HTTPS on port 443 with your certificate; - pass WebSocket upgrades through: the interface keeps one connection open per browser tab, at /_event, so allow it to stay open for hours; - send X-Forwarded-For set to the client's address and X-Forwarded-Proto set to https, replacing any values the client sent, and drop any Cf-Connecting-Ip header from clients (HouseGRC prefers that header when it is present).

HouseGRC trusts these headers only from private and loopback addresses. If the proxy reaches HouseGRC from any other address, add that address to HOUSEGRC_TRUSTED_PROXY_CIDRS and HOUSEGRC_TRUSTED_PROXIES in .env. If users reach HouseGRC on more than one name, list every https:// address in HOUSEGRC_CORS_ORIGINS. HOUSEGRC_TLS is then unused.

Where your data lives

Three Docker volumes hold everything:

Volume Contents
housegrc_data The encrypted databases
housegrc_evidence Uploaded evidence and documents
housegrc_secret The encryption keys: secret.key for the databases and evidence, mfa.key for multi-factor and single sign-on secrets

Back up all three, and keep the secret volume's backup apart from the others. Without its keys the databases cannot be read, by you or by us; with them, anyone holding the other backups can read everything. See Upgrades and backups.