STF STF 开发环境搭建与制作 docker 镜像过程

blueshark · 2016年06月19日 · 最后由 张三 回复于 2021年02月28日 · 7981 次阅读
本帖已被设为精华帖!

一、前言

看到很多同学在研究 STF,大部分人只是讲了怎么安装,然后运行一个 stf local 命令可以开始使用了,但是在实际使用中,比如大公司中肯定不能使用 stf local 方式给大家演示一下吧,哈哈~~~

另外也不能使用 mock 方式让任何人都能随意的登录。如果你想自己定制一些东西,需要自己对源码进行一些修改,说实话,想随意修改 stf 源码还真不是一件特别简单的事。下面根据我自己的一些经验介绍一个生产环境中 stf 平台的搭建及一些开发注意事项,希望想了解的同学不要踩这些坑。
参考前辈的一些文章,特别是 monkey 的 “STF 改造之 first blood”,给了我很大帮助,多谢他们!

(1)STF 改造之 first blood

(2)MAC 下 STF 的环境搭建和运行

(3)WEB 端批量移动设备管理控制工具 STF 的环境搭建和运行

二、生产环境中 STF 平台的搭建

这里是官方的搭建文档:
Deployment

官方推荐使用 docker 容器来搭建,根据我的使用经验,docker 容器确实更方便一些,关于 docker 的知识就不作介绍了,详情可以自行搜索,或者参考 docker 官方网站。

使用 docker 搭建 STF 平台需要 pull 下来五个镜像,这里假设你已经安装过了 docker 容器,为了加快 pull 速度,可以参考下面的文章,换成国内的 docker 镜像

Docker 学习笔记 — 配置国内免费 registry mirror

确定安装好 docker 以后,pull 下面几个镜像:

docker pull openstf/stf:latest
docker pull sorccu/adb:latest
docker pull rethinkdb:latest
docker pull openstf/ambassador:latest
docker pull nginx:latest

拉下来这几个镜像以后,stf 就可以直接在容器中运行了,也就是说你宿主机上完全不用再装 stf 的相关工具,甚至 adb 也不用。

很多文章介绍的装 stf 要先装一堆工具,然后使用 npm install -g stf 安装到系统中,大部分人会发现,由于网络或者其他原因,npm install -g stf 方式也不太容易成功,其实在 docker 里也可以直接运行 stf local,并且更加简单,使用以下三条命令即可:

#先启动一个数据库
docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090
#再启动adb service
docker run -d --name adbd --privileged -v /dev/bus/usb:/dev/bus/usb --net host sorccu/adb:latest
#再启动stf
docker run -d --name stf --net host openstf/stf stf local --public-ip your-ip

这样就可以直接从 7100 端口也访问了,下面介绍正宗的安装方式,先介绍下几个组件:

  • openstf/stf 就是 stf 主镜像了。

  • sorccu/adb 是 adb 工具,adb 工具是和 provider 模块在一台机器上的,这个后面会再说。

  • rethinkdb 就是数据库了,不知道开发者为什么想用这个数据库,而不用常用的 mysql 之类的,反正感觉这个数据库挺另类的,和 mysql 的查询语法完全不一样。 这里注意,官方文档上要 pull rethinkdb:2.1.1,但是现在版本的 stf 好像不支持 rethinkdb:2.1.1,经测试,最新版本的 rethinkdb 也是没问题的,所以就用最新的了。

  • openstf/ambassador 这个网络代理工具,是连接 docker 内部网络的一个工具,估计作者是基于 ambassador 官方镜像进行修改的,ambassador 可以让不同 dokcer 之前以私有网络的方式进行连接,可以理解为虚拟网络,如果你把所有的端口暴露在外面,这个东西也可以不要。

  • nginx,这是一个 web 服务器反向代理工具,详细的就不介绍了,反正 stf 依赖它将不同的 url 转发到不同模块上,反正没有 nginx,生产环境中的 stf 是肯定不能正常工作的。

好了,docker 镜像讲完了,下面就是搭建过程了,为了简单,所有的模块搭建在一台机器上,如果要搭建在不同机器,修改 nginx 里的反向代理 server 就行了。其实搭建就是启动几个 docker 容器,设置一些端口的事情。stf 作者希望用 systemd 来启动这些容器,在官方部署文档上可以看到类似下面的代码

[Unit]
Description=ADB daemon
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStartPre=/usr/bin/docker pull sorccu/adb:latest
ExecStartPre=-/usr/bin/docker kill %p
ExecStartPre=-/usr/bin/docker rm %p
ExecStart=/usr/bin/docker run --rm \
  --name %p \
  --privileged \
  -v /dev/bus/usb:/dev/bus/usb \
  --net host \
  sorccu/adb:latest
ExecStop=-/usr/bin/docker stop -t 2 %p

刚开始我纠结了几天,不知道这是个什么东西,其实它就是一个启动工具,跟手动执行 shell 命令是一样样的,只不过可以开机启动,或者在失败以后可以自动重启。在使用 sysyted 启动的系统中,systemd 所有可用的单元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录(后者优先级更高),可以去这两个目录看看已经有脚本。

ubuntu 15.04 和 centos7 以后的版本都是使用 systemd 进行启动的,如果你用的这些系统,可以考虑使用 systemd 来启动 stf 容器,确实更方便一些,如果你不要使用 systemd,使用 shell 脚本也是可以的,为了更好理解,下面介绍时会 shell 脚本来启动。

为了搭建更加顺利,先介绍几个 docker 命令:

#运行docker镜像,不再多说
docker run 一大堆参数
#查看所有的docker镜像
docker images
#查看所有的docker运行实例
docker ps -a
#停止/杀死/删除/重启 docker实例
docker stop/kill/rm/restart
#查看docker的log
docker logs 实例名或ID

其中 docker logs 比较重要,docker 实例出了什么问题可以查看 log。

启动过程:

1、启动 nginx

一般来说,nginx 肯定要第一个启动的,因为它要转发不同 url 到不同的模块,启动 nginx 需要一个 nginx.conf 配置文件,官方给的配置文件比较复杂,而且启用了 ssl,我想大部分公司都不会在内网用 ssl 吧,所以就修改了一个简单的版本如下,这里的配置需要你根据情况来修改:

daemon off;
worker_processes 4;

events {
  worker_connections 1024;
}

