Portainer
On this page
Run Office Sentry as a Portainer stack on a Docker host Portainer manages. You paste one file, set a few environment variables in Portainer, and deploy; Portainer then shows the portal and worker, their logs and a console.
Tested: the stack file, with Docker Compose 5.6: both containers healthy, named volumes and host folders, keys from variables, and the HTTPS profile. Portainer's own screens: not yet. The steps follow Portainer CE 2.2x; if a screen differs, please open an issue.
What you need #
- Portainer CE or Business managing a standalone Docker environment (local socket or the Portainer Agent), on a Linux machine with at least 2 CPUs and 4 GB of memory free for Office Sentry. Not a Swarm environment (why); for a Kubernetes environment see Kubernetes.
- A domain name for the portal, such as
sentry.yourmsp.com, and a way to put HTTPS in front: the stack's own Caddy (when nothing else on the machine uses ports 80 and 443), a proxy you already run (Nginx Proxy Manager, Traefik), or Cloudflare Tunnel.
1. Create the stack #
-
In Portainer, pick the environment, then Stacks → Add stack.
-
Name:
officesentry. -
Build method: Web editor. Paste the whole of
v2/deploy/stack/compose.yaml(on GitHub, open it and use Copy raw file). Don't change it: everything you set goes in the next step.Prefer Portainer to fetch it? Choose Repository instead, with URL
https://github.com/JackD99/OfficeSentry, referencerefs/heads/mainand compose pathv2/deploy/stack/compose.yaml. The release you run is still chosen byOFFICESENTRY_VERSION.
2. Set its environment variables #
Under Environment variables, switch to Advanced mode and paste, with your own values:
OFFICESENTRY_VERSION=2.1.0
OFFICESENTRY_BASE_URL=https://sentry.yourmsp.com
OFFICESENTRY_TIMEZONE=Europe/London
OFFICESENTRY_VERSION is the release to run (an exact
one is safest). Then add the lines for how HTTPS reaches it:
| HTTPS from | Add |
|---|---|
| The stack's own Caddy, which gets a Let's Encrypt certificate (ports 80 and 443 free, DNS pointing here) | COMPOSE_PROFILES=https and OFFICESENTRY_DOMAIN=sentry.yourmsp.com |
| Cloudflare Tunnel (no ports opened) | COMPOSE_PROFILES=tunnel and CLOUDFLARE_TUNNEL_TOKEN=<the tunnel's token> |
| A proxy you already run | nothing here; see Behind your own proxy |
Every other setting in .env.example can be set the same way once it has a line under
x-settings at the top of the stack (copy the pattern of the lines there). Portainer keeps these variables
in its own database, so anyone who can edit the stack in Portainer can read them: limit who has that access.
3. Deploy and create the first admin #
- Press Deploy the stack. Portainer pulls the image and starts
web, thenworkeronce the portal is healthy (a minute or two). Containers shows both as healthy. - If you set
COMPOSE_PROFILESand there's nocaddy(orcloudflared) container, your Portainer doesn't pass it on: open the stack's Editor, delete theprofiles:line under that service, and press Update the stack. - Open Containers → officesentry-web-1 → Logs and find the line starting No admin account yet. Open
its link, choose a username and password, scan the QR code with an authenticator app and save the
recovery codes. Lost the line? Console on the same container, Connect with
/bin/sh, then runpython -m officesentry setup-link. - Carry on from step 6 of First start: the Get started checklist on your home page walks through the app connection and your first client.
Behind your own proxy #
The portal listens on 127.0.0.1:8000 on the Docker host. A proxy installed on the host itself (nginx,
Caddy) can use that address as it is (Securing the portal).
A proxy running in another container (Nginx Proxy Manager, Traefik, SWAG) reaches the portal by name on a
shared Docker network instead. In the stack's Editor, add the network your proxy uses (its name is
under Networks) and attach web to it:
services:
web:
# ...everything already there, plus:
networks: [default, proxy]
networks:
proxy:
external: true
name: npm_default # your proxy's network
then point the proxy at http://officesentry-web-1:8000. In Nginx Proxy Manager: Add Proxy Host,
scheme http, forward hostname officesentry-web-1, port 8000, and on the SSL tab a Let's Encrypt
certificate with Force SSL. Leave OFFICESENTRY_TRUSTED_PROXIES at 1. Sign in, then check
Settings → Activity log shows your own address, not the proxy's.
Keys and backups #
The keys are generated into the officesentry_officesentry-keys volume on first start. Save a copy in your
password manager: Console on officesentry-web-1, then cat /keys/secrets.json
(Where the keys are). To keep them in Portainer instead, set
OFFICESENTRY_SECRET_KEY and OFFICESENTRY_ENCRYPTION_KEYS before the first deploy
(Keys from a secret store).
Portainer doesn't schedule commands, so make the nightly backup with the Docker host's own scheduler
(crontab -e as a user who can run Docker):
45 3 * * * docker exec officesentry-web-1 python -m officesentry backup --keep 14
Copies go to the backups folder in the data volume (on the host,
/var/lib/docker/volumes/officesentry_officesentry-data/_data/backups). Include that folder in whatever
backs up the host, or set OFFICESENTRY_DATA to a host folder owned by user ID 10001 that's already backed up.
Settings → System status shows when the last backup ran and alerts when it fails or is overdue.
To restore one: Stop both containers, then on the Docker host
docker run --rm -v officesentry_officesentry-data:/data -v officesentry_officesentry-keys:/keys \
-e OFFICESENTRY_SECRETS_FILE=/keys/secrets.json ghcr.io/jackd99/officesentry:2.1.0 \
python -m officesentry restore /data/backups/<file>.db.gz
and Start them again (Restoring a backup explains what it does).
Updating #
Read the release notes first (releases), above all
Action required, New Microsoft permissions and Database upgrade. Then open the stack, change
OFFICESENTRY_VERSION, and press Update the stack with Re-pull image and redeploy on. The portal
upgrades the database before the worker starts again. Going back needs the database from before the upgrade
(Rolling back an update).
If it doesn't start #
| You see | Fix |
|---|---|
required variable OFFICESENTRY_BASE_URL is missing a value |
Add OFFICESENTRY_BASE_URL under the stack's environment variables. |
PermissionError: [Errno 1] Operation not permitted: '/data' in the portal's log |
OFFICESENTRY_DATA (or OFFICESENTRY_KEYS) names a host folder user ID 10001 doesn't own: sudo chown 10001 <folder> on the host. |
Bind for 127.0.0.1:8000 failed: port is already allocated |
Another container uses port 8000: set OFFICESENTRY_PORT=127.0.0.1:8001. |
| The worker stays unhealthy | Its log (Containers → officesentry-worker-1 → Logs) says why; Troubleshooting covers the common causes. |
| Signing in doesn't stick | Sign-in only works over HTTPS, by design: open the https:// address, not http://<host>:8000. |