# 为了stalwart修改caddy的uuid=1000运行

**URL:** <https://ytai.de/t/topic/123>\
**Category:** General\
**Tags:** selfhosting, vps\
**Created:** [2026 年4 月 4 日 15:39 UTC](https://ytai.de/t/topic/123 "2026-04-04T15:39:12Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ray](https://ytai.de/letter_avatar_proxy/v4/letter/r/e9a140/32.png) [@Ray](https://ytai.de/u/Ray)\
**Post date:** [2026 年4 月 4 日 15:39 UTC](https://ytai.de/t/topic/123/1 "2026-04-04T15:39:12Z")

</div>

将 Caddy 改为以 `UID=1000` 运行，是彻底解决这种“Docker 容器间权限壁垒”的最根本方法（被称为“统一 UID 策略”）。

但这个操作 **绝不能简单地加一行代码就完事** ，因为它伴随着两个非常直接的风险。如果你不提前处理好，Caddy 启动瞬间就会崩溃。

* * *

### ⚠ 风险预警（为什么要谨慎？）

#### 风险 1：无法监听低端口（致命错误）

在 Linux 系统中，只有 `root` 用户有权限绑定 **1024 以下** 的端口。

你的 Caddy 承担了 `80`, `443`, `25`, `465`, `993` 等大量特权端口。一旦降级为 `1000` 用户，Caddy 启动时会立刻报 `permission denied` 无法绑定端口而直接退出。

👉 **解法** ：必须通过 Docker 给它单独追加 `NET_BIND_SERVICE` 内核权限。

#### 风险 2：历史数据变“只读”（启动崩溃）

你之前以 `root` 运行了很久，现在的 `/opt/caddy/caddy_data` 目录全都是 `root` 的资产。

如果你突然让 `1000` 用户接管，Caddy 甚至连自己的日志、配置文件和已有的证书都写不进去，会立刻挂掉。

👉 **解法** ：在重启前，必须在宿主机手动把历史资产“过户”给 1000。

* * *

### 🛠 安全操作指南（4 步无痛切换）

如果你准备好了，请 **严格按照以下顺序操作** ：

#### 第一步：停止 Caddy 容器

不要直接重启，先让它停下来，防止我们在改权限时它正在写入数据。

Bash

```auto
docker stop caddy_edge

```

_(注：请把 `caddy_edge` 换成你实际的 Caddy 容器名或通过 docker compose 停止)_

#### 第二步：在宿主机“过户”文件资产

找到你 Caddy 挂载在宿主机的物理目录（主要是 data 和 config）。根据你之前的线索，执行：

Bash

```auto
# 将证书/数据目录的所有者改为 UID 1000 和 GID 1000
chown -R 1000:1000 /opt/caddy/caddy_data

# 如果你还挂载了 config 目录，也要一起改，例如：
# chown -R 1000:1000 /opt/caddy/caddy_config

```

#### 第三步：修改 `docker-compose.yml`

打开 Caddy 的配置，在服务层级追加 `user` 和 `cap_add` 两个关键配置：

YAML

```auto
services:
  caddy_edge:
    image: caddy:latest
    # 1. 强制以 UID 1000 和 GID 1000 运行
    user: "1000:1000"
    
    # 2. 赋予绑定 1024 以下特权端口的内核能力（必须加！）
    cap_add:
      - NET_BIND_SERVICE
      
    ports:
      - "80:80"
      - "443:443"
      - "25:25"
      - "465:465"
      - "993:993"
      # ... 保持你原来的 ports 不变 ...
    volumes:
      # ... 保持你原来的 volumes 不变 ...

```

#### 第四步：重新创建并观察日志

强制重新构建容器，让新配置生效：

Bash

```auto
docker compose up -d --force-recreate

```

立刻查看日志：

Bash

```auto
docker logs --tail 50 caddy_edge

```

* * *

### 🚀 判定胜负

1. **如果 Caddy 日志没报错，且 `8080` 管理页面能打开** ：

- 恭喜！Caddy 已经成功降权运行。

1. **以后会有什么变化？**

- 以后 Caddy 每次续期申请的新证书，Owner 直接就是 `1000`。
- Stalwart（同样是 1000）去读这些证书时，就跟读自己家里的文件一样，再也不需要你手动 `chmod 644` 了。 **一劳永逸。**

**如果在某一步报错了（比如日志里有 permission denied），那通常是因为有个别冷门挂载目录忘了 `chown`。**