http {
  upstream stf_app {
    server 192.168.3.16:3100 max_fails=0;
  }

  upstream stf_auth {
    server 192.168.3.16:3200 max_fails=0;
  }

  upstream stf_storage_apk {
    server 192.168.3.16:3300 max_fails=0;
  }

  upstream stf_storage_image {
    server 192.168.3.16:3400 max_fails=0;
  }

  upstream stf_storage {
    server 192.168.3.16:3500 max_fails=0;
  }

  upstream stf_websocket {
    server 192.168.3.16:3600 max_fails=0;
  }

  types {
    application/javascript  js;
    image/gif               gif;
    image/jpeg              jpg;
    text/css                css;
    text/html               html;
  }

  map $http_upgrade $connection_upgrade {
    default  upgrade;
    ''       close;
  }

  server {
    listen 80;
    server_name stf.test;
    keepalive_timeout 70;
    root /dev/null;

    resolver 127.0.0.1 valid=300s;
    resolver_timeout 10s;

    # Handle stf-provider@floor4.service
    location ~ "^/d/floor4/([^/]+)/(?<port>[0-9]{5})/$" {
      proxy_pass http://192.168.3.16:$port/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header X-Real-IP $remote_addr;
    }

    location /auth/ {
      proxy_pass http://stf_auth/auth/;
    }

    location /s/image/ {
      proxy_pass http://stf_storage_image;
    }

    location /s/apk/ {
      proxy_pass http://stf_storage_apk;
    }

    location /s/ {
      client_max_body_size 1024m;
      client_body_buffer_size 128k;
      proxy_pass http://stf_storage;
    }

    location /socket.io/ {
      proxy_pass http://stf_websocket;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $http_x_real_ip;
    }

    location / {
      proxy_pass http://stf_app;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $http_x_real_ip;
    }
  }
}

nginx 启动命令

docker run -d -v /home/blueshark/stf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro --name nginx --net host nginx nginx

启动 nginx 以后就可以访问你的网站,看看有没起来,正常起来的现象是报一个 nginx 的错误,没错,是报一个错误,因为其他服务还没起。

好了,nginx 起来了,下面就是 db 了。

2、启动 rethinkdb

数据库当然要比其他模块要早一点儿启动,否则影响连接嘛,rethinkdb 启动命令

docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090

启动完去用浏览器访问一下 8090 端口看看,如果能看到 rethinkdb 的管理界面就是 OK 的。

3、给数据库建表

rethinkdb 启动以后,要给 stf 建立相关的表,openstf/stf 镜像提供了这个功能,执行下面这条命令即可

docker run -d --name stf-migrate --net host  openstf/stf stf migrate

可以使用 docker logs 来查看命令的执行状态

docker logs stf-migrate

4、下面要启动一堆 storage 等,这些模块在 stf 截图和安装 app 时会用到


docker run -d --name storage-plugin-apk-3300 -p 3300:3000 --dns 192.168.1.5 openstf/stf stf storage-plugin-apk --port 3000   --storage-url http://stf.test/
docker run -d --name storage-plugin-image-3400  -p 3400:3000 --dns 192.168.1.5 openstf/stf stf storage-plugin-image --port 3000 --storage-url http://stf.test/
docker run -d  --name storage-temp-3500 -v /mnt/storage:/data -p 3500:3000 --dns 192.168.1.5 openstf/stf  stf storage-temp --port 3000  --save-dir /data

这里要注意几点,stf 官方 docker 镜像使用的 google dns,但是大部分公司都有自己的内网域名,因此必须换成自己的 dns,否则内网域名没法访问。如果你有需要持久保存的数据,最好用-v 对 docker 中的目录进行映射。这里使用-p 参数把 docker 内的端口绑定到主机端口,否则都是 3000 会冲突。

5、三方代理

说实话,这个东西我也是很懂,感觉是跟总线一样的东西,这个模块的启动顺序不一定放到这里,反正我是按照这个顺序来的,能工作

docker run -d  --name triproxy-app  --net host  openstf/stf  stf triproxy app   --bind-pub "tcp://*:7150"   --bind-dealer "tcp://*:7160"  --bind-pull "tcp://*:7170"
docker run -d --name triproxy-dev  --net host  openstf/stf  stf triproxy dev  --bind-pub "tcp://*:7250"  --bind-dealer "tcp://*:7260" --bind-pull "tcp://*:7270"

6、登录授权

登录授权的重要性不言自明,没人希望自己的手机被别人随意使用,最后也不知道谁用了。

docker run -d --name stf-auth3200 -e "SECRET=YOUR_SESSION_SECRET_HERE" -p 3200:3000 --dns 192.168.1.5 openstf/stf stf auth-mock --port 3000  --app-url http://stf.test/

默认情况下的 mock 登录随便输入 name 和 email 登录,当然可以自己接入自己的授权系统。

7、stf-app

这个就是主 web 界面了。

docker run -d --name stf-app3100 --net host -e "SECRET=YOUR_SESSION_SECRET_HERE" -p 3100:3000 openstf/stf stf app --port 3100 --auth-url http://stf.test/auth/mock/ --websocket-url http://stf.test/

启动到这里,访问 stf.test 网站,应该有点儿模样了。

8、stf-processor、websocket、reaper

processor 和 websocket 不知道具体是干什么的,这和消息队列好像有点儿关系,但是 reaper 是用来不断监控手机的在线状态的。

#stf-processor
docker run -d --name stf-processor --net host openstf/stf  stf processor stf-processor.service --connect-app-dealer tcp://192.168.3.16:7160 --connect-dev-dealer tcp://192.168.3.16:7260

#websocket 3600
docker run -d --name websocket -e "SECRET=YOUR_SESSION_SECRET_HERE" --net host openstf/stf stf websocket --port 3600  --storage-url http://stf.test/ --connect-sub tcp://192.168.3.16:7150 --connect-push tcp://192.168.3.16:7170

#reaper
docker run -d --name reaper --net host openstf/stf stf reaper dev --connect-push tcp://192.168.3.16:7270  --connect-sub tcp://192.168.3.16:7150 --heartbeat-timeout 30000

至此为至,stf 主框架已经搭起来了,就等 provider 给提供手机了。

9、provider

provider 的作为就是给主框架提供手机,注意,provider 可以运行在同一台机器,也可以运行在其他机器,但是,这台机器一定要可直接访问的,因为手机屏幕其实就是从这里出来的。

在 provider 机器上一定要先运行 adb 的 docker,毕竟安卓手机要依赖 adb 调试

#adb services
docker run -d --name adbd --privileged -v /dev/bus/usb:/dev/bus/usb --net host sorccu/adb:latest

下面就可以运行 provider 了

sudo docker run -d --name provider1 --net host openstf/stf stf provider --name "provider-test" --connect-sub tcp://192.168.3.16:7250  --connect-push tcp://192.168.3.16:7270  --storage-url http://192.168.3.16  --public-ip 192.168.3.16  --min-port=15000  --max-port=25000  --heartbeat-interval 20000 --screen-ws-url-pattern "ws://stf.test/d/floor4/<%= serial %>/<%= publicPort %>/"

到这里,整个基于 docker 的 stf 生产环境就搭建好了,只要加上域名和授权控制,就可以邀请别人使用了!

