Add container build, compose example and deployment docs

Multi-stage Dockerfile on debian:trixie-slim. openvpn3 and lwIP are cloned
at pinned refs and handed to CMake through OVG_OPENVPN3_DIR/OVG_LWIP_DIR
rather than left to FetchContent, whose GIT_TAG master would make the same
Dockerfile build a different VPN client each week. The unit suite runs in
the builder stage.

docker/openvpngate.conf overrides only the keys whose host default is wrong
inside a container -- loopback listen addresses, which make a published port
reach nothing, and relative state paths, which put the node failure history
on a layer that gets thrown away. Everything else stays absent and takes the
compiled-in default so the file cannot drift from the code.

The compose example drops every capability, runs read-only as uid 10001 and
publishes both ports to host loopback: the admin endpoint has no auth and
includes POST /switch. That configuration is the design constraint of this
project (no root, no tun device) turned into something testable.

docs/DOCKER.md 8 records what was checked against the source and what was
not: this sandbox has no docker daemon, so neither the image build nor the
compose file has actually been run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iceBear67
2026-07-28 05:54:44 +00:00
co-authored by Claude Opus 5
parent 5782207744
commit f37cd0a125
8 changed files with 706 additions and 0 deletions
+15
View File
@@ -18,6 +18,7 @@ SOCKS5 客户端 ──► socks5::Server ──► egress::Egress ──► lwI
| [docs/FEASIBILITY.md](docs/FEASIBILITY.md) | 动手前的可行性结论。**需求中唯一不可能的部分在 §1**;UDP ASSOCIATE 的明确表态在 §5;1000 并发的真实天花板在 §4 |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | 模块边界、线程模型、切换状态机、选点与健康检查的具体算法 |
| [etc/openvpngate.conf](etc/openvpngate.conf) | 全部配置项,每一项都带默认值和「为什么是这个默认值」 |
| [docs/DOCKER.md](docs/DOCKER.md) | 容器部署。**容器里有三处宿主机默认值是错的**(§3);`cap_drop: ALL` 为什么能成立(§5 |
---
@@ -125,6 +126,20 @@ curl -sS --socks5-hostname alice:changeme@127.0.0.1:1080 https://example.com -o
`--socks5-hostname` 让 curl 把域名交给代理解析(DNS 不泄漏路径);`--socks5` 则是本地解析。
两条路径都支持。
### 用容器跑
```sh
cp docker/socks5.auth.example docker/socks5.auth # 改口令
docker compose up -d --build
```
镜像以 uid 10001、`cap_drop: ALL`、只读 rootfs 运行——不需要 `NET_ADMIN`,不需要
`/dev/net/tun`,这正是用户态终结隧道换来的东西,而容器让这句话第一次可以当场验证。
**但宿主机的默认配置在容器里有两处是静默错误的**(监听环回口、状态文件用相对路径),
所以镜像自带一份 `docker/openvpngate.conf` 覆盖它们。细节、暴露面取舍、以及这套编排
**哪些部分没有被真正跑过**,见 [docs/DOCKER.md](docs/DOCKER.md)。
---
## 4. 管理接口