尽管Shell脚本抛出[Errno 111]连接被拒绝

时间:2019-03-16 15:45:01

标签: python python-3.x docker sh python-asyncio

我已经开发了一些Python3脚本,它们可以通过TCP Server在Standalone Selenium Chrome映像之上运行,以执行一些过程,该过程收集测试期间创建的一些信息,这些信息位于容器内。每当我需要启动python3进程时,我都会通过TCP客户端连接到它,发送一些命令,然后python3脚本会执行我需要的操作。
在我的dockerfile上,我安装了pip3和所有我需要的东西,并且复制了我需要的所有脚本,如果手动访问docker容器,并且我手动启动python3脚本,那么一切都可以正常工作,

docker exec -it selc bash
cd /home/seluser/python/
sudo nohup python3 myscript.py &

这成功在后台启动了我的python3脚本,并且运行良好

seluser@24d2713db5f1:~/python$ sudo nohup python3 myscript.py &
[1] 71
seluser@24d2713db5f1:~/python$ nohup: ignoring input and appending output to 'nohup.out'

但是,我想在每次启动容器时自动执行此脚本,但我无法成功执行此操作。运行容器时,容器日志中出现ConnectionRefusedError: [Errno 111] Connection refused错误。以下是我的dockerfile

FROM selenium/standalone-chrome-debug

USER root

RUN apt-get update &&\
    apt-get upgrade -y &&\
    apt-get install python3-pip -y &&\
    apt-get install dos2unix -y &&\
    pip3 install pynput &&\
    pip3 install azure.storage.blob &&\
    apt-get install vim -y

USER seluser

EXPOSE 9871

RUN mkdir -p /home/seluser/upload &&\
    mkdir -p /home/seluser/python &&\
    mkdir -p /home/seluser/logs &&\
    mkdir -p /home/seluser/debug

ADD /python /home/seluser/python

USER root

COPY entry_point.sh /opt/bin/entry_point.sh

RUN dos2unix /opt/bin/entry_point.sh &&\
    chmod a+x /opt/bin/entry_point.sh

USER seluser

下面是我从selenium github获得的shell脚本entry_point.sh,只需修改即可运行我的脚本

#!/usr/bin/env bash

if ! whoami &> /dev/null; then
  if [ -w /etc/passwd ]; then
    echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
  fi
fi

/usr/bin/supervisord --configuration /etc/supervisord.conf &

SUPERVISOR_PID=$!

function shutdown {
    echo "Trapped SIGTERM/SIGINT/x so shutting down supervisord..."
    kill -s SIGTERM ${SUPERVISOR_PID}
    wait ${SUPERVISOR_PID}
    echo "Shutdown complete"
}

echo "Starting script PYTHON3"
nohup python3 /home/seluser/python/myscript.py &
echo "script PYTHON3 started"

trap shutdown SIGTERM SIGINT
wait ${SUPERVISOR_PID}

这是我开始的myscript.py

import asyncio
import logging
import time

from servico.myserver import myServer
from auxiliar.objlog import ObjLog
from auxiliar.objip import ObjIp

logger = ObjLog().executar()

logger.debug("Starting execution")

time.sleep(3)

logger.debug("Getting connection")

loop = asyncio.get_event_loop()
stream_server = myServer(loop)
# ip = ObjIp().executar()
# logger.debug('IP:' + ip)

coro_server = asyncio.start_server(
    stream_server.server_handler,
    '0.0.0.0',
    9871,
    loop=stream_server.loop
)

server = loop.run_until_complete(coro_server)

logger.debug('Pre-execution')
logger = ObjLog().executar()
logger.debug('Listening:' + str(server.sockets[0].getsockname()))

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

print('Closing Server')
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

我使用此docker run命令启动容器

docker run --name selc --detach --rm -p 4444:4444 -p 5900:5900 -p 9871:9871 mydocker/selenium-debug-chrome:latest

启动容器时得到的日志在下面

λ  docker logs selc                                                                                                     
Iniciando script PYTHON3                                                                                                
script PYTHON3 iniciado                                                                                                 
Traceback (most recent call last):                                                                                      
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/unix_connect.py", line 119, in get_socket                   
    s = _get_unix_socket(address)                                                                                       
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/unix_connect.py", line 98, in _get_unix_socket              
    s.connect(address)                                                                                                  
ConnectionRefusedError: [Errno 111] Connection refused                                                                  

During handling of the above exception, another exception occurred:                                                     

Traceback (most recent call last):                                                                                      
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/unix_connect.py", line 123, in get_socket                   
    s = _get_tcp_socket(host, dno)                                                                                      
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/unix_connect.py", line 93, in _get_tcp_socket               
    s.connect((host, 6000 + dno))                                                                                       
ConnectionRefusedError: [Errno 111] Connection refused                                                                  

During handling of the above exception, another exception occurred:                                                     

