Skip to content

Building Bifrost

This guide covers building Bifrost from source for various platforms.

SoftwareVersionPurpose
Go1.22+Compiler
Node.js18+Web UI build
npm9+Package manager
MakeanyBuild automation
GitanyVersion control

macOS:

Terminal window
brew install go node git make

Ubuntu/Debian:

Terminal window
sudo apt update
sudo apt install golang nodejs npm git make

Fedora:

Terminal window
sudo dnf install golang nodejs npm git make

Windows (with Chocolatey):

Terminal window
choco install golang nodejs git make
Terminal window
go version # Should show go1.22+
node --version # Should show v18+
npm --version # Should show 9+
make --version
Terminal window
# Clone the repository
git clone https://github.com/rennerdo30/bifrost-proxy.git
cd bifrost-proxy
# Build everything (server + client + web UI)
make build
# Binaries are in bin/
ls bin/
# bifrost-server bifrost-client
Terminal window
# Build both server and client (includes web UI)
make build
# Build server only
make build-server
# Build client only
make build-client
# Build stripped binaries (30-40% smaller, no debug info)
make build-stripped
Terminal window
# Build for all platforms (Linux, macOS, Windows)
make build-all
# Build for specific platform
make build-linux
make build-darwin
make build-windows
Terminal window
# Build for all OpenWrt architectures
make build-openwrt
# Build for MIPS only (big-endian + little-endian)
make build-openwrt-mips
# Build for ARM only (v6, v7, arm64)
make build-openwrt-arm
DirectoryContents
bin/Development binaries (current platform)
dist/Cross-compiled release binaries
VariableDefaultDescription
VERSIONgit tagVersion string embedded in binary
COMMITgit shaCommit hash embedded in binary
CGO_ENABLED0Disable CGO for static binaries

Example with custom version:

Terminal window
VERSION=1.0.0-custom make build

The Makefile uses these Go build flags:

Terminal window
# Standard build
-ldflags "-X .../version.Version=... -X .../version.GitCommit=..."
# Stripped build (smaller binary)
-ldflags "-s -w -X .../version.Version=... -X .../version.GitCommit=..."
  • -s strips the symbol table
  • -w strips DWARF debugging info

If you prefer not to use Make:

Terminal window
# Build web UI first
cd web/server && npm install && npm run build && cd ../..
cd web/client && npm install && npm run build && cd ../..
# Build Go binaries
go build -o bin/bifrost-server ./cmd/server
go build -o bin/bifrost-client ./cmd/client
Terminal window
# Linux AMD64
GOOS=linux GOARCH=amd64 go build -o dist/bifrost-server-linux-amd64 ./cmd/server
# macOS ARM64 (Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o dist/bifrost-server-darwin-arm64 ./cmd/server
# Windows AMD64
GOOS=windows GOARCH=amd64 go build -o dist/bifrost-server-windows-amd64.exe ./cmd/server
# OpenWrt MIPS (with softfloat)
CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat \
go build -ldflags "-s -w" -o dist/bifrost-server-linux-mipsle ./cmd/server
# OpenWrt ARM v7
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 \
go build -ldflags "-s -w" -o dist/bifrost-server-linux-arm7 ./cmd/server
OSArchitectureBinary SuffixNotes
Linuxamd64-linux-amd64Most servers/desktops
Linuxarm64-linux-arm64Raspberry Pi 3+, modern ARM
Linuxarm (v6)-linux-arm6Raspberry Pi 1, Pi Zero
Linuxarm (v7)-linux-arm7Raspberry Pi 2, many routers
Linuxmips-linux-mipsOpenWrt routers (big-endian)
Linuxmipsle-linux-mipsleOpenWrt routers (little-endian)
macOSamd64-darwin-amd64Intel Macs
macOSarm64-darwin-arm64Apple Silicon (M1/M2/M3)
Windowsamd64-windows-amd64.exeMost Windows PCs

To determine your router’s architecture:

Terminal window
# On the router
cat /proc/cpuinfo | head -10
# Or check OpenWrt info
cat /etc/openwrt_release
uname -m
uname -m OutputBinary to Use
mipsbifrost-server-linux-mips
mipselbifrost-server-linux-mipsle
armv6lbifrost-server-linux-arm6
armv7lbifrost-server-linux-arm7
aarch64bifrost-server-linux-arm64-openwrt

The web UI is built with Vite and embedded into the Go binary.

Terminal window
# Install dependencies
make web-install
# Build both UIs
make web-build
# Build server UI only
make web-build-server
# Build client UI only
make web-build-client
# Development server (hot reload)
make web-dev # Server UI
make web-dev-client # Client UI
PathDescription
web/server/Server dashboard UI
web/client/Client debug/traffic UI

Built UI files are copied to:

  • internal/api/server/static/ (server)
  • internal/api/client/static/ (client)

These are embedded using Go’s //go:embed directive.

Terminal window
# Run all tests
make test
# Run tests with coverage
make test-coverage
# Run integration tests (requires more setup)
make test-integration
# View coverage report
open coverage.html
Terminal window
# Run linter
make lint
# Format code
make fmt

Requires golangci-lint:

Terminal window
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
Terminal window
# Build Docker images
make docker-build
# Build and start with docker-compose
make docker-deploy
# Rebuild with no cache
make docker-rebuild-clean

Releases are automated via GitHub Actions:

  1. Nightly builds: Triggered on every push to master/main
  2. Tagged releases: Triggered when a tag like v1.0.0 is pushed
Terminal window
# Tag a release
git tag v1.0.0
git push origin v1.0.0

This triggers:

  1. GoReleaser builds all platforms (including OpenWrt)
  2. Creates GitHub release with binaries
  3. Builds and pushes Docker images
Terminal window
# Install GoReleaser
go install github.com/goreleaser/goreleaser@latest
# Build without releasing (dry run)
goreleaser release --snapshot --clean
# Check dist/ for output
ls dist/

Ensure Go is in your PATH:

Terminal window
export PATH=$PATH:/usr/local/go/bin
export PATH=$PATH:$(go env GOPATH)/bin

Install Node.js:

Terminal window
# macOS
brew install node
# Ubuntu
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

The web UI is embedded at build time. Rebuild to see changes:

Terminal window
make web-build
make build

Use stripped builds:

Terminal window
make build-stripped
# or
make build-openwrt # OpenWrt builds are always stripped

Ensure CGO is disabled for cross-compilation:

Terminal window
CGO_ENABLED=0 GOOS=linux GOARCH=arm go build ...

MIPS build fails with “softfloat required”

Section titled “MIPS build fails with “softfloat required””

Some MIPS routers lack hardware floating-point. Use:

Terminal window
GOMIPS=softfloat go build ...

The make build-openwrt-mips target includes this automatically.

The project includes these workflows:

WorkflowTriggerPurpose
ci.ymlPR, pushTests, linting
nightly.ymlpush to masterNightly builds
release.ymltag v*Official releases
docs.ymldocs changesDocumentation site

For releases:

  • GITHUB_TOKEN (automatic)

For Docker registry (optional):

  • Container registry credentials (uses GHCR by default)

Approximate sizes after stripping:

PlatformServerClient
Linux amd64~15 MB~12 MB
Linux arm64~14 MB~11 MB
OpenWrt MIPS~12 MB~10 MB
OpenWrt ARM7~11 MB~9 MB
macOS arm64~15 MB~12 MB
Windows amd64~16 MB~13 MB

Sizes include embedded web UI (~400KB compressed)