Skip to main content

Services User

services-user (VMID 118, 10.0.0.18) runs ABAIR's user-facing web apps. Each app is its own Docker Compose stack in /opt/apps/<app>/.

Playbookansible/hetzner-main/setup-services-user.yml
App definitionsansible/hetzner-main/services-user-apps/<app>/docker-compose.yml
Make targetssetup-services-user, update-services-user, deploy-services-user-apps, enroll-wazuh-services-user
SecretsDocker Registry Password, Webserver htpasswd admin, and one Secure Note per app that needs a .env

To add an app, see Adding an App.

Apps​

Images are 10.0.0.12:5000/<image>:main from the private registry unless stated otherwise.

App (directory)Public hostnamePort.env from VaultwardenNotes
abair_websiteabair.ie, www.abair.ie, dev.abair.ie3001yesRuns with host networking. A second container, abair_website-preview (tag :preview), serves preview.abair.ie on port 4001.
litreoirlitreoir.abair.ie3002no
fotheidilfotheidil.abair.ie3003noFront end for the Fotheidil subtitling tool. Host networking. Calls the Fotheidil API on Amergin at 192.168.100.2:4040.
mileglornanogmileglornanog.abair.ie3005noImage mile-glor-na-nog. Host networking.
meallanoigemeallanoige.abair.ie3009nomao.abair.ie and meallanóige.abair.ie redirect here.
web_reader_extensionwebreader.abair.ie3010noBack end for the Webreader browser extension.
geabaire-web-editoraac-editor.abair.ie3013no
mao-teacher-portalmao-portal.abair.ie3014yesSends invite emails through smtp.mailbox.org.
leigh-domleighdom.abair.ie3015yesLéigh Dom. Stores its data in a named Docker volume. Uploads are limited to 64 MB. Its .env holds ADMIN_API_TOKEN, for the admin API that CÚL calls.
abair-apiapi.abair.ie/v3/4040noThe legacy v3 API, with its own Redis. Calls synthesis-legacy at 10.0.0.21:8002.
geabaire-apigeabaire-api.abair.ie/v1/, api.geabaire.abair.ie/v1/4041yesHas its own Redis. Board images and icons (./data, ./icons) were copied in by hand and aren't in the repo.
bat-mirialtabat-mirialta.abair.ie8001no
giob-geabgiob-geab.abair.ie8003yesFastAPI plus a Celery worker and scheduler, with a Redis broker. Uses the :latest tag. 3D model assets (./assets) were copied in by hand.

"Host networking" means the container uses the VM's network directly, so its port isn't listed in the compose file. The port shown comes from the nginx config.

How apps are deployed​

make deploy-services-user-apps runs the playbook's apps tag. It doesn't touch the rest of the VM. For each app in the user_apps list, it:

  1. copies services-user-apps/<app>/ to /opt/apps/<app>/;
  2. for apps in user_apps_with_env, fetches the Secure Note <app> .env from Vaultwarden and writes it to /opt/apps/<app>/.env (owner root:deploy, mode 0640);
  3. runs docker compose pull and docker compose up -d.

It deploys every app on each run.

If a .env note is missing, empty, or in a collection you don't belong to, the run stops. That keeps an app from starting with an empty .env. Run eval "$(make unlock-bw)" first.

The copy only adds and overwrites files. A file you delete from the repo stays on the VM until you remove it by hand.

Day-to-day code changes usually don't need this target. Each app's own CI builds and pushes a new image, then runs docker compose pull && docker compose up -d on this VM over SSH as the deploy user. See Adding an App → CI/CD.

note

Only the GitHub runner's key is authorized for deploy on this VM. Apps whose CI runs on the Gitea runner can't deploy here over SSH yet. services-staff authorizes both runners.

Base setup​

make setup-services-user and make update-services-user configure the VM itself:

  • Docker CE, with the private registry 10.0.0.12:5000 allowed as an insecure registry. Docker restarts on every run, which briefly restarts all apps.
  • A deploy user, authorized with the GitHub runner's SSH key (fetched live from docker-build).
  • A registry login for both root and deploy.
  • Grafana Alloy, which ships container logs and host metrics to Secops.
  • UFW (setup only): SSH from anywhere, all ports from the webserver (10.0.0.14), port 3015 from services-staff (10.0.0.19) for CÚL's Léigh Dom page, everything else denied.

Resource history​

  • Memory was raised from 4 GB to 8 GB on 2026-08-17.
  • The disk was grown from 32 GB to 128 GB on 2026-09-21, live (qm resize on the host, then growpart and resize2fs in the guest).