From 92f89203872266497a8f9c472213980d55af9feb Mon Sep 17 00:00:00 2001 From: "3127647737@qq.com" <3127647737@qq.com> Date: Fri, 17 Jul 2026 18:51:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Docker=20=E6=8C=81?= =?UTF-8?q?=E4=B9=85=E5=8C=96=E7=9B=AE=E5=BD=95=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + README.md | 26 +++++++++++++++++++++----- deploy/prepare-volumes.sh | 25 +++++++++++++++++++++++++ docker-compose.yml | 38 ++++++++++++++++++++++++++++++-------- 4 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 deploy/prepare-volumes.sh diff --git a/Dockerfile b/Dockerfile index 41b7571..1f5b77b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,7 @@ RUN python -m pip install --upgrade pip "setuptools>=83" \ COPY app ./app COPY migrations ./migrations COPY deploy/backup.py ./deploy/backup.py +COPY deploy/prepare-volumes.sh ./deploy/prepare-volumes.sh RUN mkdir -p /app/data /app/secrets /app/backups \ && chown -R fluxip:fluxip /app/data /app/secrets /app/backups diff --git a/README.md b/README.md index 72db3f6..95f1f46 100644 --- a/README.md +++ b/README.md @@ -313,14 +313,25 @@ AWS 与 DNS 的原子事务。需要人工接管时,先禁用相关实例组 ## Docker Compose -Docker Compose 默认把 WebUI 发布到 `127.0.0.1:8787`,并使用三个独立命名卷保存 -数据库、主密钥和备份: +Docker Compose 默认把 WebUI 发布到 `127.0.0.1:8787`,并使用项目目录下三个独立的 +宿主机目录保存数据库、主密钥和备份: + +```text +data/fluxip-data/ +data/fluxip-key/ +data/fluxip-backups/ +``` + +部署需要 Docker Compose v2(使用 `docker compose` 命令)。启动时,一次性的 +`fluxip-init` 服务会拒绝挂载目录中的符号链接或特殊文件,把目录权限收紧并交给 +UID/GID `10001` 后退出;长期运行的 `fluxip` 服务仍是非 root 用户。已有数据库、 +主密钥和备份不会被初始化服务删除或改写内容。 ```bash cp deploy/fluxip.env.example .env # 编辑 .env,至少设置高熵 ROTATOR_BOOTSTRAP_TOKEN docker compose up -d --build -docker compose ps +docker compose ps -a curl http://127.0.0.1:8787/readyz ``` @@ -340,8 +351,8 @@ docker compose restart fluxip docker compose down ``` -`docker compose down` 不删除命名卷。除非已验证备份并确定要销毁全部数据,否则不要 -执行 `docker compose down -v`。 +`docker compose down` 不删除上述宿主机目录。不要手工删除 `data/fluxip-key/master.key`; +数据库存在但主密钥丢失时,已保存的云端凭据将无法解密。 ## Linux systemd 与 HTTPS @@ -437,6 +448,11 @@ systemd 定时备份示例为 `deploy/fluxip-backup.service` 和 - **任务待清理**:新地址通常已经生效,但旧地址尚未成功释放,应尽快处理以避免费用。 - **客户端短暂掉线**:Static IP 替换会终止原 TCP 连接,这是当前架构的预期边界。 - **主密钥缺失**:恢复与数据库匹配的主密钥,不要删除数据库让程序生成新密钥。 +- **Docker 启动提示 `/app/secrets/master.key` 无权限**:拉取最新代码后执行 + `docker compose down`,再执行 `docker compose up -d --build --force-recreate`,确认 + `docker compose ps -a` 中 `fluxip-init` 为 `Exited (0)`。这两个命令不会删除持久化 + 目录。旧版本可先停止服务,再将 `data/fluxip-data`、`data/fluxip-key`、 + `data/fluxip-backups` 的所有者递归改为 `10001:10001`;不要删除或单独替换已有主密钥。 ## 安全清单 diff --git a/deploy/prepare-volumes.sh b/deploy/prepare-volumes.sh new file mode 100644 index 0000000..24e5354 --- /dev/null +++ b/deploy/prepare-volumes.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -eu + +readonly FLUXIP_UID=10001 +readonly FLUXIP_GID=10001 + +prepare_directory() { + directory=$1 + mkdir -p "$directory" + unsafe_entry=$(find "$directory" -xdev ! -type d ! -type f -print -quit) + if [ -n "$unsafe_entry" ]; then + echo "Refusing unsafe volume entry: $unsafe_entry" >&2 + exit 1 + fi + find "$directory" -xdev -exec \ + chown --no-dereference "$FLUXIP_UID:$FLUXIP_GID" {} + + find "$directory" -xdev -type d -exec chmod 0700 {} + + find "$directory" -xdev -type f -exec chmod 0600 {} + +} + +prepare_directory /app/data +prepare_directory /app/secrets +prepare_directory /app/backups + +echo "FluxIP volume permissions prepared for UID $FLUXIP_UID" diff --git a/docker-compose.yml b/docker-compose.yml index b7756a9..3ca83e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,31 @@ services: + fluxip-init: + build: + context: . + dockerfile: Dockerfile + image: fluxip:local + user: "0:0" + command: + - /bin/sh + - /app/deploy/prepare-volumes.sh + volumes: + - ./data/fluxip-data:/app/data + - ./data/fluxip-key:/app/secrets + - ./data/fluxip-backups:/app/backups + read_only: true + network_mode: none + cap_drop: + - ALL + cap_add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + security_opt: + - no-new-privileges:true + healthcheck: + disable: true + restart: "no" + fluxip: build: context: . @@ -7,6 +34,9 @@ services: container_name: fluxip restart: unless-stopped init: true + depends_on: + fluxip-init: + condition: service_completed_successfully ports: - "${FLUXIP_BIND_ADDRESS:-127.0.0.1}:${FLUXIP_PORT:-8787}:8787" environment: @@ -52,11 +82,3 @@ services: options: max-size: 10m max-file: "3" - -volumes: - fluxip-data: - name: fluxip-data - fluxip-key: - name: fluxip-key - fluxip-backups: - name: fluxip-backups