lewlew-glitch/qm_companion

Self-hosted companion for Quartermaster, with Docker management, service discovery and secure mobile pairing.

JavaScript

40

22 commits

updated Oct 6, 2026

See the code

See what people are saying

SourceMessageScoreDate

Quartermaster - 64 connections under one app (r/coolgithubprojects)

Hi all, First time posting here, so a quick intro, I'm the developer of Quartermaster (QM), an app for managing your self hosted stack from your iPhone, iPad, Mac and Apple TV. QM launched on 3 July and it's been non-stop since. The Discord has grown to 700+ members and I can't thank the community…

1

Oct 6, 2026

README

Quartermaster Companion

Quartermaster Companion is a self-hosted web application for the Quartermaster phone app. It discovers supported services, prepares encrypted one-time setup transfers, and provides an authenticated view of Docker and service status.

The standard setup transfer does not route app traffic through Companion. After setup, Quartermaster connects directly to the local and away addresses saved for each service. An optional mobile profile adds a persistent, certificate-pinned HTTPS connection for Companion's Docker overview.

Features

  • Discovers multiple service instances from approved config files and Docker.
  • Transfers service addresses and API keys through a short-lived encrypted setup package.
  • Shows containers, stacks, images, volumes, networks, events, logs, and resource use.
  • Provides optional Docker lifecycle controls, image operations, Compose deployment, scheduled jobs, and an in-container shell.
  • Stores credentials in authenticated encrypted state.
  • Sends alerts from your services, with your own wording, to your phone.
  • Supports one owner account, two-factor authentication, session revocation, and recovery codes.
  • Runs without telemetry or a hosted account dependency.

Screenshots

Dashboard overview

Live monitoringCompose stacks
Dashboard live monitoringCompose stack management

Unraid

Community Apps uses separate qm-socket-proxy and qm-companion entries so the Docker socket is not mounted into the main application. Create the dedicated qm-companion Docker network first, then install the proxy and Companion on it with the same proxy key. See Unraid for the complete setup and Docker access settings.

Quick install

Clone the complete repository and edit docker-compose.example.yml before starting it:

git clone https://github.com/lewlew-glitch/qm_companion.git
cd qm_companion

Set the published address for port 8787, set QM_HOST, and replace the example service config paths with paths from this server. Mount individual config files only, not an app-data parent directory.

For a new installation, create separate secrets in the gitignored .env file. Existing installations must keep their current .env and SECRET_KEY; skip this block during an upgrade.

if [ -e .env ]; then
  printf 'Refusing to replace existing .env\n' >&2
  false
else
  umask 077
  {
    printf 'SECRET_KEY=%s\n' "$(openssl rand -hex 32)"
    printf 'QM_PROXY_KEY=%s\n' "$(openssl rand -hex 32)"
  } > .env
  chmod 600 .env
fi

Check the values without printing them:

(
  set -a
  . ./.env
  set +a
  test "${#SECRET_KEY}" -eq 64 &&
    test "${#QM_PROXY_KEY}" -ge 32 &&
    test "$SECRET_KEY" != "$QM_PROXY_KEY"
) && docker compose -f docker-compose.example.yml config --quiet

Start the recommended read-only profile:

docker compose -f docker-compose.example.yml up -d --build

Open http://<server-address>:8787 and claim the owner account. If SETUP_TOKEN is not configured, the first-run token is written to the Companion log while the installation has no owner:

docker compose -f docker-compose.example.yml logs companion

Use a trusted private network for plain HTTP. Put Companion behind a trusted HTTPS reverse proxy before exposing the panel beyond that network.

Saltbox installations can use the supplied Traefik overlay; see Saltbox.

Updates

A notice above Sign out links to a newer Companion release when one is available. See Updating Companion for Compose, container-manager and release-check settings.

Docker access profiles

The Compose profile sets the maximum Docker access available to Companion:

ProfileCompose commandInstalled maximum
Read onlydocker compose -f docker-compose.example.yml up -d --buildDiscovery, status, and logs
Managementdocker compose -f docker-compose.example.yml -f docker-compose.management.yml up -d --buildDocker writes without container exec
Management + shelldocker compose -f docker-compose.example.yml -f docker-compose.shell.yml up -d --buildDocker writes and container exec

Every explicit profile starts with the active mode set to Read only. The owner can raise it from Docker access up to the installed maximum. Management and Management + shell grant broad Docker authority to the Companion process even while the active application mode is lower. Use the Read only profile when Docker writes are not required.

Keep optional Compose files in the same order whenever the installation is recreated. If the mobile profile is used, place docker-compose.mobile.yml after every file that changes ports.

See Docker access for the permission model, proxy limits, and deployment settings.

Pairing

For a standard setup transfer:

  1. Sign in and open Set up.
  2. Review each service's local address and optional away address.
  3. Create the transfer, scan it in Quartermaster, and enter the separately displayed setup code.