三、STF 开发

如果你和我一样,觉得限制使用别人做好的东西很不爽,你肯定想要自己对 STF 框架进行开发,加入一些特色功能。但是,要想通过源码来把 STF 跑通,还真没有那么容易,其中大大小小的坑令人防不胜防。

1、 安装 nodejs。

stf 是用 nodejs 来编写的,当然要 nodejs 来运行,如果你用的是 ubuntu 系统执行下面两条命令就可以安装好了

curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y nodejs

也可以安装 6.x 版本的

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs

最好再安装一些编译的工具

sudo apt-get install -y build-essential

如果你用的是其他系统就恕不奉告了,上面都是从 nodejs 官网上抄的,可以自己去上面瞅瞅。

2、既然从源码来搞它,先拉源码吧,地址 https://github.com/openstf/stf.git
养成好习惯,拉下代码先看看分支,很多项目的 master 分支不能正常运行。stf 仓库有多个分支,其中最重的就是 master 和 2.0.0 分支,看了下 github,似乎 2.0.0 已经发布了,1.1.1 才发布,不知道怎么回事,不过看到 master 分支经常更新,就用 master 分支来搞吧。

3、根据 monkey 前两天的介绍,先安装所需要的 module 吧,在 stf 项目根目录执行

npm install

等待完成,很慢吧?可以换成淘宝的 npm 镜像,地址 http://npm.taobao.org/ ,首先执行

npm install -g cnpm --registry=https://registry.npm.taobao.org

以后就可以用 cnpm 代替 npm 命令了,cnpm 用的是淘宝镜像。注意 cnpm 要求 nodejs 版本在 4.x 以上。
下面执行

cnpm install

速度很快,然后就遇到了下面的问题

[stf@1.1.1] scripts.prepublish: "bower install && not-in-install && gulp build || in-install"
bower ESUDO         Cannot be run with sudo

Additional error details:
Since bower is a user command, there is no need to execute it with superuser permissions.
If you're having permission errors when using bower without sudo, please spend a few minutes learning more about how your system should work and make any necessary repairs.

http://www.joyent.com/blog/installing-node-and-npm
https://gist.github.com/isaacs/579814

You can however run a command with sudo using --allow-root option
Error: Run "sh -c bower install && not-in-install && gulp build || in-install" error, exit code 1
Error: Run "sh -c bower install && not-in-install && gulp build || in-install" error, exit code 1
    at ChildProcess.proc.on.code (/usr/lib/node_modules/cnpm/node_modules/runscript/index.js:67:21)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:852:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5)

这里提示 bower 不能用 root 安装,其实我也不知道 bower 到底是什么鬼,我喜欢用 root 账户来搞,这也不是一个好习惯,主要是非 root 账户问题提醒没有写入权限,百度一下,发现只要加一个 --allow-root 就行了,打开项目根目录下 package.json 文件,在 bower 那一行加上--allow-root 就行了,然后再次运行 cnpm install
然后 bower balabala 安装一大堆东西,duang! 又报了一个错!

bower ng-context-menu#~1.0.5    ECMDERR Failed to execute "git ls-remote --tags --heads git://github.com/AdiDahan/ng-context-menu.git", exit code of #128 fatal: unable to connect to github.com: github.com[0: 192.30.252.131]: errno=Connection timed out

Additional error details:
fatal: unable to connect to github.com:
github.com[0: 192.30.252.131]: errno=Connection timed out
Error: Run "sh -c bower install --allow-root && not-in-install && gulp build || in-install" error, exit code 1
Error: Run "sh -c bower install --allow-root && not-in-install && gulp build || in-install" error, exit code 1
    at ChildProcess.proc.on.code (/usr/lib/node_modules/cnpm/node_modules/runscript/index.js:67:21)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:852:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5)

遇到这种 time out 问题我一般是多试几次就行了,可是这次怎么试都不奏效了,哎,还是多分析一下错误的原因吧,提示这个命令 fail

git ls-remote --tags --heads git://github.com/AdiDahan/ng-context-menu.git

手动执行一下看看,果然是 fail,突然灵光一闪,我们都是用https://github.com/https 试试?,改成

git ls-remote --tags --heads https://github.com/AdiDahan/ng-context-menu.git

果然可以了,那么在哪里改呢,找了半天没找到,google 一下,有人提到 git 自带把 git://替换成 https://的功能,简直是雪中送炭啊!

执行一下下面的命令就行了

git config --global url."https://".insteadOf git://

如果你不放心,可以去 git 的 config 文件中看一下有没配置成功。再执行一下前面 git ls-remote 命令,这下子不报错了。

下面继续进行 cnpm install 命令,又遇到下面的问题

[stf@1.1.1] scripts.prepublish: "bower install --allow-root && not-in-install && gulp build || in-install"
(node:1305) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version.
module.js:442
    throw err;
    ^

Error: Cannot find module 'strip-json-comments'
    at Function.Module._resolveFilename (module.js:440:15)
    at Function.Module._load (module.js:388:25)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/root/stf-master/node_modules/.npminstall/eslint/2.13.0/eslint/lib/config/config-file.js:23:21)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
Error: Run "sh -c bower install --allow-root && not-in-install && gulp build || in-install" error, exit code 1
Error: Run "sh -c bower install --allow-root && not-in-install && gulp build || in-install" error, exit code 1
    at ChildProcess.proc.on.code (/usr/lib/node_modules/cnpm/node_modules/runscript/index.js:67:21)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:852:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5)

还是先升级 graceful-fs 吧,然后再安装 strip-json-comments,执行

cnpm install graceful-fs
cnpm install strip-json-comments

继续 cnpm install,终于执行完了,见到了结尾

chunk    {6} entry/commons.entry.js (entry/commons.entry.js) 0 bytes [rendered]

ERROR in ENOENT: no such file or directory, scandir '/root/stf-master/node_modules/.npminstall/node-sass/3.8.0/node-sass/vendor'
 @ ./res/web_modules/nine-bootstrap/nine-bootstrap.scss 4:14-197
[13:35:01] Finished 'webpack:build' after 16 s
INF/webpack:config 1645 [*] Build progress 100% (complete)
All packages installed (use 25s, speed 0B/s, json 0(0B), tarball 0B)

等等,还是有点错误,删除 node_modules/.npminstall/node-sasss 目录,重新执行 cnpm install

这样就好了,如重复执行 cnpm install 命令,就不会有错误了。

这时执行 stf 命令是找不到的,最后来一个 cnpm link 就行了,然后就可以 stf local 了

stf local 的时候还是有错误:

