Skip to content

Commit cc42578

Browse files
author
Developer
committed
ws: 使用宿主机版mysql,docker 不再起 mysql 容器
- docker-compose 移除 mysql 服务,agent/provision 通过 host.docker.internal 连接宿主机 MySQL,连接信息通过 .env 配置 - 宿主机 binlog 目录只读挂载进 agent 容器,config 的 binlog_dir 覆盖为 挂载点(避免 Windows 路径自动发现失败) - provision 脚本 MySQL 连接参数化;e2e-test.sh 改用宿主机 mysql 客户端, 启动前校验 binlog_format=ROW 并自动创建测试库 - 新增 .env.example;deploy/README.md 增加 Host MySQL setup 章节
1 parent 8152f1e commit cc42578

5 files changed

Lines changed: 170 additions & 67 deletions

File tree

.env.example

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# ============================================================================
2+
# mysql-pitr docker compose — 宿主机 MySQL 配置
3+
# 复制为 .env 并填写后:docker compose up -d
4+
# ============================================================================
5+
6+
# 宿主机 MySQL 连接(agent / provision 通过 host.docker.internal 访问)
7+
# Windows 下 Docker Desktop 内置 host.docker.internal;Linux 需在
8+
# docker-compose.yml 中保留 extra_hosts(已配置)
9+
MYSQL_HOST=host.docker.internal
10+
MYSQL_PORT=3306
11+
# 需要允许来自容器网段的访问,例如:
12+
# CREATE USER 'pitr'@'%' IDENTIFIED BY '密码';
13+
# GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'pitr'@'%';
14+
# GRANT SELECT ON `你的库`.* TO 'pitr'@'%';
15+
# (用 root 也可以,但需授权 root@'%' 或 root@'172.%')
16+
MYSQL_USER=root
17+
MYSQL_PASSWORD=你的MySQL密码
18+
MYSQL_DATABASE=mysql
19+
20+
# 宿主机 MySQL 数据目录(包含 binlog 文件),只读挂载进 agent 容器。
21+
# Windows 默认:C:\ProgramData\MySQL\MySQL Server 8.0\Data
22+
# Linux 默认:/var/lib/mysql
23+
MYSQL_BINLOG_DIR_HOST=C:/ProgramData/MySQL/MySQL Server 8.0/Data
24+
25+
# agent 加密配置口令(serve 启动时使用)
26+
PITR_PASSPHRASE=pitr-test

deploy/README.md

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,71 @@ agent, issues its mTLS certificate from the server's internal CA, and writes
4545
the encrypted agent config — so `docker compose up` brings up a working
4646
agent-connected stack end to end.
4747

