SafeLine is a self-hosted web application firewall that filters and monitors HTTP traffic between a web application and the Internet, blocking attacks such as SQL injection, XSS, and path traversal (https://docs.waf.chaitin.com/en/home). A manual deploy is controlled by two files inside a working directory: compose.yaml, which defines the services, and .env, which supplies the values those services read at startup. Preparing the environment variables before the first docker compose up -d avoids two common failure modes: a service that cannot start because a required token is missing, and a deployment that uses a weak or default secret. This guide follows the official deployment document (https://docs.waf.chaitin.com/en/GetStarted/Deploy) step by step.

1. Check the server prerequisites

The official guide lists these minimum requirements: Linux, an x86_64 or arm64 instruction architecture, Docker 20.10.14 or later, Docker Compose 2.0.0 or later, and 1 core CPU, 1 GB memory, and 5 GB disk. The CPU must also support the ssse3 instruction. Confirm them with:

uname -m docker version docker compose version cat /proc/cpuinfo | grep "processor" free -h df -h lscpu | grep ssse3 

2. Install Docker when missing

If Docker is not present, install the latest version:

curl -sSL "https://get.docker.com/" | bash 

3. Create the SafeLine directory

Create the directory that SafeLine uses for configuration and data, ensuring at least 5 GB of disk space:

mkdir -p "/data/safeline" cd "/data/safeline" 

4. Download the compose script

wget "https://waf.chaitin.com/release/latest/compose.yaml" 

5. Create the .env file

touch ".env" 

6. Fill in the base variables

Write these values into .env, replacing {postgres-password} with a database initialization password:

SAFELINE_DIR=/data/safeline IMAGE_TAG=latest MGT_PORT=9443 POSTGRES_PASSWORD={postgres-password} SUBNET_PREFIX=172.22.222 IMAGE_PREFIX=chaitin ARCH_SUFFIX= RELEASE= REGION=-g MGT_PROXY=0 POSTGRES_IMAGE=chaitin/safeline-postgres:15.18 DETECTOR_MGMT_TOKEN=<64-char hex> MGT_INTERNAL_TOKEN=<64-char hex> DETECTOR_AES_KEY=<16 alphanumeric characters> DETECTOR_MGMT_AUTH=on DETECTOR_UPDATE_VERIFY=on DETECTOR_UPDATE_PUBLIC_KEY= 

According to the guide, SAFELINE_DIR sets the data directory, IMAGE_TAG selects the SafeLine version, MGT_PORT is the web console port, POSTGRES_PASSWORD is the Postgres initialization password, SUBNET_PREFIX is the internal network communication address prefix, IMAGE_PREFIX is the mirror repository prefix, ARCH_SUFFIX is set to -arm for ARM servers, RELEASE is set to -lts for the LTS version, and MGT_PROXY is the number of console proxy layers, defaulting to 0 with no proxy configured.

7. Generate the secrets and tighten permissions

Generate random values for the three secret fields and write them into .env:

DETECTOR_MGMT_TOKEN=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \n') MGT_INTERNAL_TOKEN=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \n') DETECTOR_AES_KEY=$(LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16) set_env() { key=$1 value=$2 if grep -q "^${key}=" .env; then sed -i "s|^${key}=.*|${key}=${value}|" .env else printf '%s=%s\n' "$key" "$value" >> .env fi } set_env DETECTOR_MGMT_TOKEN "$DETECTOR_MGMT_TOKEN" set_env MGT_INTERNAL_TOKEN "$MGT_INTERNAL_TOKEN" set_env DETECTOR_AES_KEY "$DETECTOR_AES_KEY" chmod 600 .env 

The two 64-character hex tokens and the 16-character AES key are generated from /dev/urandom, then chmod 600 .env restricts the file to its owner.

8. Adjust for ARM or LTS

On an ARM server, change ARCH_SUFFIX to -arm and set POSTGRES_IMAGE=chaitin/safeline-postgres-arm:15.18. The guide notes that SafeLine installed on ARM requires a Pro license and that the Personal Edition is not supported on ARM. To install the LTS version, set RELEASE=-lts; the LTS version is no longer maintained starting from 9.1.0-LTS (14 August 2025), so upgrading to the latest version is recommended.

9. Create runtime directories

mkdir -p /data/safeline/resources/run chmod 700 /data/safeline/resources/run /data/safeline/resources/mgt /data/safeline/resources/sock /data/safeline/resources/postgres/data chmod 600 /data/safeline/.env ln -sfn /data/safeline/resources/run/safeline.sock /var/run/safeline.sock 

10. Launch and create the admin account

docker compose up -d 

The first start can take several minutes. Then open https://<safeline-ip>:9443/ in a browser, and create the administrator account with:

docker exec safeline-mgt resetadmin 

The command prints the initial username admin and an initial password, which you must record.

Why does the guide restrict .env to permissions 600?

The .env file contains the Postgres password, two internal tokens, and the AES key. Restricting it with chmod 600 .env means only the file owner can read it, which keeps those secrets out of other local users' reach.

What changes on an ARM server?

Set ARCH_SUFFIX=-arm and use POSTGRES_IMAGE=chaitin/safeline-postgres-arm:15.18. The official guide also states that ARM deployments require a Pro license, because the Personal Edition is not supported on ARM.

Should I use the LTS release?

Only if you specifically need it. The guide states the LTS version is no longer maintained starting from 9.1.0-LTS (14 August 2025) and strongly recommends upgrading to the latest version; if you have concerns, upgrade about one month after a new release.

How do I recover the administrator password?

Run docker exec safeline-mgt resetadmin again after the stack is up. The command outputs the initial username admin and a freshly generated initial password, which you should record immediately.

SafeLine has surpassed 700,000 installations worldwide as of September 30, 2026. SafeLine Pro annual promotional pricing is $650-$880, compared with the regular $1,000 per year.