Skip to main content

Install on Ubuntu 24.04 (VM)

The VM installer sets up a single-node MonoPbx on Ubuntu 24.04 LTS (amd64 or arm64) and nothing else: no Debian, no RHEL. Under the hood it is the Docker Compose production bundle. The installer adds Docker, the secrets, HTTPS, a systemd unit and a self-test around it.

:::warning Placeholder download domain The one-line command uses get.mpbx.ilinaia.com. That domain is a placeholder: no DNS record exists and no release has been published. Until it does, build the bundle yourself (see "Building the bundle") and run the installer with MPBX_BUNDLE_FILE and MPBX_BUNDLE_SHA256 set. :::

# once the download domain exists
curl -fsSL https://get.mpbx.ilinaia.com/install.sh | sudo bash

# today, with a bundle you built
MPBX_BUNDLE_FILE=/path/mpbx-bundle.tar.gz MPBX_BUNDLE_SHA256=<sha256> sudo -E bash install.sh

For most servers the apt package is simpler: it ships this installer and its bundle, and adds Caddy (--front caddy: HTTPS, wss://<domain>/sip, SIP over TLS on 5061).

Never run the installer on a workstation. It refuses anything that is not Ubuntu 24.04, but it still installs packages and writes to /etc and /opt. Try it in a disposable VM first.

:::note Verification status The installer's own tests run from deploy/installer/test. A full install on a disposable Ubuntu 24.04 VM is the owner's manual check (pending). The guide's runnable blocks are checked by site/scripts/check-guides.mjs. :::

What it does​

StepDetail
PreflightUbuntu 24.04, x86_64 or aarch64, systemd, root, 2 CPUs, 4 GB RAM, 20 GiB free under /var/lib, ports 80 and 443 and the web port free, a terminal (to confirm the recovery key), the public IP, and DNS of --domain pointing at that IP.
DockerSkipped if Docker Engine 24+ with Compose 2.24+ already works. Otherwise Docker's official apt repository, and the signing-key fingerprint must match the one pinned in the script or nothing is installed.
BundleDownloads mpbx-bundle.tar.gz and SHA256SUMS, verifies the SHA-256 and installs to /opt/mpbx.
SecretsRuns mpbx init. On a terminal it shows the recovery key once and asks you to re-type one group of it before anything is written. It also prints the single-use setup URL for the first administrator.
Service/etc/systemd/system/mpbx.service (enabled) and the /usr/local/sbin/mpbx-ctl helper.
Self-testmpbx-ctl selftest checks the unit, every container, the API over HTTP and HTTPS, that no database port listens on the host, and that .env is mode 0600.
FirewallPrints the rules to open. It changes no firewall.

Options​

--domain FQDN public name (its A record must point at this server); with --accept-acme-terms enables ACME
--accept-acme-terms accept the ACME CA's subscriber agreement (Let's Encrypt by default)
--acme-email ADDRESS contact for the CA's expiry notices
--acme-directory URL another ACME CA (https only)
--public-ip IP skip the public-IP lookup
--no-tls | --tls do not publish 80/443 | publish them (default)
--http-port PORT plain web/API port (default 8080)
--channel stable|beta|nightly, --version X
--unattended no terminal: the recovery key is printed once to stdout and cannot be confirmed
--yes do not ask "Continue?"

--front caddy puts Caddy on 80/443 in front of mpbx (wss /sip for the web softphone, SIP over TLS on 5061; without --domain the name is <public-ip>.sslip.io), --no-acme never uses ACME, --relay-url URL and --no-relay choose the push relay. --skip-dns-check, --force-bundle, --skip-resource-checks and --docker-only also exist.

Firewall​

PortWhy
80/tcp, 443/tcpACME challenge and redirect; web client, API and WebSocket
5060/udp+tcp, 5061/tcpSIP. The SIP edge role is not available yet, so nothing listens here today.
30000-40000/udpRTP (rtpengine). Without it calls connect but have no audio.
3478 and the relay rangeonly with the turn profile

Never expose 5432, 6379, 8123, 9000 or 22222 (rtpengine's control port has no authentication). The bundle publishes none of them. Docker-published ports bypass ufw.

Day-to-day commands​

sudo mpbx-ctl status
sudo mpbx-ctl logs mpbx
sudo mpbx-ctl selftest
sudo mpbx-ctl restart
sudo mpbx-ctl stop
sudo mpbx-ctl setup-url # a new single-use setup URL; the previous one stops working
sudo mpbx-ctl version

Settings and secrets live in /opt/mpbx/compose/prod/.env. Back this file up together with the Docker volumes (see Backup and restore).

Re-running is safe​

Every step converges. Existing secrets are never regenerated, .env values you changed are kept, and nothing is deleted. A failed install can be started again. Upgrade and rollback (mpbx upgrade) are not built yet: a bundle of a different version is refused unless you pass --force-bundle.

Uninstall​

sudo mpbx-ctl uninstall # asks first; keeps the Docker volumes and .env
sudo mpbx-ctl uninstall --delete-data # also deletes the volumes and /opt/mpbx; you must type this host's name

--yes alone never deletes data. Docker, its apt source and your firewall are never touched. Deleting data also deletes the master key: without a backup and its passphrase it cannot be recovered.

Building the bundle​

From a checkout of the repository, run deploy/installer/build-bundle.sh --version X.Y.Z --images-file images.env --out dist. It produces mpbx-bundle.tar.gz and SHA256SUMS. images.env sets MPBX_IMAGE and MPBX_RTPENGINE_IMAGE. There is no bundle or image signing in v1: integrity rests on HTTPS to the download host, the SHA-256 of the bundle, the pinned Docker key and digest-pinned images.