小团队想要"项目管理 + 远程办公"的基础设施,开源圈有几款久经考验的组合:
- 禅道(Zentao):国产老牌项目管理软件,支持需求/任务/缺陷/Bug 全生命周期,开源版免费。
- FRP(Fast Reverse Proxy):把内网服务(如家里的 NAS、办公室的服务器)暴露到公网,比 ssh 反向隧道更稳定。
- RustDesk:开源远程桌面(TeamViewer 替代品),服务端自建——数据完全可控。
这三者搭配,就构成一套"自建、不依赖第三方、够用"的远程协作工具链。
阅读对象:小团队 admin / 运维 / 想从 TeamViewer/钉钉/企业微信项目里迁出来的同学。
覆盖范围:禅道 Docker 部署(v18.3/21.4)、升级流程;FRP 客户端配置(tcp 代理 ssh/mysql);RustDesk 服务端 docker-compose、Key 生成、客户端使用。
一、禅道项目管理(Zentao)
禅道是国产开源项目管理的代表,2009 年发布,2021 年起进入"专业版/企业版/旗舰版/IPD"矩阵。开源版(zentao 18.x / 21.x)就够中小团队用。
1.1 版本对比
| 版号 | 类型 | 适合 |
|---|
zentao 18.x | 开源版(PHP 7) | 经典稳定 |
zentao 21.x | 开源版(PHP 8) | 新项目推荐 |
pro+数字 | 专业版 | 甘特图、APP、LDAP |
biz / max / ipd | 企业版/旗舰版/IPD | 中大型企业 |
1.2 Docker 部署
1
2
3
4
5
6
7
8
9
10
| # 拉镜像
docker pull easysoft/zentao:18.3
# 启动
docker run -d --name zentao --restart=always \
-p 9999:80 \
-v /home/docker/zentao/pms:/www/zentaopms \
-v /home/docker/zentao/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD={{REDACTED}} \
easysoft/zentao:18.3
|
关键参数:
-v /home/docker/zentao/pms:/www/zentaopms:禅道代码、附件的持久化-v /home/docker/zentao/mysql:/var/lib/mysql:MySQL 数据的持久化- 这两个目录必须是空目录(首次启动会初始化)
1.3 访问与初始化
访问 http://<宿主机IP>:9999:
- 几分钟后跳到登录页
- 数据库密码 = 启动时的
MYSQL_ROOT_PASSWORD({{REDACTED}}) - 选"全生命周期"模式
- 设置管理员账号(密码 6+,大小写+数字)
完整初始化流程约 3-5 分钟。
1.4 21.4 版本(PHP 8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| docker pull hub.zentao.net/app/zentao:21.4
# 21.4 支持外部 MySQL(推荐)
docker run -it \
-v /home/docker/zentao/data:/data \
-p 80:80 \
-e ZT_MYSQL_HOST=<mysql_host> \
-e ZT_MYSQL_PORT=3306 \
-e ZT_MYSQL_USER=root \
-e ZT_MYSQL_PASSWORD={{REDACTED}} \
-e ZT_MYSQL_DB=zentao \
-e ZT_REDIS_HOST=redis \
-e ZT_REDIS_PORT=6379 \
-e ZT_REDIS_PASSWORD={{REDACTED}} \
-e ZT_CACHE_TYPE=redis \
hub.zentao.net/app/zentao:21.4
|
21.x 把 MySQL 拆出来做外部依赖,更适合"禅道 + 业务共享一套 MySQL"的场景。
1.5 升级
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 1. 停止并删除旧容器
docker stop zentao
docker rm zentao
# 2. 备份数据
cp -rp /home/docker/zentao/pms /home/docker/zentao_pms_$(date +%Y%m%d)
cp -rp /home/docker/zentao/mysql /home/docker/zentao_mysql_$(date +%Y%m%d)
# 3. 拉新镜像
docker pull hub.zentao.net/app/zentao:21.4
# 4. 重新启动(沿用旧数据目录)
docker run --name zentao \
-p 80:80 \
--network=zentaonet \
--ip 172.172.172.172 \
-v /home/docker/zentao/pms:/www/zentaopms \
-v /home/docker/zentao/mysql:/var/lib/mysql \
-e MYSQL_INTERNAL=true \
-d hub.zentao.net/app/zentao:18.7
|
升级关键:数据目录 + MySQL 目录保留,只换镜像。禅道会自动检测版本、跑升级 SQL。
1.6 备份脚本
1
2
3
4
5
6
7
8
9
10
| # 1. 停禅道
docker stop zentao
# 2. 打包
tar -czf /backup/zentao_$(date +%Y%m%d).tar.gz \
/home/docker/zentao/pms \
/home/docker/zentao/mysql
# 3. 启动
docker start zentao
|
二、FRP 内网穿透
FRP(Fast Reverse Proxy) 是一个高性能的反向代理应用,可以把内网机器的 SSH、MySQL、Web 服务暴露到公网。比 ssh -R 稳定,比 ngrok 私有化。
2.1 架构
1
2
3
4
| [内网机器 A] [公网 VPS]
frpc ──tcp──► frps :7000
ssh:22 ─────► 公网 IP:6190
mysql:3306 ───► 公网 IP:6191
|
2.2 公网 VPS 部署 frps
1
2
3
4
5
6
7
| # 下载服务端
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
tar xf frp_0.52.3_linux_amd64.tar.gz
cd frp_0.52.3_linux_amd64
# 启动服务端
./frps -c frps.ini
|
frps.ini 关键配置:
1
2
3
4
5
6
| [common]
bind_port = 7000
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = {{REDACTED}}
token = {{REDACTED}}
|
2.3 内网机器部署 frpc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| mkdir -p /home/docker/rp
cat << 'EOF' > /home/docker/rp/frpc.toml
serverAddr = "1.2.3.4" # 公网 VPS IP
serverPort = 7000
auth.method = "token"
auth.token = "{{REDACTED}}"
[[proxies]]
name = "office-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6190
[[proxies]]
name = "office-mysql"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3306
remotePort = 6191
EOF
|
2.4 Docker 启动 frpc
1
2
3
4
5
| docker run -d --restart=always \
--name frpc \
--network host \
-v /home/docker/rp/frpc.toml:/etc/frp/frpc.toml \
snowdreamtech/frpc:0.52.3
|
多台内网机器:每台跑 frpc,分配不同的 remotePort 即可。frps 自动路由。
2.5 验证
1
2
3
4
5
| # 在公网 VPS 测试 SSH 到内网机器
ssh -p 6190 user@1.2.3.4
# 在业务服务器连内网 MySQL
mysql -h 1.2.3.4 -P 6191 -u root -p
|
三、RustDesk 远程桌面(自建 Server)
TeamViewer 商业版贵、向日葵限速。RustDesk 是开源替代品(Rust 写的),服务端自建、客户端开源,远程控制数据不经过第三方。
3.1 架构
1
2
3
4
5
| [被控端] ──tcp/udp──► [RustDesk Server] ◄──tcp── [主控端]
21115 (NAT)
21116 (ID 注册)
21117 (Relay)
21118 (WebSocket)
|
3.2 服务端 docker-compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| mkdir -p /home/docker/rustdesk/data
cat << 'EOF' > /home/docker/rustdesk/docker-compose.yaml
version: "3"
services:
rustdesk-server:
container_name: rustdesk-server
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21117:21117
- 21118:21118
- 21119:21119
image: rustdesk/rustdesk-server-s6:latest
environment:
- "RELAY=internal.example.com:21117"
- "ENCRYPTED_ONLY=1"
volumes:
- /home/docker/rustdesk/data:/data
restart: unless-stopped
EOF
docker-compose -f /home/docker/rustdesk/docker-compose.yaml up -d
|
关键参数:
RELAY:内网穿透地址,客户端连接不上时走 relayENCRYPTED_ONLY=1:强制端到端加密(防止 relay 服务器偷看)
3.3 提取服务端 Key
1
2
| cat /home/docker/rustdesk/data/id_ed25519.pub
# 输出形如:YFdhkFcz19pQBzEbCdf2weNt3PSmyzeHHyhRkKhyTI0=
|
Key 必须在客户端配置,否则连不上自建 server。
3.4 客户端使用
下载地址:github.com/rustdesk/rustdesk/releases
Windows / macOS / Linux / Android / iOS 全平台。
配置 ID Server:
- 打开 RustDesk → 设置 → 网络
- ID 服务器:
<公网IP或域名> - Key:粘贴上一步提取的
id_ed25519.pub - 中继服务器:
<公网IP>:21117
客户端 ID 是自动生成的(如 825 391 728),告诉对方这个 ID 就能远程。
3.5 防火墙开放端口
1
2
3
4
5
6
7
8
9
| # Ubuntu/Debian
ufw allow 21115:21119/tcp
ufw allow 21116/udp
ufw reload
# CentOS
firewall-cmd --add-port=21115-21119/tcp --permanent
firewall-cmd --add-port=21116/udp --permanent
firewall-cmd --reload
|
四、组合:自建远程协作套件
| 角色 | 工具 | 替代品 |
|---|
| 项目管理 | 禅道(自建) | Jira(商业)、Teambition、飞书项目 |
| 文档协作 | (可选)Outline / BookStack | Confluence、Notion |
| 远程桌面 | RustDesk(自建) | TeamViewer、向日葵 |
| 内网穿透 | FRP(自建) | ngrok(商业)、cpolar |
| 即时通讯 | (可选)Rocket.Chat / Mattermost | 钉钉、企业微信、Slack |
小团队 5-20 人成本几乎为 0(VPS 一年 200 元),数据全在自己手里。
五、扩展阅读