The transfer expires after three minutes and is consumed after use. A downloaded .qmcompanion file consumes the same transfer as the QR code. Treat either form, together with its setup code, as sensitive until it expires or is consumed.

Uptime Kuma, PeaNUT and Pulsarr connections require Quartermaster 1.3 or later. They start unselected in Set up; update the app before selecting them. Transfers containing only the previously supported services keep the existing format.

  • Uptime Kuma accepts an optional metrics API key from Settings, API Keys. Leave it empty for metrics with authentication disabled, or complete authentication in Quartermaster.
  • PeaNUT transfers its addresses without a password. Enter its Basic username and password in Quartermaster when PeaNUT authentication is enabled. Its Homepage widget key is a UPS name and is never imported as an API key.
  • Pulsarr accepts a dedicated API key from Utilities, API Keys. Without a supplied key, its connection is included disabled until credentials are entered.

These three Marketplace entries connect to existing installations; Companion does not provide deployment starters for them. Port-only discovery needs a product signature, so authenticated PeaNUT may require Docker discovery or manual setup in the app.

The optional direct app connection uses the mobile Compose profile and HTTPS port 8788. After deploying it, open Devices, create a pairing key or QR code, and compare the five words shown by Companion and the phone before approval. The connection is bound to one configured HTTPS origin.

See Mobile connections for address setup, pairing details, and deployment checks.

Security warning

Companion handles service credentials and can be granted host-level Docker control. Protect the owner account, .env, the full data volume, and any browser session with access to the panel. Keep SECRET_KEY unchanged across upgrades; losing it makes stored credentials unreadable.

Docker inspection can expose container metadata, mounts, network layout, and credentials stored in environment variables. A read-only file mount still allows Companion to read the mounted file. Grant only the access and mounts needed for this installation.

Read Security model before exposing the panel or enabling Docker writes. Report vulnerabilities through SECURITY.md.

Documentation

Development and verification

Node.js 24 or newer is required.

npm ci
npm test
node verify.mjs

Against an initialized running instance, prove_secure.mjs checks setup and authentication boundaries:

node prove_secure.mjs
QM_SESSION=<current-qm_sess-value> node prove_secure.mjs

Docker writes, registry behavior, reverse-proxy buffering, and NAS-specific permissions should also be tested in the target environment.

License

Quartermaster Companion is licensed under the MIT License. Bundled fonts and third-party service artwork retain their own licenses and trademark terms; see THIRD_PARTY_NOTICES.md.

lewlew-glitch/qm_companion

Self-hosted companion for Quartermaster, with Docker management, service discovery and secure mobile pairing.

JavaScript

40

22 commits

updated Oct 6, 2026

See the code

See what people are saying

SourceMessageScoreDate

Quartermaster - 64 connections under one app (r/coolgithubprojects)

Hi all, First time posting here, so a quick intro, I'm the developer of Quartermaster (QM), an app for managing your self hosted stack from your iPhone, iPad, Mac and Apple TV. QM launched on 3 July and it's been non-stop since. The Discord has grown to 700+ members and I can't thank the community…

1

Oct 6, 2026

README

Quartermaster Companion

Quartermaster Companion is a self-hosted web application for the Quartermaster phone app. It discovers supported services, prepares encrypted one-time setup transfers, and provides an authenticated view of Docker and service status.

The standard setup transfer does not route app traffic through Companion. After setup, Quartermaster connects directly to the local and away addresses saved for each service. An optional mobile profile adds a persistent, certificate-pinned HTTPS connection for Companion's Docker overview.

Features

  • Discovers multiple service instances from approved config files and Docker.
  • Transfers service addresses and API keys through a short-lived encrypted setup package.
  • Shows containers, stacks, images, volumes, networks, events, logs, and resource use.
  • Provides optional Docker lifecycle controls, image operations, Compose deployment, scheduled jobs, and an in-container shell.
  • Stores credentials in authenticated encrypted state.
  • Sends alerts from your services, with your own wording, to your phone.
  • Supports one owner account, two-factor authentication, session revocation, and recovery codes.
  • Runs without telemetry or a hosted account dependency.

Screenshots

Dashboard overview

Live monitoringCompose stacks
Dashboard live monitoringCompose stack management

Unraid

Community Apps uses separate qm-socket-proxy and qm-companion entries so the Docker socket is not mounted into the main application. Create the dedicated qm-companion Docker network first, then install the proxy and Companion on it with the same proxy key. See Unraid for the complete setup and Docker access settings.

Quick install

Clone the complete repository and edit docker-compose.example.yml before starting it:

git clone https://github.com/lewlew-glitch/qm_companion.git
cd qm_companion

Set the published address for port 8787, set QM_HOST, and replace the example service config paths with paths from this server. Mount individual config files only, not an app-data parent directory.

For a new installation, create separate secrets in the gitignored .env file. Existing installations must keep their current .env and SECRET_KEY; skip this block during an upgrade.

