基于stf-poc,但是 screenshot 不工作,很是困扰.

log

  • provider info
docker ps -a |grep provider
docker logs --details xxx

2018-09-09T05:54:43.191Z ERR/device:support:storage 31 [0123456789ABCDEF] Upload to "http://192.168.0.107/s/upload/image" failed: HTTP 502
 2018-09-09T05:54:43.231Z ERR/device:plugins:screen:capture 31 [0123456789ABCDEF] Screen capture failed Error: Upload to "http://192.168.0.107/s/upload/image" failed: HTTP 502
     at Request._callback (/app/lib/units/device/support/storage.js:29:27)
     at Request.self.callback (/app/node_modules/request/request.js:185:22)
     at emitTwo (events.js:106:13)
     at Request.emit (events.js:191:7)
     at Request.<anonymous> (/app/node_modules/request/request.js:1161:10)
     at emitOne (events.js:96:13)
     at Request.emit (events.js:188:7)
     at IncomingMessage.<anonymous> (/app/node_modules/request/request.js:1083:12)
     at IncomingMessage.g (events.js:292:16)
     at emitNone (events.js:91:20)
     at IncomingMessage.emit (events.js:185:7)
     at endReadableNT (_stream_readable.js:974:12)
     at _combinedTickCallback (internal/process/next_tick.js:80:11)
     at process._tickCallback (internal/process/next_tick.js:104:9)
  • nginx log
 2018/09/09 05:54:43 [error] 12#12: *58 upstream prematurely closed connection while reading response header from upstream, client: 172.18.0.1, server: , request: "POST /s/upload/image HTTP/1.1", upstream: "http://172.18.0.3:3000/s/upload/image", host: "192.168.0.107"
 172.18.0.1 - - [09/Sep/2018:05:54:43 +0000] "POST /s/upload/image HTTP/1.1" 502 166 "-" "-"

  • storage_temp log
docker logs  --details 568
 2018-09-09T07:56:19.241Z INF/storage:temp 1 [*] Listening on port 3000
 events.js:160
       throw er; // Unhandled 'error' event
       ^

 Error: EACCES: permission denied, open '/data/upload_b256179062a03738c180aae35dcb1741'
     at Error (native)
 2018-09-09T07:57:00.800Z INF/storage:temp 1 [*] Listening on port 3000

跟权限肯定有关系的. exec 进入 storage_temp,查看/data 文件夹:

drwxr-xr-x   2      1000      1000 4096 Sep  9 02:10 data

这个 1000 的权限很奇怪,应该是跟随了 compose yaml 文件 volumes 里本机 data 目录的权限,也就是 1000:1000(bravo:bravo)

storage-temp:
    build: storage-temp/
    restart: unless-stopped
    volumes:
      - ./data:/data
    command: stf storage-temp --port 3000 --save-dir /data

而 docker app container 执行时,应该是 stf(998)的 user 权限.

于是想到了主机改变 data group 的很 tricky 的做法:

sudo chown 998:998 data

重启后,可以了!nice.

查看 docker-compose 所有 log 的方法

docker-compose logs --tail=0 --follow

数据流向分析

host: 192.168.0.107

docker-brige network: 172.18.0.1/16

具体哪个 image 执行的 container 在 docker network 内的 ip,可以用 inspect 确定,如 screenshot post 时,需访问 docker net 的storage-temp,其 ip 可以用下面的方式查询:

docker inspect stf-poc_storage-temp_1 |grep IPAdd

"SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "172.18.0.3",

image 要存储,先访问:http://192.168.0.107/s/upload/image

再看 nginx 配置,都 反向到 http://stf_storage 去了

location /s/ {

		proxy_buffer_size  128k;
		proxy_buffers   32 32k;
		proxy_busy_buffers_size 128k;
      client_max_body_size 1024m;
      client_body_buffer_size 128k;
      proxy_pass http://stf_storage;
    }

upstream stf_storage {
    server storage-temp:3000 max_fails=0;
  }

注意http://stf_storage这种表示比较奇怪,实际地址通过 docker resolver 进行解析的,也就是 nginx.conf 开头的:

  include /etc/nginx/conf.d/resolver.conf;

其内容中127.0.0.11就是 docker 网络的 dns,将 stf_storage 替换成了内部 ip172.168.0.3

search DHCP HOST
nameserver 127.0.0.11
options ndots:0

再根据 nginx 设置的 upstream,现在访问的是http://172.168.0.3:3000/s/upload/image

这个就进到 storage-temp 的 container 里了,是 docker-compose 启动的:

command: stf storage-temp --port 3000 --save-dir /data

再往下就是继续的后端逻辑了.

权限问题

权限在 docker 里应该是个比较复杂的问题. 总结了下可能的几个来源:

  1. 继承的 image 来的权限;
  2. Dockfile 里 USER 指定的 user 的权限;
  3. volumes 挂载时,跟随主机的权限;(也就是上面解决的问题)
  4. 运行 build 时的权限(sudo build )