Skip to content
Pug Network Docs Open the app

Self-hosting

Self-host the Go build

The Go build is the reference implementation of Pug Network. It is a single static binary, has zero third-party dependencies, embeds all client assets at compile time, and runs on Linux, macOS, Windows, FreeBSD, and OpenBSD. OpenBSD is the recommended target for the strongest security posture.

Why this build, not the JS one?

Quick start (any platform with Go 1.22+)

cd pugnetwork-go
go build -o pugnetwork .
./pugnetwork --port 3000
# → http://localhost:3000

Build a distributable binary

cd pugnetwork-go/build

make build          # local platform
make build-all      # 11 OS/arch combinations → build/dist/
make checksums      # sha256sums.txt for reproducible-build verification
make test           # unit tests + race detector

All targets produce fully static binaries via CGO_ENABLED=0, -trimpath, stripped debug info, and -tags nethttpomithttp2.

Production flags

FlagEnv varPurpose
--portPORTListen port (default 3000).
--tls-certTLS_CERTPath to TLS certificate file.
--tls-keyTLS_KEYPath to TLS private key file.
--allowed-originALLOWED_ORIGINAllowed WebSocket Origin header.
--productionWarn to stderr if TLS is absent.
--versionPrint version and exit.
./pugnetwork \
  --port 443 \
  --tls-cert /etc/pugnetwork/cert.pem \
  --tls-key  /etc/pugnetwork/key.pem \
  --allowed-origin https://chat.example.com \
  --production

OpenBSD (recommended)

On OpenBSD the binary calls pledge("stdio inet") immediately after startup. From that point on, the kernel itself rejects any attempt by the process to write files, exec programs, open new socket types, or access devices. If the binary contains a vulnerability that somehow gets to one of those syscalls, the process is killed with SIGABRT instead of doing the dangerous thing.

cd build
make build-all
make openbsd-tar   # → build/dist/pugnetwork-<ver>-openbsd-amd64.tar.gz

Deploy:

tar -xzf pugnetwork-<ver>-openbsd-amd64.tar.gz -C /tmp
sudo cp /tmp/pugnetwork-openbsd-amd64 /usr/local/bin/pugnetwork
sudo cp /tmp/pugnetwork.rc.d /etc/rc.d/pugnetwork
sudo chmod +x /etc/rc.d/pugnetwork

# Enable in /etc/rc.conf.local:
echo 'pugnetwork_flags="--port 443 --tls-cert /etc/pugnetwork/cert.pem --tls-key /etc/pugnetwork/key.pem --production"' \
  | sudo tee -a /etc/rc.conf.local
echo 'pkg_scripts="pugnetwork"' | sudo tee -a /etc/rc.conf.local

sudo rcctl start pugnetwork

Linux (.deb / .rpm)

Requires nfpm:

make build-all
make deb   # → build/dist/pugnetwork_<ver>_amd64.deb
make rpm   # → build/dist/pugnetwork-<ver>.x86_64.rpm

sudo dpkg -i pugnetwork_<ver>_amd64.deb   # or
sudo rpm  -i pugnetwork-<ver>.x86_64.rpm

Edit /etc/systemd/system/pugnetwork.service to add your TLS paths, then:

sudo systemctl daemon-reload
sudo systemctl enable --now pugnetwork
sudo systemctl status pugnetwork

The systemd unit applies full OS-level sandboxing: DynamicUser, ProtectSystem=strict, NoNewPrivileges, MemoryDenyWriteExecute, SystemCallFilter, and CAP_NET_BIND_SERVICE so it can bind port 443 without root.

macOS / Windows / FreeBSD

Each is a one-liner build (make macos-pkg, make windows-zip, make freebsd-tar) followed by either copying the binary directly or installing the package. See the Go build README in the repository for the full per-platform recipes including code-signing.

Reproducible builds

The combination of -trimpath, CGO_ENABLED=0, and a pinned Go toolchain version produces binaries where the same source plus the same Go version yields the same SHA-256 checksum. This means any third party can clone the repo, run the build, and verify that a published binary corresponds to the source it claims to.

make build-all
make checksums
sha256sum -c build/dist/sha256sums.txt

Dependency verification

go mod graph
# Output: pugnetwork (nothing else)

Zero third-party packages. The entire dependency surface is the Go standard library, maintained by the Go team and covered by the Go security policy.