INF/util:procutil 15 [*] Forking "/app/lib/cli.js poorxy --port 7100 --app-url http://localhost:7105/ --auth-url http://localhost:7120/ --api-url http://localhost:7106/ --websocket-url http://localhost:7110/ --storage-url http://localhost:7102/ --storage-plugin-image-url http://localhost:7103/ --storage-plugin-apk-url http://localhost:7104/"
/app/node_modules/zmq/node_modules/bindings/bindings.js:83
        throw e
        ^

Error: libzmq.so.3: cannot open shared object file: No such file or directory
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at bindings (/app/node_modules/zmq/node_modules/bindings/bindings.js:76:44)
    at Object.<anonymous> (/app/node_modules/zmq/lib/index.js:6:30)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
FTL/cli:local 15 [*] Child process had an error ExitError: Exit code "1"
    at ChildProcess.<anonymous> (/app/lib/util/procutil.js:49:23)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:204:12)
INF/cli:local 15 [*] Shutting down all child processes
/app/node_modules/zmq/node_modules/bindings/bindings.js:83
        throw e
        ^

Error: libzmq.so.3: cannot open shared object file: No such file or directory
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at bindings (/app/node_modules/zmq/node_modules/bindings/bindings.js:76:44)
    at Object.<anonymous> (/app/node_modules/zmq/lib/index.js:6:30)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)

这里提示缺少 zmp 的一个库文件,如果你有兴趣,可以把 zmq 装一遍,就没问题,但是我有更简单的方法,去 openstf/stf 的 docker 镜像中把 libzmq.* 这类文件拷到你的系统中就行了,库目录是/usr/lib/x86_64-linux-gnu,下面还有一个类似的错误,同样拷一下库文件就行了,什么?你不知道怎么从 docker 镜像中很外拷东西?我只能说一句,查查 docker -v 命令,其他真的不能多说了。

localhost:7106/ --websocket-url http://localhost:7110/ --storage-url http://localhost:7102/ --storage-plugin-image-url http://localhost:7103/ --storage-plugin-apk-url http://localhost:7104/"
/app/node_modules/zmq/node_modules/bindings/bindings.js:83
        throw e
        ^

Error: libpgm-5.1.so.0: cannot open shared object file: No such file or directory
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at bindings (/app/node_modules/zmq/node_modules/bindings/bindings.js:76:44)
    at Object.<anonymous> (/app/node_modules/zmq/lib/index.js:6:30)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
FTL/cli:local 112 [*] Child process had an error ExitError: Exit code "1"
    at ChildProcess.<anonymous> (/app/lib/util/procutil.js:49:23)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:204:12)
INF/cli:local 112 [*] Shutting down all child processes

下面这个错误不一定每个人都会遇到,如果遇到了还真不好解决

INF/util:procutil 209 [*] Forking "/app/lib/cli.js poorxy --port 7100 --app-url http://localhost:7105/ --auth-url http://localhost:7120/ --api-url http://loc                                                   alhost:7106/ --websocket-url http://localhost:7110/ --storage-url http://localhost:7102/ --storage-plugin-image-url http://localhost:7103/ --storage-plugin-a                                                   pk-url http://localhost:7104/"
/app/node_modules/zmq/node_modules/bindings/bindings.js:83
        throw e
        ^

Error: Module version mismatch. Expected 48, got 46.
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at bindings (/app/node_modules/zmq/node_modules/bindings/bindings.js:76:44)
    at Object.<anonymous> (/app/node_modules/zmq/lib/index.js:6:30)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
FTL/cli:local 209 [*] Child process had an error ExitError: Exit code "1"
    at ChildProcess.<anonymous> (/app/lib/util/procutil.js:49:23)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:204:12)
INF/cli:local 209 [*] Shutting down all child processes

这里提示 zmq 的 version 有问题,我尝试把 zmq 重装了几次,还是不行,最终 google 了一把,原来不是 zmq 的问题,是 nodejs 版本太高了,我是个喜新厌旧(除了人)的人,所有的东西都要用最新的,系统用 ubuntu 16.04,nodejs 要用 6.x 版本,这次就栽在这里了,其实只要把 nodejs 版本换成 node-v4.4.5 就 ok 了,具体怎么换就不说了,可以了解一下 cnpm install -g n,这里吐槽一下 nodejs 的版本问题,感觉 nodejs 在 0.12 徘徊了几年,不知道什么时候突然就到 4.x 和 6.x 了,看来大跃进是国际惯例啊。

到这里 stf 已经完全可以正常运行了,终于见到了久违的登录界面!

cnpm link 会把 stf 全集安装到系统中,cnpm link 的时候还报了一个警告

root@ubuntu-mtc:~/git/stf-dev/stf-github# cnpm link
npm WARN skippingAction Module is inside a symlinked module: not running remove pinkie-promise@2.0.1 node_modules/node-sass/node_modules/meow/node_modules/read-pkg-up/node_modules/find-up/node_modules/path-exists/node_modules/pinkie-promise
npm WARN lifecycle stf@1.1.1~prepublish: cannot run in wd %s %s (wd=%s) stf@1.1.1 bower install --allow-root&& not-in-install && gulp build || in-install /root/git/stf-dev/stf-github
npm WARN optional Skipping failed optional dependency /karma/chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.12
npm WARN optional Skipping failed optional dependency /webpack/watchpack/chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.12
/usr/bin/stf -> /usr/lib/node_modules/stf/bin/stf
/usr/lib/node_modules/stf -> /root/git/stf-dev/stf-github

fsevents 是 mac 系统上的东西,linux 上不能安装,所以报 warning,但是其他 warning 我也没搞懂是怎么回事,但是不影响运行。

以后每次修改 stf 源码,都要执行一下 cnpm install,最好再 cnpm link 一下,这样修改的代码就生效了。

四、自己制作 docker 镜像

前面说过,生产环境中的 stf 是部署在 docker 当中的,我们修改完 stf 源码以后肯定要更新到镜像里才可以。制作 docker 镜像有两种方式:

  • 自己修改完代码以后,替换掉原 openstf/stf 镜像中的/app 目录即可,这样是最简单的方法,原系统有很多链接库也不用管了,但是有个缺点,就是依赖于原 docker 镜像的操作系统,stf 作者说是 coreos 系统,据说是专门为 docker 而生,但是这个系统我连自己安装软件都不会。

  • 完全自己从零开始制作镜像。这个工作的挑战性比较大,可以会遇到很多问题,特别是一些依赖的库,还有什么安装软件时 unmet 问题,太坑了!其实在 stf 项目中有一个作者的 Dockerfile,但是我基于这个 Dockerfile 制作镜像始终都没有成功。

下面分别介绍两种制作镜像的方法:

1、替换原镜像/app 文件夹。准备好你自己修改好的 stf 目录,假设为 stf-github,用下面的 Dockerfile 生成新镜像即可

FROM openstf/stf

USER root
RUN rm -rf /app
ADD ./stf-github /app

