# 部署哨站

在自己的服务器或 NAS 上运行
哨站，让选定文件夹的新邮件触发通知。安装只需要 Docker；使用 Compose
方式时还需要 Docker Compose v2。

**镜像发布状态**：可用版本以
[GitHub Releases](https://github.com/mingzaily/mailwake/releases)
和
[GHCR](https://github.com/mingzaily/mailwake/pkgs/container/mailwake)
为准。

## 1. 选择安装方式

**推荐 Docker Compose**，后续更新、备份和恢复都使用同一份配置。镜像地址为
`ghcr.io/mingzaily/mailwake:latest`，支持 Linux amd64 /
arm64。`latest` 跟随稳定版本；固定版本时，将它替换为
Releases 中已发布的版本标签。

在服务器终端执行：

```
mkdir -p ~/mailwake
cd ~/mailwake
```

在这个目录创建 `compose.yaml`，复制以下完整内容：

```
services:
  core:
    image: ghcr.io/mingzaily/mailwake:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      MAILWAKE_LISTEN: "0.0.0.0:8080"
      MAILWAKE_DATA_DIR: "/data"
      MAILWAKE_RELAY_URL: "${MAILWAKE_RELAY_URL:-}"
    volumes:
      - core-data:/data
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    stop_grace_period: 30s
volumes:
  core-data:
```

拉取镜像并启动：

```
docker compose pull core
docker compose up -d
docker compose ps
docker compose logs --tail=50 core
```

**成功标志**：`core` 显示 `Up` /
`running`，日志出现首次设置码。保存这个终端，下一步会使用设置码。以后在
`~/mailwake` 目录执行 Compose 命令。

数据存放在 Docker 的 `core-data` 命名卷中，容器内路径为
`/data`；默认项目目录下的实际卷名是
`mailwake_core-data`。重建容器保留数据，`docker compose down -v`
会删除数据卷。

### Docker Run

习惯单条命令时，可以选择下面的等价安装方式。两种安装方式选择一种即可。

```
docker volume create mailwake-data
docker run -d \
  --name mailwake \
  --restart unless-stopped \
  --stop-timeout 30 \
  --read-only \
  --security-opt no-new-privileges:true \
  --cap-drop ALL \
  -p 127.0.0.1:8080:8080 \
  -v mailwake-data:/data \
  ghcr.io/mingzaily/mailwake:latest
docker logs --tail=50 mailwake
```

Docker Run 的数据卷名是 `mailwake-data`。后面的管理命令以
Compose 为例，Docker Run 的备份命令见[备份教程](backup.md#docker-run-安装的备份)。

## 2. 打开管理页面

**在运行 Docker 的电脑上访问**：打开
<http://127.0.0.1:8080>。

**部署在远程服务器或 NAS**：在自己的电脑终端执行以下命令，将
`user@server` 替换为服务器的 SSH 用户和地址：

```
ssh -L 18080:127.0.0.1:8080 user@server
```

保持终端连接，在自己电脑的浏览器打开
<http://127.0.0.1:18080>。这样即可完成首次设置；需要长期通过域名访问时，再按下一节配置
HTTPS。

**成功标志**：看到 Mailwake
的初始化页面。输入日志中的设置码，创建至少 12
个字符的管理员密码。设置完成前，重启哨站会生成新的设置码。

接下来按[第一条通知教程](first-notification.md)添加邮箱和通知通道。

## 3. 配置 HTTPS

已有域名和反向代理时，将域名指向服务器，把代理目标设为
`http://127.0.0.1:8080`。下面以安装在同一宿主机的 Caddy
为例，在 `Caddyfile` 中加入自己的域名：

```
mail.example.org {
    reverse_proxy 127.0.0.1:8080
}
```

确保域名解析正确，服务器允许 80 / 443 入站，再校验和重载配置：

```
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
```

打开
`https://mail.example.org`，确认浏览器证书有效、可以登录并打开邮箱页面。Caddy 的安装见[官方安装说明](https://caddyserver.com/docs/install)。使用 Nginx Proxy Manager
等面板时，填写相同的域名和代理目标，并在面板申请证书。

代理在另一个容器中运行时，让它与哨站加入同一 Docker 网络，目标使用
`http://core:8080`；容器中的
`127.0.0.1` 指向它自己。代理须保留原始 Host，并设置
`X-Forwarded-For`。哨站
接受来自本机和私有网段的代理信息，8080
应只向代理及可信本机客户端开放。

## 4. 更新版本

先完成一次[备份](backup.md)，再在 Compose
目录执行：

```
docker compose pull core
docker compose up -d
docker compose ps
docker compose logs --tail=50 core
```

使用固定版本时，先修改
`compose.yaml`
中的镜像标签，再执行上述命令。打开管理页面，确认邮箱正常监听，再发送一封新邮件验证通知。保留升级前的备份；需要回退时，按恢复教程同时恢复旧数据和对应镜像。

## 5. 常见问题

### 镜像拉取失败

先检查 GHCR 是否已有目标版本。`manifest unknown`
通常表示标签不存在。若出现
`denied`，先核对镜像地址和包的公开状态；网络超时则检查服务器到 GHCR
的连接。

### 打不开管理页面

`127.0.0.1` 表示当前电脑。远程部署请使用 SSH 转发或 HTTPS
域名。执行 `docker compose ps` 与
`docker compose logs --tail=50 core`，先确认容器运行。8080 已被占用时，将端口映射左侧改为
`127.0.0.1:18080:8080`，浏览器与代理目标也改为 18080。

### 忘记管理员密码

在 Compose 目录执行，按终端提示输入新密码：

```
docker compose stop core
docker compose run --rm -it core admin reset-password
docker compose start core
```

恢复命令会获取数据目录锁，执行前先停止
哨站。重置密码会注销浏览器会话，保留 API Token、邮箱与队列。

### 官方 App 与 Pro 怎么接入

Free 的 Web 管理和 Bark / Pushover / Webhook 可独立使用。官方 App
尚未上架，正式下载入口、推送中继服务
地址和签名公钥以官方发布为准。具备正式接入配置后，按
[App 接入说明](connect-app.md)配置 HTTPS 和设备配对。

源码构建与本地开发见[开发指南](https://github.com/mingzaily/mailwake/blob/main/docs/development.md)。

## 源码构建与进程配置

开发构建见 [源码仓库说明](https://github.com/mingzaily/mailwake#run-from-source) 和[贡献者构建指南](https://github.com/mingzaily/mailwake/blob/main/CONTRIBUTING.md)。

容器外 `MAILWAKE_LISTEN` 默认 `127.0.0.1:8080`，容器内为 `0.0.0.0:8080`。`MAILWAKE_DATA_DIR` 默认 `data`，容器内为 `/data`。`MAILWAKE_RELAY_URL` 默认 `https://notify.mailwake.oritx.com`。重启与升级时保留包含 `secret.key` 的完整数据目录。

## 更换推送中继服务环境

生产与 Sandbox 使用独立配对身份。确实需要更换环境时，停止哨站，使用原数据目录和已保存的旧推送中继服务地址执行重置：

```sh
docker compose stop core
docker compose run --rm -it core admin reset-native-push
```

按提示输入 `reset-native-push`。命令会在旧推送中继服务撤销配对；旧服务无法访问时，保留旧配置并等待服务可访问后重试。确认未解决目标为零后，设置新的 `MAILWAKE_RELAY_URL`，执行 `docker compose up -d` 重建容器并[重新配对](connect-app.md)。命令保留哨站签名身份和普通渠道历史。
