最近做 APP 兼容性测试,需要在单台服务器同时拉起多个安卓容器,也就是 Docker 云手机。刚开始直接复制启动命令,没修改端口和存储目录,结果容器启动报错、ADB 端口冲突,VNC 远程画面串流,多个实例互相干扰。
很多新手以为只要多跑几条 docker run 命令就能实现多开,忽略三件核心事情:端口唯一映射、独立持久化存储、网络 / 资源隔离。一旦其中一项没处理,就会出现端口占用、实例数据混乱,甚至一个容器异常拖累整台宿主机。
目前主流自建 Docker 云手机方案用 Redroid,基于容器技术运行安卓系统。但自建多实例对 Linux 基础、内核模块、防火墙策略都有要求。如果不想从零维护整套隔离网络,六边云手机作为 Docker 云手机的代表,原生支持多实例部署,端口、存储、网络预先隔离,网页和 ADB 调试直接可用,适合开发者快速搭建测试环境。
一、核心原理:多实例为什么需要端口隔离
Redroid 容器内部固定端口:
- 5555:ADB 调试端口
- VNC/Scrcpy 图形服务端口
同一宿主机,容器内部端口可以完全一致,但映射到宿主机的外部端口不能重复。 举个例子:实例 1 宿主机端口 15555 映射容器 5555;实例 2 就必须换 15556 映射容器 5555。 每个实例配套独立数据卷,不能共用 /data 目录,否则安卓系统文件互相覆盖,会直接崩溃。
两种网络隔离方案选型
- 端口映射 bridge 桥接(推荐新手):单宿主机,不同宿主机端口转发到多个容器,部署简单,适合少量实例。
- macvlan 独立 IP 方案:每个容器分配独立 IP,不用端口映射,隔离度更高,适合大规模多实例,但是网络配置复杂,云 VPS 兼容性差。
本文重点讲解 bridge 桥接 + 独立端口,也是个人测试场景最常用方案。
二、实战部署:多实例 Redroid 启动命令
前提:宿主机提前装好 binder、ashmem 内核模块,Redroid 依赖这两个模块,否则容器启动黑屏。
实例 1(第一台云手机)
docker run -d \
--name redroid-01 \
--privileged \
--memory 2G \
--cpus 1 \
-v ~/redroid-data/inst01:/data \
-p 15555:5555 \
redroid/redroid:12.0.0-latest \
androidboot.redroid_gpu_mode=guest \
androidboot.width=1080 androidboot.height=1920
实例 2(第二台云手机,修改容器名称、数据目录、宿主机端口)
docker run -d \
--name redroid-02 \
--privileged \
--memory 2G \
--cpus 1 \
-v ~/redroid-data/inst02:/data \
-p 15556:5555 \
redroid/redroid:12.0.0-latest \
androidboot.redroid_gpu_mode=guest \
androidboot.width=1080 androidboot.height=1920
关键点说明:
--name容器名称必须唯一,不能重复;-v挂载的数据目录每个实例单独创建,分开持久化安卓数据;-p宿主机端口依次递增:15555、15556、15557,不能重复;--memory、--cpus做资源限制,防止其中一个实例占满服务器 CPU 内存,全部卡死。
执行完成,查看运行容器:
docker ps
访问方式:
- 实例 1:ADB 连接
宿主机IP:15555 - 实例 2:ADB 连接
宿主机IP:15556
三、使用 docker-compose 批量编排(实例多的时候推荐)
如果需要一次性拉起 3 台、5 台容器,逐条 docker run 效率太低,推荐 docker-compose 统一管理,方便启停。 新建docker-compose.yml
version: "3.8"
services:
redroid01:
image: redroid/redroid:12.0.0-latest
privileged: true
restart: always
ports:
- "15555:5555"
volumes:
- ./inst01:/data
deploy:
resources:
limits:
cpus: '1'
memory: 2G
command:
- androidboot.redroid_gpu_mode=guest
redroid02:
image: redroid/redroid:12.0.0-latest
privileged: true
restart: always
ports:
- "15556:5555"
volumes:
- ./inst02:/data
deploy:
resources:
limits:
cpus: '1'
memory: 2G
command:
- androidboot.redroid_gpu_mode=guest
启动所有实例:
docker-compose up -d
停止:
docker-compose down
四、网络安全与防火墙配置要点
- 宿主机防火墙 firewalld/ufw,逐个放行每一个宿主机 ADB 端口;云服务器还要在安全组添加入站规则。
注意:ADB 端口强烈不建议直接暴露公网,存在扫描爆破风险。生产 / 长期使用推荐 Tailscale 虚拟局域网或者 FRP 隧道访问。
-
容器之间默认可以互相通信,如果需要容器之间网络隔离,可以创建独立自定义 bridge 网络,不同实例加入不同网络。
创建独立网络
docker network create net-inst1
docker network create net-inst2启动容器时增加参数 --network net-inst1
不同 network 内的容器默认无法互相访问,隔离程度更高。
五、高频踩坑点总结
- 忘记修改宿主机端口,直接复制命令,端口占用,容器启动失败。 排查:
ss -lntp查看端口占用情况。 - 多个实例共用同一个 data 数据目录,安卓系统文件冲突,开机闪退。
每个实例必须独立 volume。
- 不做 CPU 内存限制,单个容器负载过高,整台服务器卡顿。多开一定要配置资源上限。
- 防火墙 / 云安全组只开放第一个端口,新增实例的端口没有放行,外网无法访问第二个云手机。
- 内核缺少 binder/ashmem 模块,容器虽然启动成功,但是 VNC 黑屏,就是前面文章提到的经典问题。
六、自建多实例 vs 成品 Docker 云手机对比
- Redroid 自建方案
- ✅优点:完全自定义镜像、分辨率、参数,自由度高;
- ❌缺点:需要自行编译内核模块、维护端口、防火墙、存储隔离;实例越多,运维工作量越大,大量排坑。适合熟悉 Linux 的技术人员做技术研究。
- 六边云手机(Docker 云手机代表)
- ✅底层基于 Docker 容器架构,原生支持多实例创建,端口、数据、网络自动隔离。开箱自带 ADB,不用手动处理 binder、ashmem 内核模块,不用一条条配置端口映射与防火墙。适合 APP 测试、需要多台独立安卓环境的开发人员,省去大量底层网络调试。
- ❌自定义底层内核的自由度不如纯自建 Redroid。
七、结尾
Docker 多开云手机,核心就是端口不冲突、数据分开存储、资源配额限制 。少量实例可以直接 docker run,数量多推荐 docker-compose 批量编排。 自建 Redroid 虽然灵活,但是整套网络隔离、内核适配、防火墙规则维护成本很高。如果你的目标是快速拿到多个隔离安卓容器用于 APP 测试,不想持续处理网络和驱动问题,可以考虑六边云手机,Docker 容器架构,多实例开箱即用。