Skip to content

Add docs/DEPLOY.md: deploying a self-built server binary#3790

Closed
mcfnord wants to merge 2 commits into
jamulussoftware:mainfrom
mcfnord:add-deploy-doc
Closed

Add docs/DEPLOY.md: deploying a self-built server binary#3790
mcfnord wants to merge 2 commits into
jamulussoftware:mainfrom
mcfnord:add-deploy-doc

Conversation

@mcfnord

@mcfnord mcfnord commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Split out of #3789 per review — one new file per PR.

DEPLOY.md covers what happens after COMPILING.md when you put a self-built headless server binary on production hosts: CPU architecture and glibc/libstdc++ matching between build and target machines, ldd verification, running under the shipped linux/debian/jamulus-headless.service unit, UDP receive-buffer tuning, firewall layering (cloud filters in front of host firewalls, JSON-RPC never internet-exposed), and a post-deploy verification checklist.

It is the distillation of operating self-built server binaries across Ubuntu 22.04/24.04/26.04, Oracle Linux, x86-64 and ARM, and sub-1GB-RAM machines. Every rule corresponds to a real outage I have caused or debugged.

Docs only; no code changes.

CHANGELOG: SKIP

🤖 Generated with Claude Code

Covers the step after COMPILING.md: architecture/glibc matching between
build and target hosts, ldd verification, running under the shipped
systemd unit, UDP buffer tuning, firewall layering, and a post-deploy
verification checklist.

Co-Authored-By: Claude Fable 5 <[email protected]>
Comment thread docs/DEPLOY.md
Comment on lines +3 to +8
Author(s):
* The Jamulus Development Team

Licensed under AGPL 3.0 or any later version. See [COPYING](../COPYING) for details.

---

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this is not right - we need the full header.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — full AGPL header now (also applied the same fix to docs/ARCHITECTURE.md in #3791).

Comment thread docs/DEPLOY.md

# Deploying a Jamulus Server

[COMPILING.md](../COMPILING.md) ends when the binary exists. This document covers the step after that: putting a self-built headless server binary on a production host and verifying it actually runs. Most self-inflicted server outages happen in this step, and every rule below corresponds to a real-world failure.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I think we should link the website directly. But I'll need to have a thought on this.

Comment thread docs/DEPLOY.md
## Build for the target, not for the build machine

- **CPU architecture must match.** A binary built on x86-64 will not run on an ARM host (and vice versa) — the service crash-loops with `Exec format error`. Before copying, compare `file ./Jamulus` on the build machine with `uname -m` on the target.
- **Build on the oldest OS release you deploy to.** Binaries depend on the glibc/libstdc++ of the build machine. A binary built on Ubuntu 24.04 fails on 22.04 with `GLIBCXX_3.4.32 not found`, while a 22.04 build runs fine on 24.04 and later. Newer hosts run older binaries; the reverse never holds.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clearly just targeted at AI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's targeted at running a fleet, which AI makes much more realistic. some of my Linux instances are really tiny, and compiling on them is fraught with peril. So I've sorta taught it to build certain binaries in certain places and copy them along when done. All that version-specific gotcha stuff has been very useful in this. still seems like something a human would also want to be aware of.

Comment thread docs/DEPLOY.md

## Run under systemd

Use the unit shipped in [`linux/debian/jamulus-headless.service`](../linux/debian/jamulus-headless.service) as your starting point — it already encodes hard-won defaults (dedicated `jamulus` user, `Nice=-20`, real-time I/O scheduling, `MemorySwapMax=0`, `Restart=on-failure`). Manage the server only through `systemctl`; never kill the process by PID.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a README.md to linux/debian explaining this then (if it doesn't exist yet)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #3799 — one new file, linux/debian/README.md.

Comment thread docs/DEPLOY.md

## Host tuning

- **Enlarge the UDP receive buffer.** Under load, default kernel buffers drop packets, which musicians hear as dropouts. Set in `/etc/sysctl.d/99-jamulus.conf`:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sou you'd use an agent to deploy Jamulus to a machine automatically???

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I run 81 servers on 26 instances. I paste in a single authentication secret and then never visit the Linux instance again.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I'd rather use something deterministic like ansible for this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I'd rather use something deterministic like ansible for this.

Yes - or MicroK8s against a revision controlled deployment state. I would trust an AI Agent any more than I'd trust a human agent. You end believing both when they tell you something is working. If you have to fix it in Git to get it working, it tends to stay working or you know why due to the revision history.

@ann0see

ann0see commented Jul 17, 2026

Copy link
Copy Markdown
Member

Not sure about those tbh. I'd rather add README.md files in the respective folders, link to the webpage or add comments to the files.

@ann0see

ann0see commented Jul 17, 2026

Copy link
Copy Markdown
Member

Even though unrelated: could you run Faible on the whole code base and let it find concurrency bugs especially concerning missing std::atomic booleans. Open an issue with the findings and files only. That would be very much appreciated

Co-Authored-By: Claude Fable 5 <[email protected]>
@ann0see

ann0see commented Jul 18, 2026

Copy link
Copy Markdown
Member

I hope it's ok that I close this. I think that it's better to put the stuff into other files/READMEs. Then on your fork you can use this markdown as you need it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants