Covers both installation methods (the official one-line script and manual Docker Compose), initial configuration, and what you actually get out of running it.
1. What SafeLine Is, Briefly
SafeLine is an open-source Web Application Firewall (WAF) from Chaitin Tech, sitting as a reverse proxy in front of your web apps. Instead of relying purely on regex/signature matching like older WAFs (e.g. ModSecurity), its core detection engine does semantic analysis of requests — looking at the actual structure and intent of a payload rather than just pattern-matching known attack strings. In practice this means fewer false positives and better detection of attack variants that don't match a known signature.
It ships as a Community Edition (free, self-hosted) and a paid Pro tier that unlocks some additional features (see Section 5).
2. Requirements
| Minimum | |
|---|---|
| OS | Linux (this guide: Ubuntu) |
| Architecture | x86_64 (ARM64 supported, but Pro licence required — Community Edition doesn't run on ARM) |
| Docker | v20.10.14+ |
| Docker Compose | v2.0.0+ |
| CPU | 1 core |
| RAM | 1 GB |
| Disk | 5 GB free |
Check your system meets this before starting:
uname -m # architecture
docker version # Docker version (if already installed)
docker compose version # Compose version
cat /proc/cpuinfo | grep "processor" # CPU core count
free -h # memory
df -h # disk space
lscpu | grep ssse3 # confirm SSSE3 instruction support (required)
For anything beyond a toy/test deployment, give it more headroom than the bare minimum — 2 vCPU / 2-4GB RAM is a more realistic comfortable baseline if you're actually proxying live traffic.
3. Method 1 — The Official Install Script (Recommended, Fastest)
This is Chaitin's own automated installer. It handles the Docker install (if missing), directory setup, compose file, and environment config in one go.
Step 1: Run the installer
As root (or with sudo):
bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en
The --en flag sets the installer's language to English. If you want the LTS release track instead of latest, add --lts:
bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en --lts
The script will:
- Install Docker if it isn't already present
- Create the SafeLine data directory (default /data/safeline)
- Download the compose file and generate a .env with sensible defaults, including a randomly generated Postgres password
- Pull images and bring the stack up
Step 2: Get your admin credentials
Once the script finishes, retrieve the auto-generated admin login:
docker exec safeline-mgt resetadmin
This prints the admin username and password to the terminal — copy them somewhere safe immediately, this is the only time they're shown in plain text this way.
Step 3: Log in
Open a browser to:
https://<your-server-ip>:9443
You'll hit a self-signed cert warning on first access — that's expected, SafeLine issues its own cert for the management console. Accept it and log in with the credentials from Step 2.
That's it for a working install. Skip to Section 4 for configuration.
4. Method 2 — Manual Docker Compose Deployment
Use this if you want more visibility/control over what's being deployed, you're integrating it into an existing Compose-based stack, or you just prefer not to run someone else's install script as root (a completely reasonable instinct).
Step 1: Install Docker (skip if already installed)
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
Step 2: Create the SafeLine directory
sudo mkdir -p /data/safeline
cd /data/safeline
(You can use a different path — just be consistent with SAFELINE_DIR in the .env file below.)
Step 3: Download the Compose file
sudo wget "https://waf.chaitin.com/release/latest/compose.yaml"
Step 4: Create and populate the .env file
sudo touch .env
sudo nano .env
Paste in:
SAFELINE_DIR=/data/safeline
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD={your-strong-password-here}
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=chaitin
ARCH_SUFFIX=
RELEASE=
REGION=-g
MGT_PROXY=0
Notes on the fields that actually matter to you:
- POSTGRES_PASSWORD — set this yourself to something strong, don't leave it as a placeholder
- MGT_PORT — the port you'll access the web UI on; change if 9443 clashes with something else on your host
- SUBNET_PREFIX — the internal Docker network range SafeLine's containers use; only worth changing if it collides with an existing network on your host
- ARCH_SUFFIX — leave blank for x86_64; set to -arm if deploying on ARM (and remember: ARM requires a Pro licence, Community Edition won't run)
- RELEASE — leave blank for the latest rolling release, or set to -lts if you want the LTS track for stability over bleeding-edge features
- MGT_PROXY — leave at 0 unless you're putting the management console itself behind another reverse proxy layer
Step 5: Bring it up
sudo docker compose up -d
Step 6: Get admin credentials and log in
Same as Method 1:
sudo docker exec safeline-mgt resetadmin
Then browse to https://<your-server-ip>:9443 and log in.
5. Initial Configuration
Once you're into the dashboard, here's the practical setup order.
5.1 Add your first protected application
Applications → Add Application:
- Website Name — a label for yourself
- Domain — the public domain/hostname this app answers on
- Upstream — the actual backend address SafeLine forwards traffic to once it's passed inspection (e.g. 192.168.1.100:3000)
- SSL — see below
5.2 SSL / certificates
SafeLine terminates SSL itself, so you don't need a separate reverse proxy handling TLS in front of it. Options: - Auto (Let's Encrypt) — SafeLine requests and renews certs automatically, provided the domain correctly resolves to this server and port 80/443 are reachable for the ACME challenge - Custom cert — upload your own if you're using an internal CA, a wildcard cert, or a cert from another provider - Wildcard domains are supported either way
5.3 Protection mode
Three modes, set per-application:
| Mode | Behaviour | When to use |
|---|---|---|
| Monitor | Logs suspicious/matching traffic but doesn't block anything | Rolling out to a new app — run in Monitor first so you can see what would have been blocked before you risk false positives on real traffic |
| Balanced | Blocks clear attacks, tuned for a reasonable false-positive rate | Default for most production use |
| Strict | Maximum detection sensitivity | Higher-risk targets (admin panels, auth endpoints) where you'd rather over-block than under-block — expect to tune exceptions |
Practical tip: don't deploy straight into Strict on a live app. Start in Monitor, watch the logs for a few days, move to Balanced, then only push specific applications to Strict once you've confirmed legitimate traffic isn't getting caught.
5.4 Rate limiting (HTTP Flood settings)
Configurable globally or per-application, with three limiting types: - Access Limiting — general request frequency caps - Attack Limiting — thresholds specifically on requests that match attack patterns (e.g. block an IP for 30 minutes after 5 detected SQLi attempts in 60 seconds) - Error Limiting — caps on repeated error responses (403/404/500), useful for catching scanners/enumeration attempts
Actions available: hard block, or trigger an anti-bot challenge instead of an outright block — useful when you want friction rather than a full lockout for borderline cases.
5.5 Anti-bot / challenge features
- Anti-Bot Challenge — a JavaScript proof-of-work challenge that real browsers solve transparently in the background but headless scrapers and simple scripts fail
- Authentication Challenge — a separate gate (password prompt) you can put in front of specific paths, e.g. an admin panel or staging environment, to hide it from casual scanning even before someone gets to a login form
- Dynamic HTML/JS encryption — obfuscates client-side identifiers per request, making it harder for scrapers and credential-stuffing tools to reliably target form fields
5.6 Geo-blocking
Block by country where your application has no legitimate business outside a specific region — a blunt but effective tool for cutting a large chunk of opportunistic scanning/attack traffic if your user base is genuinely geographically limited.
6. Benefits — What You Actually Get
- Semantic detection over pure signature-matching — better at catching attack variants that don't exactly match a known pattern, generally with fewer false positives than older regex-based WAFs
- Self-hosted, full data control — nothing routes through a third-party edge/CDN; all inspection happens on infrastructure you control
- Free tier is genuinely usable — Community Edition covers core WAF protection, rate limiting, and the dashboard; you're not crippled without Pro
- SSL termination built in — one less moving part; you don't need a separate reverse proxy purely for cert handling
- Virtual waiting room — for legitimate traffic spikes (not just attacks), SafeLine can queue and gradually release users rather than letting the backend fall over
- Real operational dashboard — logging and analytics that are actually usable day-to-day, not just a raw log dump
- Active development — frequent releases; recent changes include per-path rate limiting policies and expanded custom rule matching conditions (response body, full request/response headers)
Worth knowing before you commit
- Origin/jurisdiction — Chaitin Tech is a China-based company; if outbound telemetry/update traffic matters to your threat model, it's worth checking what the container communicates with (a simple
tcpdump/Wireshark capture on the host will show you) - ARM support requires Pro — Community Edition is x86_64 only
- Some features are Pro-gated — verify current gating against SafeLine's pricing page directly, as this has shifted between releases; don't rely on older reviews for what's free today
7. Quick Reference — Useful Commands
# Get/reset admin credentials
docker exec safeline-mgt resetadmin
# Check container status
docker compose ps
# View logs
docker compose logs -f
# Update to latest version (manual Compose method)
cd /data/safeline
mv compose.yaml compose.yaml.old
wget "https://waf.chaitin.com/release/latest/compose.yaml"
docker compose pull
docker compose up -d
# Update via the manager script (works regardless of install method)
bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en
8. Which Method Should You Actually Use?
- Script method — genuinely fine for most homelab/personal use. It's Chaitin's own tooling, it's what most of the write-ups you'll find online use, and it gets you running in under 5 minutes.
- Manual Compose — better if you want to see exactly what's being deployed before it touches your system, you're folding this into an existing Compose-managed stack, or you're the sort of person who reads scripts before piping them into bash (no judgement — that instinct is correct).
Either way you land on the same Docker Compose stack underneath — the script just automates steps 1-6 of the manual method for you.