48+
> **Using MySQL on the host?** The stack is configured for a host MySQL out
49+
> of the box — no MySQL container is started. See
50+
> [Host MySQL setup](#host-mysql-setup) below.
51+
4852
```bash
4953
git clone https://github.com/a-shan/mysql-pitr.git
5054
cd mysql-pitr
5155

52-
# Start all services (provision runs once, then the agent connects)
56+
# 1. Configure the host MySQL connection (see .env.example)
57+
cp .env.example .env
58+
# edit .env: MYSQL_PASSWORD, MYSQL_BINLOG_DIR_HOST, ...
59+
60+
# 2. Start all services (provision runs once, then the agent connects)
5361
docker compose up -d
5462

55-
# Watch the agent come online
63+
# 3. Watch the agent come online
5664
docker compose logs -f agent
5765
```
5866

5967
This starts:
6068

61-
- **mysql** — MySQL 8.0 with binary logging enabled (required for PITR)
6269
- **provision** — one-shot: CA extraction, agent registration, cert issuance
63-
- **agent**`mysql-pitr-agent serve`, connected to the server hub
70+
- **agent**`mysql-pitr-agent serve`, connected to the server hub; reads
71+
the **host** MySQL's binlog directory (mounted read-only)
6472
- **server** — web dashboard + API (`localhost:8080`) and the mTLS agent
6573
endpoint (`localhost:9443`)
6674

75+
### Host MySQL setup
76+
77+
The agent connects to MySQL on the host via `host.docker.internal` and reads
78+
the host's binlog files from a mounted directory. Prepare the host MySQL once:
79+
80+
1. **Enable ROW binlog** — in `my.ini` under `[mysqld]`:
81+
82+
```ini
83+
log-bin=mysql-bin
84+
binlog-format=ROW
85+
binlog-row-image=FULL
86+
```
87+
88+
then restart the MySQL service. Windows example path for the data
89+
directory: `C:\ProgramData\MySQL\MySQL Server 8.0\Data` (where the
90+
`mysql-bin.*` files live).
91+
92+
2. **Create a dedicated account** for the agent (containers connect from the
93+
Docker bridge network, so `root@localhost` won't work):
94+
95+
```sql
96+
CREATE USER 'pitr'@'%' IDENTIFIED BY 'change-me';
97+
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'pitr'@'%';
98+
GRANT SELECT ON `mydb`.* TO 'pitr'@'%';
99+
```
100+
101+
3. **Fill in `.env`** (copy from `.env.example`):
102+
103+
| Variable | Description |
104+
|---|---|
105+
| `MYSQL_HOST` | `host.docker.internal` (Docker Desktop built-in) |
106+
| `MYSQL_USER` / `MYSQL_PASSWORD` | the account above |
107+
| `MYSQL_BINLOG_DIR_HOST` | host MySQL data dir, e.g. `C:/ProgramData/MySQL/MySQL Server 8.0/Data` |
108+
| `PITR_PASSPHRASE` | passphrase for the encrypted agent config |
109+
110+
Linux note: if `host.docker.internal` does not resolve, use the host's LAN
111+
IP in `MYSQL_HOST` and grant the account to `'pitr'@'%'`.
112+
67113
---
68114

69115
## Quick Start (systemd / bare metal)
@@ -176,11 +222,13 @@ target schema, `REPLICATION SLAVE`, `REPLICATION CLIENT`).
176222

177223
### Production docker-compose.yml
178224

179-
Use the included `docker-compose.yml` as a starting point. For production:
225+
Use the included `docker-compose.yml` as a starting point (host MySQL — see
226+
[Host MySQL setup](#host-mysql-setup)). For production:
180227

181-
1. **Change default passwords** — override `MYSQL_ROOT_PASSWORD` and the
182-
provision/agent config values
183-
2. **Persist MySQL data** — named volumes are already mounted; keep them
228+
1. **Change default passwords** — set `MYSQL_PASSWORD` and `PITR_PASSPHRASE`
229+
in `.env`; use a dedicated MySQL account instead of root
230+
2. **Persist volumes**`server-data` (CA material) and `agent-data`
231+
(checkpoints) are named volumes; keep them
184232
3. **Place the web server behind a reverse proxy** (nginx, Caddy, Traefik)
185233
with TLS; the agent endpoint (`:9443`) already speaks TLS with its own
186234
internal CA

docker-compose.yml

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
11
version: '3.8'
22

3-
services:
4-
mysql:
5-
image: mysql:8.0
6-
environment:
7-
MYSQL_ROOT_PASSWORD: pitr_test
8-
MYSQL_DATABASE: pitr_test
9-
command: --binlog-format=ROW --binlog-row-image=FULL --log-bin=mysql-bin
10-
ports:
11-
- "3306:3306"
12-
volumes:
13-
- mysql-data:/var/lib/mysql
14-
networks:
15-
- pitr-network
16-
healthcheck:
17-
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
18-
interval: 10s
19-
timeout: 5s
20-
retries: 5
3+
# 使用宿主机 MySQL(不在 Docker 内另起 mysql 容器)。
4+
# 连接信息与 binlog 目录通过 .env 配置(参考 .env.example):
5+
# - agent / provision 通过 host.docker.internal 访问宿主机 MySQL
6+
# - 宿主机的 MySQL 数据目录(含 binlog 文件)只读挂载进 agent 容器
7+
# - 宿主机 MySQL 必须开启 binlog:log-bin=mysql-bin、binlog-format=ROW、
8+
# binlog-row-image=FULL(Windows: my.ini 中 [mysqld] 段)
219

22-
# One-shot provisioning: waits for the server CA, registers an agent via
23-
# the API, issues its mTLS client certificate, and writes the encrypted
24-
# agent config into the shared agent-config volume.
10+
services:
11+
# 一次性初始化:提取 server CA → 通过 API 注册 agent → 签发 mTLS 证书 →
12+
# 写入加密的 agent 配置(MySQL 连接指向宿主机)
2513
provision:
2614
build:
2715
context: .
2816
target: agent
2917
entrypoint: ["/bin/sh", "/scripts/e2e-provision.sh"]
3018
environment:
31-
PITR_PASSPHRASE: pitr-test
19+
PITR_PASSPHRASE: ${PITR_PASSPHRASE:-pitr-test}
20+
MYSQL_HOST: ${MYSQL_HOST:-host.docker.internal}
21+
MYSQL_PORT: ${MYSQL_PORT:-3306}
22+
MYSQL_USER: ${MYSQL_USER:-root}
23+
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
24+
MYSQL_DATABASE: ${MYSQL_DATABASE:-mysql}
25+
# 容器内挂载点,config 的 binlog_dir 指向此处(覆盖 Windows 路径自动发现)
26+
MYSQL_BINLOG_DIR: /var/lib/mysql
3227
depends_on:
3328
server:
3429
condition: service_started
3530
volumes:
3631
- ./scripts:/scripts:ro
3732
- server-data:/var/lib/mysql-pitr:ro
3833
- agent-config:/etc/agent
34+
- ${MYSQL_BINLOG_DIR_HOST:?set MYSQL_BINLOG_DIR_HOST in .env (host MySQL data dir)}:/var/lib/mysql:ro
35+
extra_hosts:
36+
- "host.docker.internal:host-gateway"
3937
networks:
4038
- pitr-network
4139
restart: "no"
@@ -44,14 +42,16 @@ services:
4442
build:
4543
context: .
4644
target: agent
47-
command: ["serve", "--config=/etc/agent/config.json", "--passphrase=pitr-test"]
45+
command: ["serve", "--config=/etc/agent/config.json", "--passphrase=${PITR_PASSPHRASE:-pitr-test}"]
4846
depends_on:
4947
provision:
5048
condition: service_completed_successfully
5149
volumes:
52-
- mysql-data:/var/lib/mysql:ro
50+
- ${MYSQL_BINLOG_DIR_HOST:?set MYSQL_BINLOG_DIR_HOST in .env (host MySQL data dir)}:/var/lib/mysql:ro
5351
- agent-config:/etc/agent:ro
5452
- agent-data:/var/lib/mysql-pitr
53+
extra_hosts:
54+
- "host.docker.internal:host-gateway"
5555
networks:
5656
- pitr-network
5757
restart: unless-stopped
@@ -64,22 +64,17 @@ services:
6464
- "8080:8080"
6565
- "9443:9443"
6666
environment:
67-
DATABASE_URL: "root:pitr_test@tcp(mysql:3306)/pitr_server"
6867
LISTEN_ADDR: ":8080"
6968
AGENT_LISTEN_ADDR: ":9443"
7069
AGENT_DATA_DIR: /var/lib/mysql-pitr
7170
AGENT_CERT_HOSTS: "server,localhost,127.0.0.1"
7271
volumes:
7372
- server-data:/var/lib/mysql-pitr
74-
depends_on:
75-
mysql:
76-
condition: service_healthy
7773
networks:
7874
- pitr-network
7975
restart: unless-stopped
8076

8177
volumes:
82-
mysql-data:
8378
server-data:
8479
agent-data:
8580
agent-config:

scripts/e2e-provision.sh

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#!/bin/sh
22
# ============================================================================
3-
# E2E provisioning: register an agent, issue its mTLS certificate from the
3+
# Provisioning: register an agent, issue its mTLS certificate from the
44
# server's internal CA, and write the encrypted agent config.
55
#
66
# Runs once inside the `provision` compose service (agent image). Expects:
77
# - server:8080 reachable (REST API)
88
# - /var/lib/mysql-pitr/ca.json (server CA, created on server startup)
99
# - /etc/agent writable (agent-config volume)
10+
# - MYSQL_HOST / MYSQL_PASSWORD etc. set by compose (host MySQL)
1011
# ============================================================================
1112
set -e
1213

@@ -17,6 +18,14 @@ DATA_DIR="/var/lib/mysql-pitr"
1718
CONFIG_DIR="/etc/agent"
1819
PASSPHRASE="${PITR_PASSPHRASE:-pitr-test}"
1920

21+
# Host MySQL connection (configured via .env, see docker-compose.yml).
22+
MYSQL_HOST="${MYSQL_HOST:-host.docker.internal}"
23+
MYSQL_PORT="${MYSQL_PORT:-3306}"
24+
MYSQL_USER="${MYSQL_USER:-root}"
25+
MYSQL_PASSWORD="${MYSQL_PASSWORD:?set MYSQL_PASSWORD in .env}"
26+
MYSQL_DATABASE="${MYSQL_DATABASE:-mysql}"
27+
MYSQL_BINLOG_DIR="${MYSQL_BINLOG_DIR:-/var/lib/mysql}"
28+
2029
echo "[provision] waiting for server CA..."
2130
for i in $(seq 1 60); do
2231
[ -f "$DATA_DIR/ca.json" ] && break
@@ -77,19 +86,20 @@ echo "[provision] writing encrypted agent config..."
7786
cat > "$CONFIG_DIR/plain.json" <<EOF
7887
{
7988
"mysql": {
80-
"host": "mysql",
81-
"port": 3306,
82-
"user": "root",
83-
"password": "pitr_test",
84-
"database": "pitr_test"
89+
"host": "$MYSQL_HOST",
90+
"port": $MYSQL_PORT,
91+
"user": "$MYSQL_USER",
92+
"password": "$MYSQL_PASSWORD",
93+
"database": "$MYSQL_DATABASE"
8594
},
8695
"server": {
8796
"url": "wss://server:9443/ws/agent",
8897
"cert_file": "$CONFIG_DIR/client.pem",
8998
"key_file": "$CONFIG_DIR/client-key.pem",
9099
"ca_file": "$CONFIG_DIR/ca.pem"
91100
},
92-
"data_dir": "/var/lib/mysql-pitr"
101+
"data_dir": "/var/lib/mysql-pitr",
102+
"binlog_dir": "$MYSQL_BINLOG_DIR"
93103
}
94104
EOF
95105

0 commit comments

Comments
 (0)