我已经开发了一些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"
},
我不希望更改基本图像工作原理的机制,只是对其进行了一些微调,以尝试使用现有代码执行我的脚本。但是我很开放想法,因为我不知道该怎么办。
答案 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,因此无需修改入口点脚本