USER root 是因为原镜像不用 root 账户不能删除/app 目录。

2、从零开始构建自己的镜像。

这里我使用的是 ubuntu 系统,所以首先要 docker pull 一个 ubuntu 系统镜像

docker pull ubuntu

准备好修改过的 stf-github 文件夹,和 Dockerfile 放在同一目录下,另外准备原 openstf/stf 镜像中的两种 lib 文件,在/usr/lib/x86_64-linux-gnu 目录下,还有最好换成国内的 ubuntu 源,使用下面的 Dockerfile 创建镜像

FROM ubuntu

ADD ./stf-github /app

EXPOSE 3000

#replace source
ADD ./sources.list /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y vim curl git sudo

ADD /x86_64-linux-gnu/libzmq.* /usr/lib/x86_64-linux-gnu/
ADD /x86_64-linux-gnu/libpgm* /usr/lib/x86_64-linux-gnu/

#install npm
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y nodejs

RUN npm install -g cnpm --registry=https://registry.npm.taobao.org

WORKDIR /app

RUN cnpm install -g graceful-fs
RUN cnpm install
RUN cnpm link

如果构建镜像过程中提示缺少某个模块,自己加上就行了,这个不是绝对的,上面的 graceful-fs 是因为有警告说 graceful-fs 的版本太低,就顺便更新一下了。其实也可以在宿主机上把 stf 全部弄好以后再整个放到 docker 中,都一样的。

至此,自己的镜像也构造完了,至于源码怎么修改,等我研究透了再说了

后续更新:

文章中说的复制 libzmq 的东西有点儿麻烦,事实上每个系统都有安装 zmq 的命令比,如说 ubuntu 上用 apt-cache search zmq 可以找到 zmq 的库 (PS:说实话我没搞清楚到底是哪个,反正装了几个以后就可以了,试试 libzmq-dev),mac 上可以用 brew install zmq 来安装。

共收到 76 条回复 时间 点赞

为啥感觉好复杂。。= =。。这个和源码中给的是一样的镜像么?

#1 楼 @monkey 主要是要安装很多依赖,再解决一些报错,镜像中代码和源码是一样的,只是经过编译,然后放到了 docker 中

#2 楼 @blueshark 看着就好累。。辛苦。。。

匿名 #4 · 2016年06月20日

看得我当时就吓尿了。。。
我有两个疑问,望解答:)
1、“provider 可以运行在同一台机器,也可以运行在其他机器”
——可以实现多个 provider 向同一个 stf 主框架提供手机的方式吗?
2、把 stf 放在 docker 中,对 USB 连接数上是否会造成限制?
——因为我试过把 stf 放在 vm 虚拟机中会有 USB 连接数限制的问题。
3、stf+docker 楼主在落地过程中还有遇到些什么坑?
——环境限制或者其它。
😁 😁 😁

stf 2.0.0 还没发布,只是有个叫 Banthia 在上面加入 appium 等测试工具的集成。建议还是使用 master 版本。

#4 楼 @link1220
1、当然可以用多个 provider 向一个 stf 主框架提供手机,而且 stf 本来就是这样设计的,希望这样来用
2、目前我没发现限制,连个十几台是没问题的,docker 和 vm 原理不一样,所以不用太担心数量限制问题
3、遇到的坑基本上在文章中都说过了

#5 楼 @0x88 多谢提醒

#6 楼 @blueshark 你有试过多少台手机连续工作多少天么?之前我试过十台手机连续工作后就会出异常,系统报 usb 相关的错误。

#9 楼 @0x88 我用最新的代码跑过大概一星期是没问题的,时间再长就没试过了,因为经常重新部署,我这边也报过一些 USB 的错误,但是感觉是手机是问题,而不是平台的问题,总体感觉还是挺稳定的

匿名 #11 · 2016年06月20日

#6 楼 @blueshark 多谢回复。下一步我也要学习下 docker!

—— 来自 TesterHome 官方 安卓客户端

就冲你写那么多,我也要顶一下,看完了,部署起来确实各种大小坑。

#12 楼 @simple 多谢,共同交流

看着就好累,楼主一生平安

我的镜像和你的为什么不一样? 确实看着好累

非常感谢楼主如此详细的文档。今天试着在 docker 里搭建 STF 环境,我已经 PULL 了上面提到的镜像,然后分别运行了上面提到的三个在 docker 的命令,然后用 docker ps 看到三个容器,说明它们都是正常启动的。但在浏览器上访问 localhost:7100 是失败的,我想问这是什么原因呀?还是我漏掉了什么操作?多谢帮助

#14 楼 @mads 共同交流

#15 楼 @liuxiaoyao0602 哪里不一样?

#16 楼 @xutester 其实在 docker 里运行和外面运行是一样的,只不过不用搭建复杂的环境,你可以看看 docker 的 log 哪里出问题了

看着就好累,楼主平安

@blueshark 请问,在另外的主机上运行 provider 时,参数怎么指定 stf 运行的机器?

#21 楼 @xiaodian provider 启动的时候会指定 --connect-sub、 --screen-ws-url-pattern 等参数

#20 楼 @ivymobi 谢谢关注

windows 下怎么安装?可以指导下不@blueshark

#24 楼 @lilili 我没见过也没尝试过在 windows 上直接安装,不过可以通过 windows 的 docker 安装,其实就是 linux 虚拟机了

文中有几个 IP,不知道是本机的,还是 docker 的,我 QQ349111840,坐等大神指导😹 👏

#26 楼 @tql 可以说是本机的,也可以说是 docker 的,这取决于你的 docker 有没有一个独立的 ip,如果有,就是 docker 的,没有就是本机的,注意端口不同

@blueshark 楼主我在一台机子上,通过 docker 启动了 stf 可以登录,在另一台电脑 provider 设备,同时在网页中可以看到 provider 的设备,但是当我点击设备,想进入 control 界面的时候,页面只是进到 control 页面什么都没有然后就刷新回来,并且手机断连了,但是我从 adb devices 去查看,设备是正常的。只能拔线重插后网页才显示正常。但是还是无法进入 control 界面。
https://github.com/openstf/stf/issues/455,具体描述在这。

分步启动的时候 /api/v1/devices 访问一直是 404,无法访问到.我根据 deployment 启动了 api 后,仍然无法访问到。

#28 楼 @zangtian2 手机掉线说明 web 或者 provider 出了错误,可以看下 log 是什么错误,不过看你前面的描述是请求不到接口的问题,很奇怪你那里为什么会去 3100 端口请求接口,官方文档是 3700,mock 的时候是 7100,如果你用了 nginx,建议你检查一下 nginx 的映射是否正确,从其他机器上 provide 机器一定要 nginx 吧。我这篇文章是针对 stf1.2 的,从 2.0 开始已经有独立的 api 模块了,需要用 nginx 做控制,上文中没有写。

@blueshark ,谢谢楼主,已解决。是浏览器的问题。firefox 导致,其他浏览器正常。

@blueshark 又麻烦下楼主。我通过 php 或 python 在 post STF 时,由于 crsf 原因无法跨源请求(403),请问源码中如何干掉这部分,主要是为了解决直接跳过登陆界面。/auth/mock 这个页面

#31 楼 @zangtian2 你是想做 SSO 吧,SSO 确实存在这个问题,我是模仿 mock.js 做了一个接口,然后把这段代码干掉了
app.use(function(req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken())
next()
})
还有 app.use(csrf())
或者看看 oauth2 有没什么好办法实现

#32 楼 @blueshark 嗯好的,我也是把这两段干掉的,还是没通。我再研究下。多谢了

请教下,我不是用 DOCKER 建立的,是本地的,最多连接手机是 37 台,是 STF 限制,还是 ADB 限制,有什么解决方案吗

#6 楼 @blueshark
#28 楼 @zangtian2
请问下,provider 提供设备的启动命令式什么啊?我也想从别的电脑 A,向 stf 服务器 B 提供设备,但不知 B 的启动命令式什么?

#34 楼 @hongxang 本地的可能和 adb 有关,我这里超过 37 台是没问题的,而且有的电脑很怪,只能识别 9 台,我遇到过。

#35 楼 @onlinesen123 A 上启动 provider,B 上搭建正常的环境就行,B 上有手机就在 B 上也启一个 provider,没有就不用启。

#37 楼 @blueshark 感谢留言,我就想知道你 A 的启动 provider 带的参数是啥啊?难道 A 也要装 STF 环境?我意思是 B 是装了 STF,A 是一台 XP 电脑连了 1 台设备,B 想操控 A 电脑的设备。。
我以为是在 B 上面的 stf 启动 provider 的命令呢,不是这样吗?

#38 楼 @onlinesen123 在连接手机的电脑上启 provider 和 adb,在服务器上启其他模块,比如 app,websocket 等等,provider 启动的命令可以参考官方:

stf provider \
   --name "%H/%i" \
   --connect-sub tcp://devside.stf.example.org:7250 \
   --connect-push tcp://devside.stf.example.org:7270 \
   --storage-url https://stf.example.org/ \
   --public-ip ${COREOS_PRIVATE_IPV4} \
   --min-port=15000 \
   --max-port=25000 \
   --heartbeat-interval 10000 \
   --screen-ws-url-pattern "wss://stf.example.org/d/%i/<%= serial %>/<%= publicPort %>/"

#39 楼 @blueshark
哦,晕死,那就是只要 provider 设备的,都要安装 STF 环境。。这个晕菜了,老板竟然提出随便找个设备裸体就能接入 stf,这要求怎么做啊。。。

#40 楼 @onlinesen123 这怎么可能,必须安装 stf 环境和 adb,所以最好用 docker,否则就要自己搭环境了

@zangtian2 确实是本地 ADB 问题,我改成 DOCKER 限制台数取消了。现在我想问一下,我想把 STF 允许外网访问进来,是用 NGINX 反代吗?

#43 楼 @hongxang nginx 反向代理可以的,但是需要注意一些事情,provider 与 web 有很多交互,其实用户与 provider 也有交互,web 与用户的交互要保证所有的交互都通过 nginx 进行代理。

@blueshark 我外网 IP:7100 访问,然后网页直接转向到 192.168.10.10:7100 。这个是不是要在 STF 什么参数上设置,才能允许外网访问

#45 楼 @hongxang 如果是 7100 好像不用设置什么了,我也没试过,不过 7100 只是个 demo,最好自己分开搭建

@blueshark 请教下:
1.如果用 WIFI 连接,是不是必须手机安装无线 ADB(我通过此方法用 7100 的架好了),但不知道 STF 本身可以不用无线 ADB 吗?
2.按上面的教程,DEMO 的没问题,但分开架的,查看日志都没错误了,但是连接设备会马上断开,然后设备就断开了,不知道哪里设置错误,我是将你的域名改成我的外网域名,然后路由做端口印射,IP 改成我的 IP,其它都没有变动。
3.STF 的 PLUGAPK,要怎么使用,应该能支持批量下发 APK 吧?

#47 楼 @hongxang 1、我不太清楚你说的无线 adb 是什么意思,我们一般把手机插在台式电脑上。电脑上安装 provider,如果你想用远程 adb,要把 provider 的--allow-remote 参数加上,否则 stf 不允许类似于 ip:端口号的 serial 上线的。2、分开架的时候 nginx 转发比较复杂,单凭你说的现象我也没办法判断问题所在,你可以看一下 stf 的 log,看看报什么错。3、PLUGAPK 是什么功能?我好像没见到这个

楼主,你好!本文中未提及 rethinkdb-proxy-28015.service 这个服务。这个是可以不采用的么?

rethinkdb-proxy-28015.service 这个其实只是连接 rethinkdb 的一个代理模块,如果直接写死了 rethinkdb 的地址,可以不用


你好,这是我写的一个 Dockerfile 文件,想替换掉镜像中的,tables.js,想请教下,RUN rm -rf /app 这个路劲是写我要替换掉的 tables.js 源码中的位置吗????

刘扬 回复

当然要,否则把整个 app 文件夹都删除了

生产环境,一台服务器最多可连多少设备?

Bob 回复

这个我还没发现上限,100 台是没问题的,不够的话可以扩展的

6、登录授权
请教登录授权有更具体的介绍么?

Kun 回复

登录授权不同的公司不一样,所以没有详细介绍,不过可以参考 stf mock 模块

blueshark 回复

@zangtian2 @blueshark 的确需要部署单独的 api server,还需要在 nginx 配置文件里添加二段描述。参考了这篇文章,我弄了一个一键部署 stf 的脚本 https://github.com/thinkhy/STF-Assistor/blob/master/deploy_stf.sh.template

方叶 回复

脚本写的很棒,赞一个!我用 nginx 做负载均衡的时候遇到的两个问题,希望对你有用
1、torage-plugin-apk、storage-plugin-image、storage-temp 这三个最好不要做均衡,因为 nginx 会把文件上传一个 server,而去另外一个 server 拉下来安装,结果拉不到文件,造成安装失败。
2、provider 中的这一段--screen-ws-url-pattern "ws://IP_ADDRESS/d/floor4/<%= serial %>/<%= publicPort %>/",如果用户和 provider 在同一网络,在IP_ADDRESS这里可以直接换成 PROVIDRE_IP_ADDRESS__:<%= publicPort %>,就是直接换成 provder 的 ip 加端口号,这样就不经 nginx 转发了,减少 nginx 的压力。

