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.