if [ -e .env ]; then
  printf 'Refusing to replace existing .env\n' >&2
  false
else
  umask 077
  {
    printf 'SECRET_KEY=%s\n' "$(openssl rand -hex 32)"
    printf 'QM_PROXY_KEY=%s\n' "$(openssl rand -hex 32)"
  } > .env
  chmod 600 .env
fi

Check the values without printing them:

(
  set -a
  . ./.env
  set +a
  test "${#SECRET_KEY}" -eq 64 &&
    test "${#QM_PROXY_KEY}" -ge 32 &&
    test "$SECRET_KEY" != "$QM_PROXY_KEY"
) && docker compose -f docker-compose.example.yml config --quiet

Start the recommended read-only profile:

docker compose -f docker-compose.example.yml up -d --build

Open http://<server-address>:8787 and claim the owner account. If SETUP_TOKEN is not configured, the first-run token is written to the Companion log while the installation has no owner:

docker compose -f docker-compose.example.yml logs companion

Use a trusted private network for plain HTTP. Put Companion behind a trusted HTTPS reverse proxy before exposing the panel beyond that network.

Saltbox installations can use the supplied Traefik overlay; see Saltbox.

Updates

A notice above Sign out links to a newer Companion release when one is available. See Updating Companion for Compose, container-manager and release-check settings.

Docker access profiles

The Compose profile sets the maximum Docker access available to Companion:

ProfileCompose commandInstalled maximum
Read onlydocker compose -f docker-compose.example.yml up -d --buildDiscovery, status, and logs
Managementdocker compose -f docker-compose.example.yml -f docker-compose.management.yml up -d --buildDocker writes without container exec
Management + shelldocker compose -f docker-compose.example.yml -f docker-compose.shell.yml up -d --buildDocker writes and container exec

Every explicit profile starts with the active mode set to Read only. The owner can raise it from Docker access up to the installed maximum. Management and Management + shell grant broad Docker authority to the Companion process even while the active application mode is lower. Use the Read only profile when Docker writes are not required.

Keep optional Compose files in the same order whenever the installation is recreated. If the mobile profile is used, place docker-compose.mobile.yml after every file that changes ports.

See Docker access for the permission model, proxy limits, and deployment settings.

Pairing

For a standard setup transfer:

  1. Sign in and open Set up.
  2. Review each service's local address and optional away address.
  3. Create the transfer, scan it in Quartermaster, and enter the separately displayed setup code.

The transfer expires after three minutes and is consumed after use. A downloaded .qmcompanion file consumes the same transfer as the QR code. Treat either form, together with its setup code, as sensitive until it expires or is consumed.

Uptime Kuma, PeaNUT and Pulsarr connections require Quartermaster 1.3 or later. They start unselected in Set up; update the app before selecting them. Transfers containing only the previously supported services keep the existing format.

  • Uptime Kuma accepts an optional metrics API key from Settings, API Keys. Leave it empty for metrics with authentication disabled, or complete authentication in Quartermaster.
  • PeaNUT transfers its addresses without a password. Enter its Basic username and password in Quartermaster when PeaNUT authentication is enabled. Its Homepage widget key is a UPS name and is never imported as an API key.
  • Pulsarr accepts a dedicated API key from Utilities, API Keys. Without a supplied key, its connection is included disabled until credentials are entered.

These three Marketplace entries connect to existing installations; Companion does not provide deployment starters for them. Port-only discovery needs a product signature, so authenticated PeaNUT may require Docker discovery or manual setup in the app.

The optional direct app connection uses the mobile Compose profile and HTTPS port 8788. After deploying it, open Devices, create a pairing key or QR code, and compare the five words shown by Companion and the phone before approval. The connection is bound to one configured HTTPS origin.

See Mobile connections for address setup, pairing details, and deployment checks.

Security warning

Companion handles service credentials and can be granted host-level Docker control. Protect the owner account, .env, the full data volume, and any browser session with access to the panel. Keep SECRET_KEY unchanged across upgrades; losing it makes stored credentials unreadable.

Docker inspection can expose container metadata, mounts, network layout, and credentials stored in environment variables. A read-only file mount still allows Companion to read the mounted file. Grant only the access and mounts needed for this installation.

Read Security model before exposing the panel or enabling Docker writes. Report vulnerabilities through SECURITY.md.

Documentation

Development and verification

Node.js 24 or newer is required.

npm ci
npm test
node verify.mjs

Against an initialized running instance, prove_secure.mjs checks setup and authentication boundaries:

node prove_secure.mjs
QM_SESSION=<current-qm_sess-value> node prove_secure.mjs

Docker writes, registry behavior, reverse-proxy buffering, and NAS-specific permissions should also be tested in the target environment.

License

Quartermaster Companion is licensed under the MIT License. Bundled fonts and third-party service artwork retain their own licenses and trademark terms; see THIRD_PARTY_NOTICES.md.