方叶 回复

请问这个脚本文件下载下来之后直接就在 win7 下面点击相应的.sh 文件就可以了吗

blueshark 回复

@blueshark Thanks! nginx 的负载均衡这块我还没弄, Provider 的 websocket 直连已经注意到了,provider 的部署也做成了一键脚本:https://github.com/thinkhy/STF-Assistor/blob/master/deploy_stf_provider.sh.template 另外还把 systemd 的配置也自动化了,这样以服务方式启动 stf,可用性提高不少,比如 adb server 和 provider 断了能自动重启。

wanxiaoqiang 回复

自动部署脚本只支持 ubuntu。本想用 chef 和 ansible 实现自动批量部署,考虑到实现简单和使用方便,直接用 Bash shell 写了。

方叶 回复

能不能加下我的联系方式,共同建个群交流一下,可以看我的个人介绍,我后面又写了一些文档,感觉对 STF 的理解还不够清楚,所以没发出来。

blueshark 回复

OK. 晚点我联系你

你好,想请教一个问题
在 Mac 机器上安装开源的 stf,安装完成后执行 stf local 命令后,提示如下错误:Error:Could not locate the bindings file.,请大神们帮忙指点迷津

bogon:pkgconfig baidu$ stf -V
2.3.0
bogon:pkgconfig baidu$
bogon:pkgconfig baidu$ stf local
/usr/local/lib/node_modules/stf/node_modules/bindings/bindings.js:91
throw err
^
Error: Could not locate the bindings file. Tried:
→ /usr/local/lib/node_modules/stf/node_modules/zmq/build/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/build/Debug/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/build/Release/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/out/Debug/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/Debug/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/out/Release/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/Release/zmq.node
→ /usr/local/lib/node_modules/stf/node_modules/zmq/build/default/zmq.node

Awesome 回复

brew install zmq
brew install yasm # 安装 jpegturbo 会用到

windows 按照楼主的方式,通过 docker 启动,不能访问

Yat_Ho 回复

麻烦你把具体的操作和遇到的错误描述一下,或者看我的资料联系我共同交流

方便加下 QQ1076947473 进行交流

陈恒捷 treafik 试用记录 中提及了此贴 01月09日 14:43

大概用 Mac 部署了一下,有两个地方有点问题:

  • 第一是--net host参数好像在 Mac OS 并不支持,所以导致无法访问 nginx 等(估计 windows 也会有同样的问题?)
  • 第二个是文中的 DNS 部分描述,如果完全按照描述的配置,最后也无法使用 url 来访问啊,是否需要申请个域名,并且 dns 有对应记录才可以使用呢?
雨夜狂奔 回复

1、--net host 是指定使用宿主机的网络,如果不方便使用宿主机网络,可以想其他办法进行返向代理,这个其实和 STF 本身无关了。
2、和域名无关,ip 也是可以的。

我用的 centos7 node 版本是 9.0.0,执行 npm install 的时候一直报 fsevents,难道需要改回 Ubuntu 么

请问下我使用 docker 部署的 STF,现在我想在容器里面改动 stf 代码,然后重新编译,但是总是报错,有人知道怎么回事么?

docker stf 真得安装好快哇!!
stf 开发环境,装得好累,cnpm install 可以了,cnpm link 不行,最后搞不定,
还是用另外一大神的安装方式https://testerhome.com/topics/6112,在这基础上准备进行二次开发

楼主问下,我这边在 docker 里边拉了几个镜像,容器三个都跑起来了,vm 内部可以通过 IP 访问,宿主机和局域网其他物理机都访问不了是什么原因?ip 都是可以 ping 的通的

space 回复

我也想知道为什么?请问你的问题解决了么?

我 stf local 启动后 localhost:7100 页面无法打开请问这个怎么解决

tcp://127.0.0.1:7111 --bind-dealer tcp://127.0.0.1:7112 --bind-pull tcp://127.0.0.1:7113"

2021-02-28T12:38:30.404Z INF/util:procutil 1 [*] Forking "/app/lib/cli triproxy dev001 --bind-pub tcp://127.0.0.1:7114 --bind-dealer tcp://127.0.0.1:7115 --bind-pull tcp://127.0.0.1:7116"

2021-02-28T12:38:30.405Z INF/util:procutil 1 [*] Forking "/app/lib/cli processor proc001 --connect-app-dealer tcp://127.0.0.1:7112 --connect-dev-dealer tcp://127.0.0.1:7115"

2021-02-28T12:38:30.407Z INF/util:procutil 1 [*] Forking "/app/lib/cli processor proc002 --connect-app-dealer tcp://127.0.0.1:7112 --connect-dev-dealer tcp://127.0.0.1:7115"

2021-02-28T12:38:30.408Z INF/util:procutil 1 [*] Forking "/app/lib/cli reaper reaper001 --connect-push tcp://127.0.0.1:7116 --connect-sub tcp://127.0.0.1:7111"

2021-02-28T12:38:30.410Z INF/util:procutil 1 [*] Forking "/app/lib/cli provider --name docker-desktop --min-port 7400 --max-port 7700 --connect-sub tcp://127.0.0.1:7114 --connect-push tcp://127.0.0.1:7116 --group-timeout 900 --public-ip 192.168.1.4 --storage-url http://localhost:7100/ --adb-host 127.0.0.1 --adb-port 5037 --vnc-initial-size 600x800 --mute-master never --allow-remote"

2021-02-28T12:38:30.417Z INF/util:procutil 1 [*] Forking "/app/lib/cli auth-mock --port 7120 --secret kute kittykat --app-url http://192.168.1.4:7100/"

2021-02-28T12:38:30.432Z INF/util:procutil 1 [*] Forking "/app/lib/cli app --port 7105 --secret kute kittykat --auth-url http://192.168.1.4:7100/auth/mock/ --websocket-url http://192.168.1.4:7110/"

2021-02-28T12:38:30.441Z INF/util:procutil 1 [*] Forking "/app/lib/cli api --port 7106 --secret kute kittykat --connect-push tcp://127.0.0.1:7113 --connect-sub tcp://127.0.0.1:7111 --connect-push-dev tcp://127.0.0.1:7116 --connect-sub-dev tcp://127.0.0.1:7114"

2021-02-28T12:38:30.450Z INF/util:procutil 1 [*] Forking "/app/lib/cli groups-engine --connect-push tcp://127.0.0.1:7113 --connect-sub tcp://127.0.0.1:7111 --connect-push-dev tcp://127.0.0.1:7116 --connect-sub-dev tcp://127.0.0.1:7114"

2021-02-28T12:38:30.472Z INF/util:procutil 1 [*] Forking "/app/lib/cli websocket --port 7110 --secret kute kittykat --storage-url http://localhost:7100/ --connect-sub tcp://127.0.0.1:7111 --connect-push tcp://127.0.0.1:7113"

