BitVoice logoBitVoice

Technology / Operations

Running BitVoice: one program, installers and updates

Operating BitVoice: a single binary, installers for Linux, macOS and Windows, signed updates, Let's Encrypt, Health, SIP trace, metrics and a call generator.

9 min read · 1,933 words

What it means to run a phone system

A phone system is infrastructure, so the day-to-day work is less about features than about keeping it up, knowing when something is wrong, upgrading without dropping calls, and proving to yourself that the hardware can carry the load before real callers arrive. Most phone systems make this harder than it needs to be. A traditional open-source stack is several programs (a SIP server, a media server, a database, a web front end) that have to be installed, matched in version, and configured in files that only an expert reads; an upgrade means lining all of them up again, and a mistake can leave the system down.

The approach BitVoice takes is to be one program. Everything (the SIP stack, the media engine, WebRTC, the web interface, the metrics, the trace) is in a single binary with no outside runtime. That changes what operating it means. Installing is downloading one file and running it; upgrading is replacing one file; monitoring is scraping one endpoint; and there is one place, the Health page, that says whether the system is ready for calls. A concrete example: on a laptop you double-click the binary and a browser opens on a setup wizard; a few minutes later a phone rings. On a server, one command installs it as a service that starts by itself.

Behind that simplicity are the things real operations need: safe upgrades that can be undone, encryption certificates that renew themselves, metrics a monitoring system can read, a live view of the SIP messages for when something fails, and a way to measure capacity honestly rather than guess it.

Where it usually goes wrong

The upgrade is where phone systems bite. A new version is installed in place, it fails to start, and now the system is down with no quick way back. Or it is upgraded while calls are up and drops them. Signed releases are meant to stop a tampered or wrong file being installed, but only if the system actually checks the signature, and many do not.

Certificates expire, quietly, and one morning phones will not register over TLS because the certificate ran out at the weekend. Monitoring is bolted on late, if at all, so the first sign of trouble is a user complaint rather than an alert. And capacity is usually a guess: a vendor's "supports 500 calls" means little without knowing the codec, the conversion, the recording and the network, so systems are either over-bought or fall over under real load.

The subtler trap is knowing whether the system is healthy at all. "The web interface loads" is not the same as "it can place a 911 call," and the checks that matter (an emergency route exists, a trunk is registered, a certificate is valid, the disk has room) are exactly the ones that are easy to forget until they fail.

How BitVoice does it

One program. BitVoice is a single binary, pure Go with no C libraries, so it runs on any Linux including Alpine and distroless images, on macOS and on Windows. Its data is one SQLite file plus the recordings and voicemail as sound files, or a PostgreSQL database for a cluster.

Installers. One command installs it as a service that starts by itself. On Linux and macOS, curl -fsSL https://raw.githubusercontent.com/BioDream-LLC/bitvoice/main/deploy/install.sh | sh; on Windows, irm https://raw.githubusercontent.com/BioDream-LLC/bitvoice/main/deploy/install.ps1 | iex. The script downloads the right release for the machine, checks it against the release's SHA-256 sums and BioDream's release signature with OpenSSL 3, and installs it: on Linux as a systemd service with a bitvoice user and the firewall opened for the web, SIP and media ports; on macOS under caffeinate so the Mac does not sleep and stop answering calls; on Windows as a startup task with a firewall rule. Running the command again upgrades; --uninstall removes the program and keeps the data, --purge removes the data too. The whole thing is checked in CI on Linux, macOS and Windows on every change.

Signed updates with go back. Updating is one click and safe. On Updates you upload the new program and its .sig signature; by default BitVoice waits until no calls are in progress (or installs at once if you choose), installs beside the old version, and restarts. The version you left is kept, so Go back returns to it in one click, and a new version that fails to start twice or does not stay up for a minute is replaced by the previous one automatically. From v0.1.3 every release carries BioDream's release key and such a build installs only programs signed with that key: an unsigned file, one signed by anyone else, or one changed by a single byte is refused with "the signature does not match." In a cluster, calls in progress are handed to another server and carry on.

Let's Encrypt built in. BitVoice starts with a self-signed certificate that browsers warn about. For a server with a public name, Settings → Certificate → Let's Encrypt gets a free certificate, uses it at once for the web interface, SIP over TLS and Teams, and renews it about thirty days before it ends. It proves the names with http-01 (a request to port 80, which BitVoice can answer itself) or tls-alpn-01 (for a web interface on port 443), and Test the names asks each name over the internet, as Let's Encrypt will, and says whether it reached BitVoice, reached something else, or is not in DNS. The status line says when it was issued, when it renews and, if it failed, why. The ACME client is BitVoice's own.