Traceback (most recent call last):                                                                                      
  File "/home/seluser/python/my.py", line 5, in <module>                                                      
    from servico.myserver import myServer                                                           
  File "/home/seluser/python/servico/myserver.py", line 7, in <module>                                        
    from servico.tarefas.download_pdf import DownloadPdf                                                                
  File "/home/seluser/python/servico/tarefas/download_pdf.py", line 5, in <module>                                      
    from pynput.keyboard import Key, Controller                                                                         
  File "/usr/local/lib/python3.6/dist-packages/pynput/__init__.py", line 23, in <module>                                
    from . import keyboard                                                                                              
  File "/usr/local/lib/python3.6/dist-packages/pynput/keyboard/__init__.py", line 49, in <module>                       
    from ._xorg import KeyCode, Key, Controller, Listener                                                               
  File "/usr/local/lib/python3.6/dist-packages/pynput/keyboard/_xorg.py", line 39, in <module>                          
    from pynput._util.xorg import (                                                                                     
  File "/usr/local/lib/python3.6/dist-packages/pynput/_util/xorg.py", line 40, in <module>                              
    _check()                                                                                                            
  File "/usr/local/lib/python3.6/dist-packages/pynput/_util/xorg.py", line 38, in _check                                
    display = Xlib.display.Display()                                                                                    
  File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 89, in __init__                                   
    self.display = _BaseDisplay(display)                                                                                
  File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 71, in __init__                                   
    protocol_display.Display.__init__(self, *args, **keys)                                                              
  File "/usr/local/lib/python3.6/dist-packages/Xlib/protocol/display.py", line 89, in __init__                          
    self.socket = connect.get_socket(name, protocol, host, displayno)                                                   
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/connect.py", line 87, in get_socket
    return mod.get_socket(dname, protocol, host, dno)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/unix_connect.py", line 127, in get_socket
    raise error.DisplayConnectionError(dname, str(val))
Xlib.error.DisplayConnectionError: Can't connect to display ":99.0": [Errno 111] Connection refused
2019-03-16 14:00:59,881 INFO Included extra file "/etc/supervisor/conf.d/selenium-debug.conf" during parsing
2019-03-16 14:00:59,881 INFO Included extra file "/etc/supervisor/conf.d/selenium.conf" during parsing
2019-03-16 14:00:59,885 INFO supervisord started with pid 7
2019-03-16 14:01:00,887 INFO spawned: 'xvfb' with pid 13
2019-03-16 14:01:00,888 INFO spawned: 'fluxbox' with pid 14
2019-03-16 14:01:00,890 INFO spawned: 'vnc' with pid 15
2019-03-16 14:01:00,891 INFO spawned: 'selenium-standalone' with pid 16
2019-03-16 14:01:01,016 INFO success: xvfb entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)2019-03-16 14:01:01,016 INFO success: fluxbox entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2019-03-16 14:01:01,016 INFO success: vnc entered RUNNING state, process has stayed up for > than 0 seconds (startsecs) 2019-03-16 14:01:01,017 INFO success: selenium-standalone entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
14:01:01.332 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
14:01:01.429 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
2019-03-16 14:01:01.489:INFO::main: Logging initialized @570ms to org.seleniumhq.jetty9.util.log.StdErrLog
14:01:01.822 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
14:01:01.941 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444    

如果我通过bash手动连接到它,并按照我已指出的方式启动它,它会正常工作。它只是在启动时不起作用。

为什么会出现此错误?容器启动后,还有其他方法可以自动启动python3脚本吗?非常感谢您的帮助。

编辑

基于基本映像,它已经具有shell脚本的入口点。看着docker inspect,我可以看到它。

λ  docker inspect selc
[
    {
        "Id": "24d2713db5f13be0c69479a27f6ea4c943d194edbe3b2fa303aaac966639694e",
        "Created": "2019-03-16T14:31:43.6236537Z",
        "Path": "/opt/bin/entry_point.sh",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 34191,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-03-16T14:31:44.2388239Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },

我不希望更改基本图像工作原理的机制,只是对其进行了一些微调,以尝试使用现有代码执行我的脚本。但是我很开放想法,因为我不知道该怎么办。

1 个答案:

答案 0 :(得分:2)

由于您拥有supervisord,因此更好的方法是通过它运行python脚本,而不是使用nohup。因此,创建一个像myscript.conf

这样的文件
[program:myscript]
command=/usr/bin/python3 /home/seluser/python/myscript.py
autostart=true
autorestart=true
startretries=3
user=seluser

在您的Dockerfile中 替换以下行:

COPY entry_point.sh /opt/bin/entry_point.sh

RUN dos2unix /opt/bin/entry_point.sh &&\
    chmod a+x /opt/bin/entry_point.sh

下面有一个:

  

根据docker-selenium中的the main configuration file,应将任何其他配置添加到/etc/supervisor/conf.d/

COPY myscript.conf /etc/supervisor/conf.d/

由于我们用主管配置文件替换了nohup,因此无需修改入口点脚本