2021-02-28T12:38:30.495Z INF/util:procutil 1 [*] Forking "/app/lib/cli storage-temp --port 7102"

2021-02-28T12:38:30.503Z INF/util:procutil 1 [*] Forking "/app/lib/cli storage-plugin-image --port 7103 --storage-url http://localhost:7100/"

2021-02-28T12:38:30.518Z INF/util:procutil 1 [*] Forking "/app/lib/cli storage-plugin-apk --port 7104 --storage-url http://localhost:7100/"

2021-02-28T12:38:30.531Z INF/util:procutil 1 [*] Forking "/app/lib/cli poorxy --port 7100 --app-url http://localhost:7105/ --auth-url http://localhost:7120/ --api-url http://localhost:7106/ --websocket-url http://localhost:7110/ --storage-url http://localhost:7102/ --storage-plugin-image-url http://localhost:7103/ --storage-plugin-apk-url http://localhost:7104/"

2021-02-28T12:38:30.633Z INF/triproxy 19 [dev001] PUB socket bound on tcp://127.0.0.1:7114

2021-02-28T12:38:30.635Z INF/triproxy 19 [dev001] DEALER socket bound on tcp://127.0.0.1:7115

2021-02-28T12:38:30.638Z INF/triproxy 19 [dev001] PULL socket bound on tcp://127.0.0.1:7116

2021-02-28T12:38:30.839Z INF/triproxy 18 [app001] PUB socket bound on tcp://127.0.0.1:7111

2021-02-28T12:38:30.849Z INF/db 29 [*] Connecting to 127.0.0.1:28015

2021-02-28T12:38:30.854Z INF/triproxy 18 [app001] DEALER socket bound on tcp://127.0.0.1:7112

2021-02-28T12:38:30.854Z INF/triproxy 18 [app001] PULL socket bound on tcp://127.0.0.1:7113

2021-02-28T12:38:30.873Z INF/reaper 34 [reaper001] Subscribing to permanent channel "*ALL"

2021-02-28T12:38:30.876Z INF/reaper 34 [reaper001] Reaping devices with no heartbeat

2021-02-28T12:38:30.876Z INF/processor 29 [proc002] App dealer connected to "tcp://127.0.0.1:7112"

2021-02-28T12:38:30.876Z INF/processor 29 [proc002] Device dealer connected to "tcp://127.0.0.1:7115"

2021-02-28T12:38:30.877Z INF/db 34 [reaper001] Connecting to 127.0.0.1:28015

2021-02-28T12:38:30.890Z INF/reaper 34 [reaper001] Receiving input from "tcp://127.0.0.1:7111"

2021-02-28T12:38:30.891Z INF/reaper 34 [reaper001] Sending output to "tcp://127.0.0.1:7116"

2021-02-28T12:38:30.945Z INF/db 24 [*] Connecting to 127.0.0.1:28015

2021-02-28T12:38:30.985Z INF/processor 24 [proc001] App dealer connected to "tcp://127.0.0.1:7112"

2021-02-28T12:38:30.986Z INF/processor 24 [proc001] Device dealer connected to "tcp://127.0.0.1:7115"

2021-02-28T12:38:31.175Z INF/groups-engine 67 [*] Subscribing to permanent channel "*ALL"

2021-02-28T12:38:31.173Z INF/poorxy 97 [*] Listening on port 7100

2021-02-28T12:38:31.194Z INF/groups-engine 67 [*] Groups engine started

2021-02-28T12:38:31.196Z INF/db 67 [*] Connecting to 127.0.0.1:28015

2021-02-28T12:38:31.214Z INF/groups-engine 67 [*] Sending output to "tcp://127.0.0.1:7113"

2021-02-28T12:38:31.214Z INF/groups-engine 67 [*] Receiving input from "tcp://127.0.0.1:7111"

2021-02-28T12:38:31.215Z INF/groups-engine 67 [*] Sending output to "tcp://127.0.0.1:7116"

2021-02-28T12:38:31.215Z INF/groups-engine 67 [*] Receiving input from "tcp://127.0.0.1:7114"

2021-02-28T12:38:31.228Z INF/provider 36 [*] Subscribing to permanent channel "b8dffek2TyWjhplVh+Qf+g=="

2021-02-28T12:38:31.245Z INF/app 55 [*] Using pre-built resources

2021-02-28T12:38:31.256Z INF/app 55 [*] Listening on port 7105

2021-02-28T12:38:31.263Z INF/provider 36 [*] Sending output to "tcp://127.0.0.1:7116"

2021-02-28T12:38:31.268Z INF/db 55 [*] Connecting to 127.0.0.1:28015

2021-02-28T12:38:31.271Z INF/auth-mock 49 [*] Listening on port 7120

2021-02-28T12:38:31.273Z INF/provider 36 [*] Receiving input from "tcp://127.0.0.1:7114"

2021-02-28T12:38:31.277Z INF/provider 36 [*] Tracking devices

2021-02-28T12:38:31.284Z INF/db 49 [*] Connecting to 127.0.0.1:28015

2021-02-28T12:38:31.298Z INF/storage:plugins:image 85 [*] Listening on port 7103

2021-02-28T12:38:31.322Z INF/storage:temp 79 [*] Listening on port 7102

2021-02-28T12:38:31.331Z INF/storage:plugins:apk 91 [*] Listening on port 7104

2021-02-28T12:38:31.410Z INF/websocket 73 [*] Subscribing to permanent channel "*ALL"

2021-02-28T12:38:31.415Z INF/websocket 73 [*] Listening on port 7110

2021-02-28T12:38:31.425Z INF/db 73 [*] Connecting to 127.0.0.1:28015

2021-02-28T12:38:31.428Z INF/websocket 73 [*] Sending output to "tcp://127.0.0.1:7113"

2021-02-28T12:38:31.429Z INF/websocket 73 [*] Receiving input from "tcp://127.0.0.1:7111"

2021-02-28T12:38:31.700Z INF/api 60 [*] Subscribing to permanent channel "*ALL"

2021-02-28T12:38:31.731Z INF/api 60 [*] Listening on port 7106

2021-02-28T12:38:31.760Z INF/api 60 [*] Sending output to "tcp://127.0.0.1:7113"

2021-02-28T12:38:31.760Z INF/api 60 [*] Receiving input from "tcp://127.0.0.1:7111"

2021-02-28T12:38:31.761Z INF/api 60 [*] Sending output to "tcp://127.0.0.1:7116"

2021-02-28T12:38:31.761Z INF/api 60 [*] Receiving input from "tcp://127.0.0.1:7114"

2021-02-28T12:38:32.114Z INF/db 60 [*] Connecting to 127.0.0.1:28015

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册