feat(safeline): add coordinated 9.3.10 releases

Add standard and isolated-network SafeLine 9.3.10 packages with lockstep component tags, non-destructive lifecycle scripts, and upgrade guidance. Preserve PostgreSQL 15.8 and existing environment/data contracts for old users.
This commit is contained in:
okxlin
2026-07-22 17:16:46 +08:00
parent 8d855eb9f0
commit 0ad80bcc08
13 changed files with 637 additions and 21 deletions
+5
View File
@@ -0,0 +1,5 @@
CONTAINER_NAME="safeline"
PANEL_APP_PORT_HTTP="40080"
POSTGRES_PASSWORD="password_xxJdZD"
SAFELINE_DIR="./data"
SUBNET_PREFIX="172.18.0"
+68
View File
@@ -0,0 +1,68 @@
additionalProperties:
formFields:
- default: ""
edit: true
envKey: POSTGRES_PASSWORD
labelEn: Postgres database User Password
labelZh: Postgres数据库密码
label:
en: 'Postgres database User Password'
zh: 'Postgres数据库密码'
zh-Hant: 'Postgres 資料庫使用者密碼'
ja: 'Postgres データベースユーザーパスワード'
ko: 'Postgres 데이터베이스 사용자 비밀번호'
ru: 'Пароль пользователя базы данных Postgres'
ms: 'Kata laluan pengguna pangkalan data Postgres'
pt-br: 'Senha do usuário do banco de dados Postgres'
required: true
rule: paramCommon
type: password
- default: 40080
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: Port
labelZh: 端口
label:
en: 'Port'
zh: '端口'
zh-Hant: '埠'
ja: 'ポート'
ko: '포트'
ru: 'Порт'
ms: 'Port'
pt-br: 'Porta'
required: true
rule: paramPort
type: number
- default: ./data
edit: true
envKey: SAFELINE_DIR
labelEn: Data storage folder
labelZh: 数据存放文件夹
label:
en: 'Data storage folder'
zh: '数据存放文件夹'
zh-Hant: '資料存放資料夾'
ja: 'データ保存フォルダー'
ko: '데이터 저장 폴더'
ru: 'Папка хранения данных'
ms: 'Folder storan data'
pt-br: 'Pasta de armazenamento de dados'
required: true
type: text
- default: 172.18.0
edit: true
envKey: SUBNET_PREFIX
labelEn: 1panel-network subnet prefix (Check the docker network to get it)
labelZh: 1panel-network 子网前缀 (查看docker网络获取)
label:
en: '1panel-network subnet prefix (Check the docker network to get it)'
zh: '1panel-network 子网前缀 (查看docker网络获取)'
zh-Hant: '1panel-network 子網前綴(查看 docker 網路取得)'
ja: '1panel-network サブネット接頭辞(docker ネットワークで確認)'
ko: '1panel-network 서브넷 접두사(도커 네트워크에서 확인)'
ru: 'Префикс подсети 1panel-network (проверьте сеть Docker)'
ms: 'Awalan subnet 1panel-network (semak rangkaian Docker)'
pt-br: 'Prefixo da sub-rede 1panel-network (verifique a rede Docker)'
required: true
type: text
+150
View File
@@ -0,0 +1,150 @@
services:
safeline-mgt:
container_name: ${CONTAINER_NAME}-mgt
restart: always
networks:
1panel-network:
ipv4_address: ${SUBNET_PREFIX}.234
image: chaitin/safeline-mgt:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
- ${SAFELINE_DIR}/resources/mgt:/app/data
- ${SAFELINE_DIR}/logs/nginx:/app/log/nginx:z
- ${SAFELINE_DIR}/resources/sock:/app/sock
- /var/run:/app/run
ports:
- ${PANEL_APP_PORT_HTTP:-9443}:1443
healthcheck:
test: curl -k -f https://localhost:1443/api/open/health
environment:
- MGT_PG=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce?sslmode=disable
logging:
options:
max-size: "100m"
max-file: "5"
depends_on:
- safeline-pg
- safeline-fvm
labels:
createdBy: Apps
safeline-detector:
container_name: ${CONTAINER_NAME}-detector
restart: always
networks:
1panel-network:
ipv4_address: ${SUBNET_PREFIX}.235
image: chaitin/safeline-detector:9.3.10
volumes:
- ${SAFELINE_DIR}/resources/detector:/resources/detector
- ${SAFELINE_DIR}/logs/detector:/logs/detector
- /etc/localtime:/etc/localtime:ro
environment:
- LOG_DIR=/logs/detector
labels:
createdBy: Apps
safeline-tengine:
container_name: ${CONTAINER_NAME}-tengine
restart: always
image: chaitin/safeline-tengine:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/resolv.conf:/etc/resolv.conf:ro
- ${SAFELINE_DIR}/resources/nginx:/etc/nginx
- ${SAFELINE_DIR}/resources/detector:/resources/detector
- ${SAFELINE_DIR}/resources/chaos:/resources/chaos
- ${SAFELINE_DIR}/logs/nginx:/var/log/nginx:z
- ${SAFELINE_DIR}/resources/cache:/usr/local/nginx/cache
- ${SAFELINE_DIR}/resources/sock:/app/sock
environment:
- TCD_MGT_API=https://${SUBNET_PREFIX}.234:1443/api/open/publish/server
- TCD_SNSERVER=${SUBNET_PREFIX}.235:8000
- SNSERVER_ADDR=${SUBNET_PREFIX}.235:8000
- CHAOS_ADDR=${SUBNET_PREFIX}.240
ulimits:
nofile: 131072
network_mode: host
labels:
createdBy: Apps
safeline-luigi:
container_name: ${CONTAINER_NAME}-luigi
restart: always
networks:
1panel-network:
ipv4_address: ${SUBNET_PREFIX}.237
image: chaitin/safeline-luigi:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
- ${SAFELINE_DIR}/resources/luigi:/app/data
environment:
- MGT_IP=${SUBNET_PREFIX}.234
- LUIGI_PG=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce?sslmode=disable
logging:
options:
max-size: "100m"
max-file: "5"
depends_on:
- safeline-detector
- safeline-mgt
labels:
createdBy: Apps
safeline-fvm:
container_name: ${CONTAINER_NAME}-fvm
restart: always
networks:
1panel-network:
ipv4_address: ${SUBNET_PREFIX}.238
image: chaitin/safeline-fvm:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
logging:
options:
max-size: "100m"
max-file: "5"
labels:
createdBy: Apps
safeline-pg:
container_name: ${CONTAINER_NAME}-pg
restart: always
networks:
1panel-network:
ipv4_address: ${SUBNET_PREFIX}.232
image: postgres:15.8
volumes:
- ${SAFELINE_DIR}/resources/postgres/data:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
environment:
- POSTGRES_USER=safeline-ce
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
command: [postgres, -c, max_connections=600]
healthcheck:
test: pg_isready -U safeline-ce -d safeline-ce
labels:
createdBy: Apps
safeline-chaos:
container_name: ${CONTAINER_NAME}-chaos
restart: always
networks:
1panel-network:
ipv4_address: ${SUBNET_PREFIX}.240
image: chaitin/safeline-chaos:9.3.10
logging:
options:
max-size: "100m"
max-file: "5"
environment:
- DB_ADDR=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce?sslmode=disable
volumes:
- ${SAFELINE_DIR}/resources/sock:/app/sock
- ${SAFELINE_DIR}/resources/chaos:/app/chaos
labels:
createdBy: Apps
networks:
1panel-network:
external: true
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
strip_matching_quotes() {
local value="$1"
if [[ ${#value} -ge 2 ]]; then
if [[ "${value:0:1}" == '"' && "${value: -1}" == '"' ]]; then
value="${value:1:${#value}-2}"
elif [[ "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
value="${value:1:${#value}-2}"
fi
fi
printf '%s\n' "$value"
}
if [[ ${SAFELINE_DIR+x} ]]; then
DATA_DIR_RAW="$SAFELINE_DIR"
elif [[ -f "$ENV_FILE" ]]; then
DATA_DIR_RAW="$(sed -n 's/^SAFELINE_DIR=//p' "$ENV_FILE" | tail -n 1)"
else
DATA_DIR_RAW="./data"
fi
DATA_DIR_RAW="$(strip_matching_quotes "${DATA_DIR_RAW:-./data}")"
[[ "$DATA_DIR_RAW" != *$'\n'* && "$DATA_DIR_RAW" != *$'\r'* ]] || {
echo "SAFELINE_DIR must be a single-line path" >&2
exit 1
}
if [[ "$DATA_DIR_RAW" = /* ]]; then
DATA_DIR="$(realpath -m -- "$DATA_DIR_RAW")"
else
DATA_DIR="$(realpath -m -- "${ROOT_DIR}/${DATA_DIR_RAW#./}")"
fi
[[ "$DATA_DIR" != "/" ]] || {
echo "SAFELINE_DIR must not be the filesystem root" >&2
exit 1
}
mkdir -p -- \
"$DATA_DIR/resources/mgt" \
"$DATA_DIR/resources/sock" \
"$DATA_DIR/resources/detector" \
"$DATA_DIR/resources/nginx" \
"$DATA_DIR/resources/chaos" \
"$DATA_DIR/resources/cache" \
"$DATA_DIR/resources/luigi" \
"$DATA_DIR/resources/postgres/data" \
"$DATA_DIR/logs/nginx" \
"$DATA_DIR/logs/detector"
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
docker compose down --remove-orphans
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
"${SCRIPT_DIR}/init.sh"
+49 -21
View File
@@ -1,41 +1,69 @@
# 雷池 Web 应用防火墙(Safeline WAF)
# 雷池 Web 应用防火墙SafeLine WAF
## 应用简介
一款足够简单、足够好用、足够强的免费 WAF
## 产品介绍
雷池是一款开源 Web 应用防火墙,通过反向代理接入网站流量并提供攻击检测、访问控制和人机验证能力
英文说明:A simple and easy to use WAF tool.
## 主要功能
- Web 攻击检测与拦截
- 访问控制、人机验证和防爬虫能力
- 多站点反向代理与证书管理
- 管理控制台、检测引擎和防护引擎协同运行
## 访问说明
安装完成后,通过 `https://<服务器 IP>:<PANEL_APP_PORT_HTTP>` 访问管理控制台。首次访问可能看到自签名证书警告,请核对访问地址后继续,或配置受信任证书。
## Introduction
SafeLine is an open source web application firewall that protects websites through a reverse-proxy deployment with attack detection, access control, and human verification.
## Features
- Web attack detection and blocking
- Access control, human verification, and bot mitigation
- Multi-site reverse proxy and certificate management
- Coordinated management, detection, and traffic-processing services
## 部署说明
- 本应用使用 Docker Compose 在 1Panel 中部署。
- 应用分类:工具
- 支持架构:amd64
- 可选版本:`latest``7.3.1``newnet-7.3.1``newnet-latest`
- 安装后按应用表单中的端口访问 Web UI、SSH 或对应服务
- 本应用使用长亭官方 SafeLine 镜像,并以 Docker Compose 在 1Panel 中部署。
- 普通版本复用 `1panel-network` 并占用一组固定容器地址,安装前必须确认 `SUBNET_PREFIX` 与该网络一致且地址未冲突
- `newnet-*` 版本创建独立的 `safeline-ce` 网络,通常更不容易与其他商店应用发生地址冲突,推荐新安装优先选择
- 安装后不要在普通版本和 `newnet-*` 版本之间直接切换;升级时应保持原有网络变体
- 本应用支持 `amd64`
## 端口
| 变量 | 说明 | 默认值 | 必填 |
| --- | --- | --- | --- |
| PANEL_APP_PORT_HTTP | 端口 | 40080 | 是 |
| PANEL_APP_PORT_HTTP | HTTPS 管理端口 | 40080 | 是 |
## 数据持久化
| 变量 | 说明 | 默认值 | 必填 |
| --- | --- | --- | --- |
| SAFELINE_DIR | 数据存放文件夹 | ./data | 是 |
升级或迁移前,请在 1Panel 中备份上述数据目录。
| SAFELINE_DIR | SafeLine 配置、日志和内置 PostgreSQL 数据目录 | ./data | 是 |
## 配置项
| 变量 | 说明 | 默认值 | 必填 |
| --- | --- | --- | --- |
| POSTGRES_PASSWORD | Postgres数据库密码 | - | 是 |
| SUBNET_PREFIX | 1panel-network 子网前缀 (查看docker网络获取) | 172.18.0 | 是 |
| POSTGRES_PASSWORD | 内置 PostgreSQL 用户密码 | - | 是 |
| SUBNET_PREFIX | Docker 网络的前三段 IPv4 地址 | 依版本而定 | 是 |
## 使用说明
- 安装完成后,在 1Panel 应用页面查看运行状态、端口和日志
- 首次启用前,请按安装表单填写域名、账号、密码、Token、数据目录等参数
- 如需对外开放访问,请同步检查防火墙安全组和反向代理配置
## 安全与部署风险
- `safeline-tengine` 使用主机网络模式,可直接访问主机网络栈,并可能占用主机上的业务端口。这是 WAF 反向代理流量所需的核心部署方式
- 管理服务将主机 `/var/run` 挂载到容器内,以支持官方运行时协作。请仅在可信主机上部署,并限制 1Panel 和 Docker 的管理权限
- 对外开放管理端口前,请使用防火墙安全组限制可信来源
## Security and Deployment Risks
- `safeline-tengine` uses host networking and can access the host network stack or bind host service ports. This is required for the WAF reverse-proxy path.
- The management service mounts host `/var/run` for the official runtime integration. Deploy only on a trusted host and restrict 1Panel and Docker administrative access.
- Restrict the management port to trusted source addresses before exposing it externally.
## 升级说明
- 升级前使用 `pg_dump` 备份内置 PostgreSQL 数据库,并在停止应用后备份整个 `SAFELINE_DIR`。仅复制正在运行的 PostgreSQL 数据目录不能替代数据库原生备份。
- 保持 `POSTGRES_PASSWORD``SAFELINE_DIR``SUBNET_PREFIX` 和普通版/`newnet-*` 变体不变。
- SafeLine 的管理、检测、Tengine、Luigi、FVM 和 Chaos 六个组件必须使用同一发布版本,不要单独替换其中一个镜像。
- 商店包继续使用既有的 PostgreSQL 15.8 镜像和数据目录,避免老用户在升级时切换数据库镜像谱系或发生版本倒退。
- 当前官方部署以应用内 PostgreSQL 为基线,尚无足够的官方迁移和升级证据支持改接共享商店数据库,因此本应用暂不提供数据库应用选择器。
- 升级脚本只补齐缺失的数据目录,不修改目录所有者、不重写配置,也不删除持久化数据。
## 参考资料
- 官网: <https://waf-ce.chaitin.cn/>
- 文档: <https://waf-ce.chaitin.cn/posts/guide_introduction>
- 源码: <https://github.com/chaitin/safeline>
- 官方文档: <https://waf-ce.chaitin.cn/posts/guide_install>
- 官方源码: <https://github.com/chaitin/SafeLine>
- 官方发布记录: <https://github.com/chaitin/SafeLine/releases>
+5
View File
@@ -0,0 +1,5 @@
CONTAINER_NAME="safeline"
PANEL_APP_PORT_HTTP="40080"
POSTGRES_PASSWORD="password_xxJdZD"
SAFELINE_DIR="./data"
SUBNET_PREFIX="192.168.255"
+68
View File
@@ -0,0 +1,68 @@
additionalProperties:
formFields:
- default: ""
edit: true
envKey: POSTGRES_PASSWORD
labelEn: Postgres database User Password
labelZh: Postgres数据库密码
label:
en: 'Postgres database User Password'
zh: 'Postgres数据库密码'
zh-Hant: 'Postgres 資料庫使用者密碼'
ja: 'Postgres データベースユーザーパスワード'
ko: 'Postgres 데이터베이스 사용자 비밀번호'
ru: 'Пароль пользователя базы данных Postgres'
ms: 'Kata laluan pengguna pangkalan data Postgres'
pt-br: 'Senha do usuário do banco de dados Postgres'
required: true
rule: paramCommon
type: password
- default: 40080
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: Port
labelZh: 端口
label:
en: 'Port'
zh: '端口'
zh-Hant: '埠'
ja: 'ポート'
ko: '포트'
ru: 'Порт'
ms: 'Port'
pt-br: 'Porta'
required: true
rule: paramPort
type: number
- default: ./data
edit: true
envKey: SAFELINE_DIR
labelEn: Data storage folder
labelZh: 数据存放文件夹
label:
en: 'Data storage folder'
zh: '数据存放文件夹'
zh-Hant: '資料存放資料夾'
ja: 'データ保存フォルダー'
ko: '데이터 저장 폴더'
ru: 'Папка хранения данных'
ms: 'Folder storan data'
pt-br: 'Pasta de armazenamento de dados'
required: true
type: text
- default: 192.168.255
edit: true
envKey: SUBNET_PREFIX
labelEn: New docker network subnet prefix
labelZh: 新 docker 网络子网前缀
label:
en: 'New docker network subnet prefix'
zh: '新 docker 网络子网前缀'
zh-Hant: '新 docker 網路子網前綴'
ja: '新しい docker ネットワークのサブネット接頭辞'
ko: '새 docker 네트워크 서브넷 접두사'
ru: 'Префикс подсети новой сети Docker'
ms: 'Awalan subnet rangkaian Docker baharu'
pt-br: 'Prefixo da sub-rede da nova rede Docker'
required: true
type: text
@@ -0,0 +1,166 @@
services:
safeline-mgt:
container_name: ${CONTAINER_NAME}-mgt
restart: always
networks:
1panel-network:
safeline-ce:
ipv4_address: ${SUBNET_PREFIX}.4
image: chaitin/safeline-mgt:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
- ${SAFELINE_DIR}/resources/mgt:/app/data
- ${SAFELINE_DIR}/logs/nginx:/app/log/nginx:z
- ${SAFELINE_DIR}/resources/sock:/app/sock
- /var/run:/app/run
ports:
- ${PANEL_APP_PORT_HTTP:-9443}:1443
healthcheck:
test: curl -k -f https://localhost:1443/api/open/health
environment:
- MGT_PG=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce?sslmode=disable
logging:
options:
max-size: "100m"
max-file: "5"
depends_on:
- safeline-pg
- safeline-fvm
labels:
createdBy: Apps
safeline-detector:
container_name: ${CONTAINER_NAME}-detector
restart: always
networks:
1panel-network:
safeline-ce:
ipv4_address: ${SUBNET_PREFIX}.5
image: chaitin/safeline-detector:9.3.10
volumes:
- ${SAFELINE_DIR}/resources/detector:/resources/detector
- ${SAFELINE_DIR}/logs/detector:/logs/detector
- /etc/localtime:/etc/localtime:ro
environment:
- LOG_DIR=/logs/detector
labels:
createdBy: Apps
safeline-tengine:
container_name: ${CONTAINER_NAME}-tengine
restart: always
image: chaitin/safeline-tengine:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/resolv.conf:/etc/resolv.conf:ro
- ${SAFELINE_DIR}/resources/nginx:/etc/nginx
- ${SAFELINE_DIR}/resources/detector:/resources/detector
- ${SAFELINE_DIR}/resources/chaos:/resources/chaos
- ${SAFELINE_DIR}/logs/nginx:/var/log/nginx:z
- ${SAFELINE_DIR}/resources/cache:/usr/local/nginx/cache
- ${SAFELINE_DIR}/resources/sock:/app/sock
environment:
- TCD_MGT_API=https://${SUBNET_PREFIX}.4:1443/api/open/publish/server
- TCD_SNSERVER=${SUBNET_PREFIX}.5:8000
- SNSERVER_ADDR=${SUBNET_PREFIX}.5:8000
- CHAOS_ADDR=${SUBNET_PREFIX}.10
ulimits:
nofile: 131072
network_mode: host
labels:
createdBy: Apps
safeline-luigi:
container_name: ${CONTAINER_NAME}-luigi
restart: always
networks:
1panel-network:
safeline-ce:
ipv4_address: ${SUBNET_PREFIX}.7
image: chaitin/safeline-luigi:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
- ${SAFELINE_DIR}/resources/luigi:/app/data
environment:
- MGT_IP=${SUBNET_PREFIX}.4
- LUIGI_PG=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce?sslmode=disable
logging:
options:
max-size: "100m"
max-file: "5"
depends_on:
- safeline-detector
- safeline-mgt
labels:
createdBy: Apps
safeline-fvm:
container_name: ${CONTAINER_NAME}-fvm
restart: always
networks:
1panel-network:
safeline-ce:
ipv4_address: ${SUBNET_PREFIX}.8
image: chaitin/safeline-fvm:9.3.10
volumes:
- /etc/localtime:/etc/localtime:ro
logging:
options:
max-size: "100m"
max-file: "5"
labels:
createdBy: Apps
safeline-pg:
container_name: ${CONTAINER_NAME}-pg
restart: always
networks:
1panel-network:
safeline-ce:
ipv4_address: ${SUBNET_PREFIX}.2
image: postgres:15.8
volumes:
- ${SAFELINE_DIR}/resources/postgres/data:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
environment:
- POSTGRES_USER=safeline-ce
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
command: [postgres, -c, max_connections=600]
healthcheck:
test: pg_isready -U safeline-ce -d safeline-ce
labels:
createdBy: Apps
safeline-chaos:
container_name: ${CONTAINER_NAME}-chaos
restart: always
networks:
1panel-network:
safeline-ce:
ipv4_address: ${SUBNET_PREFIX}.10
image: chaitin/safeline-chaos:9.3.10
logging:
options:
max-size: "100m"
max-file: "5"
environment:
- DB_ADDR=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce?sslmode=disable
volumes:
- ${SAFELINE_DIR}/resources/sock:/app/sock
- ${SAFELINE_DIR}/resources/chaos:/app/chaos
labels:
createdBy: Apps
networks:
1panel-network:
external: true
safeline-ce:
name: safeline-ce
driver: bridge
ipam:
driver: default
config:
- gateway: ${SUBNET_PREFIX:?SUBNET_PREFIX required}.1
subnet: ${SUBNET_PREFIX}.0/24
driver_opts:
com.docker.network.bridge.name: safeline-ce
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
strip_matching_quotes() {
local value="$1"
if [[ ${#value} -ge 2 ]]; then
if [[ "${value:0:1}" == '"' && "${value: -1}" == '"' ]]; then
value="${value:1:${#value}-2}"
elif [[ "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
value="${value:1:${#value}-2}"
fi
fi
printf '%s\n' "$value"
}
if [[ ${SAFELINE_DIR+x} ]]; then
DATA_DIR_RAW="$SAFELINE_DIR"
elif [[ -f "$ENV_FILE" ]]; then
DATA_DIR_RAW="$(sed -n 's/^SAFELINE_DIR=//p' "$ENV_FILE" | tail -n 1)"
else
DATA_DIR_RAW="./data"
fi
DATA_DIR_RAW="$(strip_matching_quotes "${DATA_DIR_RAW:-./data}")"
[[ "$DATA_DIR_RAW" != *$'\n'* && "$DATA_DIR_RAW" != *$'\r'* ]] || {
echo "SAFELINE_DIR must be a single-line path" >&2
exit 1
}
if [[ "$DATA_DIR_RAW" = /* ]]; then
DATA_DIR="$(realpath -m -- "$DATA_DIR_RAW")"
else
DATA_DIR="$(realpath -m -- "${ROOT_DIR}/${DATA_DIR_RAW#./}")"
fi
[[ "$DATA_DIR" != "/" ]] || {
echo "SAFELINE_DIR must not be the filesystem root" >&2
exit 1
}
mkdir -p -- \
"$DATA_DIR/resources/mgt" \
"$DATA_DIR/resources/sock" \
"$DATA_DIR/resources/detector" \
"$DATA_DIR/resources/nginx" \
"$DATA_DIR/resources/chaos" \
"$DATA_DIR/resources/cache" \
"$DATA_DIR/resources/luigi" \
"$DATA_DIR/resources/postgres/data" \
"$DATA_DIR/logs/nginx" \
"$DATA_DIR/logs/detector"
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
docker compose down --remove-orphans
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
"${SCRIPT_DIR}/init.sh"