Choose a shared application root or the standard FHS layout, then configure systemd and a dedicated unprivileged system user.
This is the multi-page printable view of this section. .
Deployment & Installation
CheeseWAF can be deployed as a system service, containerized workload, or standalone binary across all major platforms. Choose the deployment method that aligns with your infrastructure:
Release Package Matrix & Distribution Strategy
Beginning with stable releases (v0.3.9+), CheeseWAF enforces a server-first distribution model: stable releases prioritize certified Linux server packages accompanied by Sigstore cryptographic signatures and SBOM attestations. Windows and macOS desktop packages are provided as optional operator-side builds.
Pre-compiled production binaries can be downloaded directly from GitHub Releases:
| Release Package | Target Platform & Architecture |
|---|---|
cheesewaf-amd64-linux-*.tar.gz | Linux x86_64 architecture |
cheesewaf-arm64-linux-*.tar.gz | Linux ARM64 architecture |
cheesewaf-loong64-linux-*.tar.gz | Linux LoongArch architecture |
cheesewaf-amd64-darwin-*.tar.gz / .dmg | macOS Intel architecture |
cheesewaf-arm64-darwin-*.tar.gz / .dmg | macOS Apple Silicon architecture |
cheesewaf-amd64-windows-*.exe | Windows x86_64 standalone executable |
cheesewaf-arm64-windows-*.exe | Windows ARM64 standalone executable |
cheesewaf-amd64-windows-*.zip | Windows x86_64 portable ZIP archive |
cheesewaf-arm64-windows-*.zip | Windows ARM64 portable ZIP archive |
cheesewaf-amd64-windows-*-setup.exe | Windows x86_64 NSIS graphical installer |
cheesewaf-arm64-windows-*-setup.exe | Windows ARM64 NSIS graphical installer |
Following installation, proceed to Quick Start to complete system initialization and onboard your first reverse proxy site.
1 - Linux Deployment (systemd)
This guide covers Linux physical servers, cloud instances, and virtual machines. The online installer selects a language, detects the CPU architecture, downloads the latest stable release, verifies its checksum, installs the systemd service when available, and prints the first-setup URLs. Use the offline path when the target host cannot reach GitHub.
1. One-line installation (recommended)
Copy and paste this command. The installer opens an interactive prompt for language selection and then downloads, verifies, and installs the matching server release:
When already running as root, omit sudo:
The script reads language, install-root, and entry-name input from /dev/tty, so interactive answers are not consumed as script source. For unattended provisioning, set the documented CHEESEWAF_* environment variables and invoke the downloaded script; never put passwords or setup tokens in shell arguments or history.
To install a specific stable or beta tag, set CHEESEWAF_RELEASE (the v prefix is optional):
During the interactive flow, choose an application install root after selecting the language. Entering /opt/cheesewaf, for example, places the binary, Web assets, runtime configuration, data, and logs under bin/, web/, config/, data/, and logs/ beneath that root. Press Enter to keep the split FHS layout shown below. The systemd unit remains under /etc/systemd/system unless CHEESEWAF_UNIT_DIR is explicitly overridden.
For automation, set CHEESEWAF_INSTALL_DIR before invoking the installer. Individual CHEESEWAF_PREFIX, CHEESEWAF_WEB_DIR, CHEESEWAF_CONFIG_DIR, CHEESEWAF_DATA_DIR, and CHEESEWAF_LOG_DIR values take precedence for their respective paths:
Install roots must be absolute dedicated directories whose path components contain only ASCII letters, digits, ., _, or -; shared system directories and paths containing shell metacharacters are rejected.
The installer will:
- Ask for 中文 or English and check Linux, architecture, disk space,
curl,tar,sha256sum,awk, andodprerequisites. - Download the selected server archive from GitHub Releases and verify its single matching
SHA256SUMSentry. A failed verification stops before installation or service startup. - Install the binary, Web Console, runtime configuration, and systemd unit, then create the non-login
cheesewafservice account. - Generate an HTTPS management listener, a one-time setup token, and a safe entry path. The entry path accepts ASCII letters and digits only; a random value is generated by default, and a custom value is accepted only when it passes the same validation.
- Start the service when
systemdis available, check the listener and health state, and print the version, architecture, installation paths, service state, public management URL, detected private management URLs, token lifetime, and next steps. Withoutsystemd, the files are installed but the service is reported as not started.
Save the complete setup URL printed at the end. On an interactive terminal the installer prints the public setup URL and the secure-entry URL; it also prints each detected private-address setup URL. In a non-interactive run, secrets are withheld from stdout and stored in the root-only install-secrets.txt receipt; set CHEESEWAF_SHOW_SECRETS=1 only when the output is protected. The token is short-lived and is revoked immediately after first setup. Do not paste the complete URL into tickets, screenshots, shell history, or logs.
2. First setup and public entry
During initialization, open the https:// URL printed by the installer. The setup URL always uses the fixed /setup path:
ONE_TIME_TOKEN is the one-time bootstrap token. The browser reads the token from the URL fragment, clears it from the address bar, and sends it in the X-CheeseWAF-Setup-Token header. The token is never placed in query parameters, cookies, or localStorage.
After setup completes, open https://PUBLIC_IP:9443/SECURITY_ENTRY. The security entry contains ASCII letters and digits only; it is generated by default or accepted as a validated custom value. The entry endpoint signs an access Cookie and redirects to the login page. Keep the setup route and the post-setup security entry as separate paths.
The management plane uses HTTPS and binds publicly by default for this installation path. The installer writes the detected public host to admin.env; set CHEESEWAF_ADMIN_PUBLIC_HOST when the host has no directly assigned public address (for example, behind NAT or a reverse proxy). Restrict security groups, firewalls, and any reverse proxy to trusted administration networks before exposing port 9443 to the Internet. A locally generated certificate may cause a browser warning on first access; replace it with a trusted certificate for production use.
After setup completes, the bootstrap token is invalid. If the URL is lost before an administrator is created, reset it on the host:
Use the new URL printed by the command. The old URL cannot be recovered.
Running the installer again against an existing configuration performs an upgrade. It keeps the existing listener, TLS settings, sites, policies, and security-entry path; choose the same install root or set the same CHEESEWAF_*_DIR overrides so the intended service is upgraded.
3. Verify the installation
Confirm that the version and architecture match the target host and that the expected process owns the management port. After first setup, add the first protected site and configure the data-plane listener from the Console.
Default FHS paths:
| Path | Purpose |
|---|---|
/usr/local/bin/cheesewaf | Main binary |
/usr/local/bin/waf-cli | CLI symlink |
/usr/share/cheesewaf/web | Web Console assets |
/etc/cheesewaf/cheesewaf.yaml | Runtime configuration copy |
/var/lib/cheesewaf | Data, certificates, and bootstrap state |
/var/log/cheesewaf | Access and audit logs |
With CHEESEWAF_INSTALL_DIR=/opt/cheesewaf, the corresponding application paths are /opt/cheesewaf/bin/cheesewaf, /opt/cheesewaf/web, /opt/cheesewaf/config/cheesewaf.yaml, /opt/cheesewaf/data, and /opt/cheesewaf/logs.
4. Offline or manual installation
On a connected machine, download the architecture-specific .tar.gz, SHA256SUMS, and (when publishing signatures) signature files from GitHub Releases, then transfer them to the target host. Verify the files in the download directory, extract the archive, and run the installer:
The offline script still asks for the language and entry path locally, generates the setup token, and starts the service; it does not attempt to download another release. On a host without systemd, copy the binary and web/dist into your process manager’s paths and start the service there. Keep a runtime configuration copy and a dedicated data directory; never edit the tracked configs/cheesewaf.yaml template in place.
Do not use unverified binaries, third-party mirrors, or stale installer scripts. A complete Linux archive contains cheesewaf, Web assets, configuration templates, the systemd unit, and this installer; stop and download the archive again if any item is missing.
2 - Docker Compose Deployment
This guide covers deploying CheeseWAF on containerized infrastructure. The repository provides a hardened Dockerfile and Compose example; the example builds the image locally. Do not treat cheesewaf:dev as a vendor-signed or registry-published image unless you have separately verified the image provenance. The runtime is configured to run as an unprivileged user (UID 10001) with a read-only root filesystem.
Compose Configuration
Reference deploy/docker/docker-compose.yml:
When building locally, ensure the build context points to the root of the CheeseWAF repository so both the frontend (web/) and backend Go modules build successfully.
The sample 8080:8080 mapping publishes the data-plane listener on all Docker host interfaces. Put it behind an intentional firewall/reverse-proxy policy, or bind it to a controlled interface; only the admin mapping is loopback-bound by default.
Launching & Initialization
Start the container daemon and view logs:
On initial startup, the container generates self-signed TLS certificates for the admin API. This Compose file binds the admin port to the Docker host’s loopback interface (127.0.0.1:9443), so open https://127.0.0.1:9443/setup on the Docker host. From another machine, set CHEESEWAF_SSH_TARGET to your SSH target and create a tunnel with ssh -N -L 9443:127.0.0.1:9443 "$CHEESEWAF_SSH_TARGET", then use the same local URL; if you intentionally change the port binding, apply an appropriate access-control policy. You can also run the CLI wizard inside the container:
While first-install setup is pending, the container log never prints the setup token or complete URL. It shows only the base /setup URL, the protected /var/lib/cheesewaf/setup.url path, and an opaque receipt. Read the complete URL from that mode 0600 file within its 10-minute validity period. After setup completes, the token is revoked; expired setup.url files are cleaned up.
Stopping containers with docker compose -f deploy/docker/docker-compose.yml down safely preserves SQLite data, certificates, and log streams inside the named volumes cheesewaf-data and cheesewaf-logs. If storage.postgresql is configured, it receives external access-log records; the Docker volume still contains the management database for the default storage.profile: temporary. The reserved production profile currently fails closed at startup.
3 - Windows Deployment
CheeseWAF offers three distribution options for Windows, each utilizing the identical core engine and protection capabilities:
1. Single-File CLI & Native Windows Service
Designed for rapid testing, automated scripts, or native Windows Service hosting:
Native Windows Service Awareness
cheesewaf serve includes native Windows Service state machine integration (golang.org/x/sys/windows/svc):
- When invoked by the Windows Service Control Manager (SCM), the process automatically identifies service mode, seamlessly handling SCM
StopandShutdownsignals with zero external service wrappers (like NSSM or WinSW). - The default service name is
CheeseWAF.
2. Portable Zip Archive
The portable package bundles default configuration templates and compiled Web Console assets:
- Extract
cheesewaf-amd64-windows-*.zipto your target directory (e.g.,D:\CheeseWAF). - Run terminal setup and start the server:
When first-install setup is pending, the process log shows only the base /setup URL, the protected data\setup.url path, and an opaque receipt. Read the complete URL from the mode 0600 file within its 10-minute validity period. After setup completes, the token is revoked; expired setup.url files are cleaned up.
3. NSIS Graphical Installer (Recommended)
Ideal for workstation or production servers requiring guided installation and Windows Service registration:
- Run the
cheesewaf-amd64-windows-*-setup.exeinstaller (use thearm64variant on Windows ARM64). - Follow the wizard prompts. The installer registers the
CheeseWAFWindows service in manual (start= demand) mode; start or stop it explicitly from the Service Control Manager or withsc.exe. - Upon uninstallation, the
data\directory containing your databases and certificates is retained by default to prevent accidental data loss.
Local Helper Controller (GUI)
cheesewaf-gui is a lightweight browser-based local controller for managing the lifecycle of the underlying service:
- Network Security: Strictly binds only to the local loopback address
127.0.0.1:17943. - Key Features: Service start/stop/restart, status and PID display, direct access to the Web Console, and a shortcut to the configuration directory.
- Process Model: The controller starts the local
cheesewaf serveprocess when requested; it is not a second management backend.
Once started, open http://127.0.0.1:17943/ in your browser to view the local desktop controller dashboard.
4 - macOS Deployment
CheeseWAF supports two primary deployment mechanisms on macOS:
1. DMG Graphical Installer
Ideal for local testing, development, and desktop workstations:
- Download the DMG matching your CPU architecture:
cheesewaf-arm64-darwin-*.dmgfor Apple Silicon (M-series), orcheesewaf-amd64-darwin-*.dmgfor Intel Macs. - Open the DMG image and drag CheeseWAF into your Applications folder.
- Launch CheeseWAF from Launchpad or Spotlight.
Gatekeeper Guidance: A release is signed and notarized only when the build has a Developer ID identity and Apple notarization credentials. The packaging script intentionally falls back to ad-hoc signing without notarization when those credentials are unavailable. Verify the exact downloaded artifact with its published signature metadata before deployment. For an ad-hoc developer build that triggers macOS security prompts, Control-click the app icon, select “Open”, and confirm the prompt.
Upon launching, the DMG application runs a lightweight browser-based local controller bound to loopback at http://127.0.0.1:17943/. It provides process start/stop/restart controls, status monitoring, and shortcuts to the Web Console and configuration directory. Default runtime data is saved under ~/Library/Application Support/CheeseWAF.
2. Command-Line Archive (tar.gz)
Ideal for headless servers, developer terminal workflows, or automated scripts:
If first-install Web setup is still pending, process output shows only the base /setup URL, the protected data/setup.url path, and an opaque receipt. Read the complete URL from the mode 0600 file within its 10-minute validity period. After setup completes, the token is revoked; expired setup.url files are cleaned up.
Once initialized, navigate to http://127.0.0.1:9443/ to log into the Web Console.