Выполнение скрипта python3 с TCP-сервером при запуске Docker, хотя сценарий оболочки выдает отказ в соединении [Errno 111]

#python #python-3.x #docker #sh #python-asyncio

#python #python-3.x #docker #sh #python-asyncio

Вопрос:

Я разработал несколько скриптов Python3 для запуска поверх автономного образа Selenium Chrome с TCP-сервером для выполнения некоторого процесса, который собирает некоторую информацию, созданную во время тестирования, и которая находится внутри контейнера. Всякий раз, когда мне нужно запустить процесс python3, я подключаюсь к нему через TCP-клиент, отправляю несколько команд, и скрипт python3 выполняет то, что мне нужно.
В моем dockerfile я устанавливаю pip3 и все, что мне нужно, и копирую все нужные мне скрипты, и все работает отлично, если я вручную обращаюсь к контейнеру docker и запускаю скрипт python3 вручную, вот так:

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

Это успешно запускает мой скрипт python3 в фоновом режиме, и он отлично работает

 seluser@24d2713db5f1:~/python$ sudo nohup python3 myscript.py amp;
[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 amp;amp;
    apt-get upgrade -y amp;amp;
    apt-get install python3-pip -y amp;amp;
    apt-get install dos2unix -y amp;amp;
    pip3 install pynput amp;amp;
    pip3 install azure.storage.blob amp;amp;
    apt-get install vim -y

USER seluser

EXPOSE 9871

RUN mkdir -p /home/seluser/upload amp;amp;
    mkdir -p /home/seluser/python amp;amp;
    mkdir -p /home/seluser/logs amp;amp;
    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 amp;amp;
    chmod a x /opt/bin/entry_point.sh

USER seluser
  

Ниже приведен сценарий оболочки entry_point.sh это я получил с selenium github, с простой модификацией для запуска моего скрипта

 #!/usr/bin/env bash

if ! whoami amp;> /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 amp;

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 amp;
echo "script PYTHON3 started"

trap shutdown SIGTERM SIGINT
wait ${SUPERVISOR_PID}
  

This is the myscript.py that I start

 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()
  

I start the container using this docker run command

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

The log that I get when I start then container is below

 λ  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 после запуска моего контейнера? Большое вам спасибо за любую помощь.

Редактировать

На основе базового образа у него уже есть точка входа в сценарий оболочки. Глядя на 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:

Поскольку у вас возникли проблемы, 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 amp;amp;
    chmod a x /opt/bin/entry_point.sh
  

С этим ниже:

Согласно основному конфигурационному файлу docker-selenium , любая дополнительная конфигурация должна быть добавлена в /etc/supervisor/conf.d/

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

И нет необходимости изменять скрипт точки входа, поскольку мы заменяем nohup файлом конфигурации supervisorord