Health. The Health page says whether the system is ready for calls and, if not, what to do, with the emergency checks always first: can emergency calls get out, which extensions have no emergency location, is SIP listening, which phones are not connected, are the trunks registered, do menus have prompts, is the time zone set, is there disk room, when does the TLS certificate run out, can the key vaults be read, and in a cluster is each server running. Problems are coloured: red stops calls, amber should be looked at, grey is information. Each line links to the screen where it is fixed.

SIP trace. The SIP trace shows the messages BitVoice sends and receives, live, and is the first place to look when a phone will not register or a call fails, and what a provider's support desk asks for. It keeps the last 2,000 messages in memory, nothing written to disk, with a filter by number, address or Call-ID, and a message chosen shows the whole call flow between the phone, BitVoice and the provider. The chapter lists what common answers mean (a REGISTER answered 401 then nothing is the wrong password; a 488 is no codec in common). Only people signed in to the server see it, and hosted organisations never do.

Metrics. Prometheus scrapes /metrics with an API token as its bearer credential, reading calls in progress by state, calls ended by outcome, talk time, phones registered, each trunk's state and round trip, callers waiting and agents per queue, packets received and lost, a histogram of MOS, and callbacks booked. The same measurements can be pushed to an OpenTelemetry collector over OTLP/HTTP every minute, and a ready-made Grafana dashboard downloads from the settings. For monitoring systems that speak SNMP (Zabbix, PRTG, LibreNMS, Nagios, SolarWinds), an SNMPv2c agent answers GET, GETNEXT and GETBULK from the networks you list, serving the standard system group and BitVoice's own values under a base OID, with a downloadable BITVOICE-MIB and SNMPv2 traps on a trunk going down, an emergency call, or a cluster server going quiet. Call records can also go to syslog, a daily CSV with Asterisk's Master.csv columns, or a PostgreSQL table with Asterisk's cdr columns, for the reporting and billing tools built for Asterisk.

The call generator and measured capacity. The call generator (on the Call generator page) places real calls with real audio into BitVoice from the same computer, to measure what the hardware carries and to check after a change that calls still go where they should. You set the number to call, how many calls, how many at once (up to 2,000), how fast they start and how long each lasts, and it reports answered and failed calls with reasons, the answer time, the audio lost, an audio score (MOS), and a chart of the load over time. It only calls numbers inside BitVoice, never trunks or emergency numbers, so a test can never cost money or reach 911.

The published capacity comes from this generator. On a 16-vCPU Amazon EC2 c7i.4xlarge, with the media port range widened in Settings, BitVoice carried 2,000 calls at once with no loss, MOS 4.41, about ten of the sixteen vCPUs busy and 380 MB of memory, and 2,000 is the generator's ceiling rather than BitVoice's. Smaller machines were measured too: 200 calls at once on a c7g.large, a c7i.large, a t4g.small, an Apple M4 and the public demo's Lightsail nano, every run with all calls answered, no loss and MOS 4.41. Because the generator's own callers and answerers run in the same process, each call is carried three times over, so the PBX alone needs less. Your numbers depend on the codec, conversion, recording and network, which is why the right answer is to run the generator on your own server before going live.

Why BitVoice fits

One binary means one thing to install, upgrade and monitor, with no version-matching across several daemons. Every operational task is in the web interface or one command: the installer, the Updates page with go-back, the Health page, the SIP trace, the metrics settings, the call generator. Updates are signed by BioDream and the check is on by default in release builds, so a tampered file is refused rather than trusted. Let's Encrypt and the ACME client are built in, so certificates renew themselves. The cryptography and the metrics, trace and SNMP are all BitVoice's own code, with the cloud integrations using BitVoice's own SigV4 and Entra token code rather than a cloud SDK. And it is Apache-2.0 and free, so none of this is behind a paid operations tier.

What has been tested, and what has not

Much of this is rated Field-tested in the maturity table. The one-command installer has run on Ubuntu 24.04 (x86 and Arm), Debian 12, Amazon Linux 2023, Windows Server 2022 and macOS, each coming back by itself after a reboot; the Windows run found and fixed a health-check bug under Windows PowerShell 5.1. Capacity is measured on real EC2 machines and the demo nano, with the 2,000-call figure on the c7i.4xlarge. Let's Encrypt issues and renews the public demo's certificate, a real issuance. SNMP has been checked against net-snmp's snmpwalk and snmptrapd, and archiving to S3 and reading a secret from AWS Secrets Manager against real AWS. Machine images built by deploy/cloud/build-images.sh from Ubuntu 24.04 start fresh on EC2, and deploy/terraform has been driven with OpenTofu 1.13 through create, change, no-drift and destroy; Azure images are not yet tried. Prometheus and OpenTelemetry are served by BitVoice's own code and read by its tests. The honest caveat throughout is that "field-tested" means real machines and real networks on EC2 and the internet, not every third-party monitoring product or cloud; BioDream LLC also has no SNMP enterprise number yet, so the default base OID sits in Net-SNMP's experimental space.

Read more