# Caddy 部署辅助脚本

## 文件

- `install_caddy.sh`：按 `binary` 或 `docker` 模式准备 Caddy 部署。
- `.bash_caddy`：由 `install_caddy.sh` 通过 `HELPER_SCRIPT_URL` 下载并部署到目标目录的 helper 脚本。
- `tests/test_install_caddy.sh`：shell 回归测试。

安装脚本会自动把 helper source 片段写入当前用户的 shell rc，新开的 shell 会自动拥有 `caddy` 命令。shell hook 指向部署后的 helper，而不是仓库里的模板文件。
如果后续 helper 发布地址变化，可以直接修改 `install_caddy.sh` 顶部的 `HELPER_SCRIPT_URL`。

## 部署模式

### Binary

- 默认从上游 GitHub Releases 的 `latest` 重定向解析并下载最新版本。
- 二进制文件写入 `/usr/local/bin/caddy`。
- 配置文件写入 `/etc/caddy/Caddyfile`。
- 日志写入 `/etc/caddy/logs`。
- `/etc/caddy/state` 用于保存 Caddy 状态和证书数据。
- 默认不启用静态站点。
- 只有使用 `--enable-static-site` 时才会创建 `/etc/caddy/site`。
- 写入的 `/etc/systemd/system/caddy.service` 基于上游 `caddyserver/dist` 的 unit 文件。

生成的目录和文件：

- `/etc/caddy`：Caddy 主配置根目录。
- `/etc/caddy/Caddyfile`：脚本生成并由服务使用的 Caddyfile。
- `/etc/caddy/.bash_caddy`：部署后的 helper 脚本，供 shell 启动文件加载。
- `/etc/caddy/.helper.env`：安装脚本生成的 helper 配置，目前用于保存首选编辑器。
- `/etc/caddy/logs`：运行日志和访问日志目录。
- `/etc/caddy/state`：Caddy 状态目录，用于保存证书、ACME 账户数据、续签状态和本地存储数据。
- `/etc/caddy/site`：可选静态站点目录，只有使用 `--enable-static-site` 时才会创建。
- `/usr/local/bin/caddy`：安装后的 Caddy 二进制文件。
- `/etc/systemd/system/caddy.service`：binary 模式生成的 systemd unit 文件。

### Docker

- 默认镜像为 `caddy:latest`。
- 默认根目录为 `~/projects/caddy`。
- 默认使用 `network_mode: host`，因为这里的 Docker 部署目标是 Linux 网关场景。
- `compose.yml` 写入 `~/projects/caddy/compose.yml`。
- 配置文件写入 `~/projects/caddy/conf/Caddyfile`。
- 日志挂载到 `~/projects/caddy/logs`。
- 状态目录挂载到 `~/projects/caddy/data` 和 `~/projects/caddy/config`。
- 默认不启用静态站点。
- 只有使用 `--enable-static-site` 时才会挂载 `~/projects/caddy/site:/srv`。

`~/projects/caddy` 下生成的目录和文件：

- `conf`：存放 `Caddyfile` 和其他挂载到 `/etc/caddy` 的配置文件。
- `.bash_caddy`：部署后的 helper 脚本，供 shell 启动文件加载。
- `.helper.env`：安装脚本生成的 helper 配置，目前用于保存首选编辑器。
- `compose.yml`：脚本生成的 Docker Compose 文件。
- `logs`：宿主机侧日志目录，挂载到容器内 `/var/log/caddy`。
- `data`：宿主机侧 `/data` 挂载目录，用于持久化证书和 Caddy 运行数据。
- `config`：宿主机侧 `/config` 挂载目录，用于持久化官方镜像使用的配置状态。
- `site`：可选静态站点目录，只有使用 `--enable-static-site` 时才会挂载到 `/srv`。

## 安装

```bash
cd bitfennec_simple_page/http/linux/caddy
bash install_caddy.sh <binary|docker> [options]
```

| 参数 | 作用 | 默认值 |
| --- | --- | --- |
| `binary` / `docker` | 选择部署模式 | `binary` |
| `--enable-static-site` | 创建并启用可选的静态站点目录 | 关闭 |
| `--editor <name>` | 设置 `caddy edit` 使用的编辑器 | `vim` |
| `--docker-root <path>` | 覆盖 Docker 根目录 | `~/projects/caddy` |
| `--version <x.y.z>` | 在 binary 模式固定 Caddy 版本 | 最新版 |

示例：

```bash
bash install_caddy.sh binary
bash install_caddy.sh binary --enable-static-site --editor hx
bash install_caddy.sh docker --docker-root ~/projects/caddy-gateway
```

安装后，重新开一个 shell，或者执行：

```bash
exec $SHELL -l
```

## 命令

先在 bash 里加载包装脚本：

```bash
source /etc/caddy/.bash_caddy
```

如果是 Docker 模式，则改为加载部署目录里的 helper：

```bash
source <docker-root>/.bash_caddy
```

helper 现在会同时注册 bash 和 zsh 的补全。部署新版 helper 后，zsh 不再需要手动执行 `bashcompinit`。

常用命令：

```bash
caddy up
caddy down
caddy restart
caddy reload
caddy status
caddy edit
caddy version
caddy logs runtime
caddy logs runtime -f
caddy logs access
caddy logs access -f
caddy fmt
caddy validate
```

`caddy version` 现在会先输出部署详情，再输出 Caddy 自带的版本信息，内容包括：

- 当前安装模式
- 安装根目录和配置路径
- 日志目录和状态目录
- helper 脚本与 helper env 路径
- 静态站点是否启用
- 安装脚本生成的目录和文件，以及当前是 `present` 还是 `missing`

## 日志

- `runtime.log`：运行日志，用来看启动、reload、ACME 证书申请、续签、告警和错误。
- `access.log`：访问日志，用来看客户端请求、路径、状态码和响应信息。

## 权限

- Binary 模式需要 root 或可用的 sudo，因为它会写 `/usr/local/bin`、`/etc/caddy` 和 `/etc/systemd/system`。
- Docker 模式默认只写所选 docker 根目录，通常直接用当前用户即可。

## 验证

```bash
cd bitfennec_simple_page/http/linux/caddy
bash tests/test_install_caddy.sh
```
