[英]Executing a python3 script with TCP Server on Docker startup though shell script throws [Errno 111] Connection refused
I've developed some Python3 scripts to run on top of the Standalone Selenium Chrome image with a TCP Server to execute some process that collects some information created during testing, and that are inside the container. 我已经开发了一些Python3脚本,它们可以在带有TCP Server的独立Selenium Chrome映像之上运行,以执行一些过程,该过程收集测试期间创建的一些信息,这些信息位于容器内。 Whenever I need to start the python3 process, I connect to it through a TCP Client, send some commands, and the python3 script does what I need it to do. 每当我需要启动python3进程时,我都会通过TCP客户端连接到它,发送一些命令,然后python3脚本执行我需要做的事情。
On my dockerfile, I install pip3 and everything I need, and I copy over all the scripts that I need, and everything works perfectly if I manually access the docker container, and I start the python3 script manually, like this: 在我的dockerfile上,我安装了pip3和我需要的所有内容,并复制了我需要的所有脚本,如果手动访问docker容器,并且我手动启动python3脚本,那么一切都可以正常运行,如下所示:
docker exec -it selc bash
cd /home/seluser/python/
sudo nohup python3 myscript.py &
This successfully start my python3 script on the background, and it runs great 这样可以在后台成功启动我的python3脚本,并且运行良好
seluser@24d2713db5f1:~/python$ sudo nohup python3 myscript.py &
[1] 71
seluser@24d2713db5f1:~/python$ nohup: ignoring input and appending output to 'nohup.out'
However, I would like to execute this script automatically whenever I start my container, and I haven't being able to do this successfully. 但是,我想在每次启动容器时自动执行此脚本,但是我无法成功执行此操作。 I get a ConnectionRefusedError: [Errno 111] Connection refused
error in the container logs when I run the container. 我收到一个ConnectionRefusedError: [Errno 111] Connection refused
运行容器时,容器日志中的ConnectionRefusedError: [Errno 111] Connection refused
错误。 Below is my dockerfile 以下是我的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
Below is the shell script entry_point.sh that I got from the selenium github, with just a modification to run my script 下面是我从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}
This is the myscript.py that I start 这是我开始的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()
I start the container using this docker run command 我使用此docker run命令启动容器
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
If I connect to it manually though bash, and start it the same way I've pointed out, it works fine. 如果我通过bash手动连接到它,然后以我所指出的方式启动它,那么它将正常工作。 It just won't work on startup. 它只是在启动时不起作用。
Why am I getting this error? 为什么会出现此错误? Is there other way to start my python3 script automatically after my container starts? 容器启动后,还有其他方法可以自动启动python3脚本吗? Thank you very much for any help. 非常感谢您的帮助。
EDIT 编辑
Based on the base image, it already has an entry point to the shell script. 基于基本映像,它已经具有shell脚本的入口点。 Looking at docker inspect
I can see it. 看着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"
},
I preferred not to change the mechanics of how to base image works, just tuned it a bit to try to execute my script using the existing code. 我宁愿不更改基础图像工作原理的机制,只是对其进行了一些微调,以尝试使用现有代码执行我的脚本。 But I'm open to ideas, since I don't know what to do. 但是我很开放想法,因为我不知道该怎么做。
Since you are having supervisord
a better approach would be running the python script through it instead of using nohup
. 由于您已经supervisord
了,所以更好的方法是通过它运行python脚本,而不是使用nohup
。 So create a file like myscript.conf
所以创建一个像myscript.conf
这样的文件
[program:myscript]
command=/usr/bin/python3 /home/seluser/python/myscript.py
autostart=true
autorestart=true
startretries=3
user=seluser
And in your Dockerfile Replace the following lines: 并在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
With this one below: 下面的这个:
According to the main configuration file of
docker-selenium
, any additional config should be add to/etc/supervisor/conf.d/
根据/etc/supervisor/conf.d/
docker-selenium
的主要配置文件 ,任何其他配置都应添加到/etc/supervisor/conf.d/
COPY myscript.conf /etc/supervisor/conf.d/
And there is no need to modifying the entrypoint script since we replace nohup with supervisord config file 而且由于我们将nohup替换为超级用户配置文件,因此无需修改入口点脚本
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.