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 acertsfolder next todocker-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 withdocker 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:
- In
docker-compose.yml, delete thecaddyservice (and thecaddy_dataandcaddy_configvolumes). - Publish the
housegrcservice's port 3100 to the proxy only. Replaceexpose: ["3100"]withports: ["127.0.0.1:3100:3100"]when the proxy runs on the same server, or withports: ["3100:3100"]and a firewall rule that admits only the proxy when it does not. Rundocker compose up -d --remove-orphans. - 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; - sendX-Forwarded-Forset to the client's address andX-Forwarded-Protoset tohttps, replacing any values the client sent, and drop anyCf-Connecting-Ipheader 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.