问题描述
我想用Python做一个MetaTrader5环境。虽然我可以在Windows机器上做到这一点,但我想将其作为独立的Docker容器部署在我的(我还有两个我更喜欢编码的系统:mac和linux)机器或AWS中ECR。
为此,我创建了这个docker文件:
FROM ubuntu:20.04
# In order to use the python version,we'll have to install
# wine emulator. We're installing both 32 and 64 bits API.
RUN dpkg --add-architecture i386
RUN apt update
ENV TZ=UTC
RUN apt-get install --assume-yes apt-utils
RUN DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes tzdata
RUN apt-get install --assume-yes wine64 wine32
# The root wine prefix will be: /root/.wine.
# Now MetaTrader5 is being moved to the Program Files directory.
copY ["MetaTrader5","/root/.wine/drive_c/Program Files/MetaTrader5"]
# Also the Python interpreter is moved to that directory.
ADD ["python-3.9.0","/root/.wine/drive_c/Program Files/python-3.9.0"]
# And the get-pip script is added to the standard interpreter.
ADD ["https://bootstrap.pypa.io/get-pip.py","/root/.wine/drive_c/Program Files/python-3.9.0/get-pip.py"]
# The server script itself is then added as another application.
RUN ["mkdir","-p","/root/.wine/drive_c/Program Files/MetaTrader5 AI Server"]
copY ["server.py","/root/.wine/drive_c/Program Files/MetaTrader5 AI Server/server.py"]
############### 'Till this point,everything is fine.
# Now,pip will be installed for windows.
RUN ["wine","/root/.wine/drive_c/Program Files/python-3.9.0/pythonw.exe","/root/.wine/drive_c/Program Files/python-3.9.0/get-pip.py"]
# And then,MetaTrader will be installed,along with aiohttp
# library for websockets.
# RUN pip install MetaTrader5 aiohttp
# Choosing this tail command is just for debug
# purposes,as the true implementation will use
# the server.py file as entry point.
CMD ["tail","-f","/dev/null"]
我遇到的问题涉及最后一部分:执行get-pip.py
时,将使用Scripts/
和{{1来创建/root/.wine/drive_c/Program Files/python-3.9.0/Scripts
目录(pip.exe
) }}可执行文件,但是在尝试调用它们中的任何一个时,都会出现错误,因为似乎未安装easy_install.exe
python模块。
这可以通过运行以下dockerfile进行测试:
pip
然后:
$ docker build . --tag=mt5pyserver
$ docker run --name=prueba -it mt5pyserver bash
我需要在Windows python解释器中正确安装root@a169a4c4aae8:~# cd ".wine/drive_c/Program Files/python-3.9.0"
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0# wine python.exe get-pip.py
Collecting pip
Using cached pip-20.2.3-py2.py3-none-any.whl (1.5 MB)
Collecting setuptools
Using cached setuptools-50.3.0-py3-none-any.whl (785 kB)
Collecting wheel
Using cached wheel-0.35.1-py2.py3-none-any.whl (33 kB)
Installing collected packages: pip,setuptools,wheel
WARNING: The scripts pip.exe,pip3.9.exe and pip3.exe are installed in 'C:\Program Files\python-3.9.0\Scripts' which is not on PATH.
Consider adding this directory to PATH or,if you prefer to suppress this warning,use --no-warn-script-location.
WARNING: The scripts easy_install-3.9.exe and easy_install.exe are installed in 'C:\Program Files\python-3.9.0\Scripts' which is not on PATH.
Consider adding this directory to PATH or,use --no-warn-script-location.
WARNING: The script wheel.exe is installed in 'C:\Program Files\python-3.9.0\Scripts' which is not on PATH.
Consider adding this directory to PATH or,use --no-warn-script-location.
Successfully installed pip-20.2.3 setuptools-50.3.0 wheel-0.35.1
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0# pip
bash: pip: command not found
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0# wine Scripts/pip.exe
Traceback (most recent call last):
File "runpy.py",line 197,in _run_module_as_main
File "runpy.py",line 87,in _run_code
File "C:\Program Files\python-3.9.0\Scripts\pip.exe\__main__.py",line 4,in <module>
ModuleNotFoundError: No module named 'pip'
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0# wine --version
wine-5.0 (Ubuntu 5.0-3ubuntu1)
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0#
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0# wine Scripts/pip.exe
Traceback (most recent call last):
File "runpy.py",in <module>
ModuleNotFoundError: No module named 'pip'
root@a169a4c4aae8:~/.wine/drive_c/Program Files/python-3.9.0#
。有一个根本原因:软件包pip
仅对于Windows python版本存在。最后,我想安装该软件包以及aiohttp。然后,服务器将使用MetaTrader5 documentation for Python integration中所述的那些软件包以及我自己的一些魔法。
我该怎么做才能避免出现该错误?
解决方法
看看this Dockerfile
。它可能会给您一些见识。所使用的方法完全不同。
此Dockerfile
与您的设置之间存在一些值得注意的区别:
- 使用 WineHQ 的软件包存储库中的
wine
,而不是Ubuntu的软件包存储库。 - 从python.org下载python
msi
设置文件,并使用wine msiexec
安装它们。
这里是Dockerfile
中的一个例外:
...
...
ARG PYINSTALLER_VERSION=4.0
...
...
RUN set -x \
&& for msifile in `echo core dev exe lib path pip tcltk tools`; do \
wget -nv "https://www.python.org/ftp/python/$PYTHON_VERSION/amd64/${msifile}.msi"; \
wine msiexec /i "${msifile}.msi" /qb TARGETDIR=C:/Python37; \
rm ${msifile}.msi; \
done \
&& cd /wine/drive_c/Python37 \
&& echo 'wine '\''C:\Python37\python.exe'\'' "$@"' > /usr/bin/python \
&& echo 'wine '\''C:\Python37\Scripts\easy_install.exe'\'' "$@"' > /usr/bin/easy_install \
&& echo 'wine '\''C:\Python37\Scripts\pip.exe'\'' "$@"' > /usr/bin/pip \
&& echo 'wine '\''C:\Python37\Scripts\pyinstaller.exe'\'' "$@"' > /usr/bin/pyinstaller \
&& echo 'wine '\''C:\Python37\Scripts\pyupdater.exe'\'' "$@"' > /usr/bin/pyupdater \
&& echo 'assoc .py=PythonScript' | wine cmd \
&& echo 'ftype PythonScript=c:\Python37\python.exe "%1" %*' | wine cmd \
&& while pgrep wineserver >/dev/null; do echo "Waiting for wineserver"; sleep 1; done \
&& chmod +x /usr/bin/python /usr/bin/easy_install /usr/bin/pip /usr/bin/pyinstaller /usr/bin/pyupdater \
&& (pip install -U pip || true) \
&& rm -rf /tmp/.wine-*
ENV W_DRIVE_C=/wine/drive_c
ENV W_WINDIR_UNIX="$W_DRIVE_C/windows"
ENV W_SYSTEM64_DLLS="$W_WINDIR_UNIX/system32"
ENV W_TMP="$W_DRIVE_C/windows/temp/_$0"
# install Microsoft Visual C++ Redistributable for Visual Studio 2015,2017 and 2019 dll files
RUN set -x \
&& rm -f "$W_TMP"/* \
&& wget -P "$W_TMP" https://aka.ms/vs/16/release/vc_redist.x64.exe \
&& cabextract -q --directory="$W_TMP" "$W_TMP"/vc_redist.x64.exe \
&& cabextract -q --directory="$W_TMP" "$W_TMP/a10" \
&& cabextract -q --directory="$W_TMP" "$W_TMP/a11" \
&& cd "$W_TMP" \
&& rename 's/_/\-/g' *.dll \
&& cp "$W_TMP"/*.dll "$W_SYSTEM64_DLLS"/
# install pyinstaller
RUN /usr/bin/pip install pyinstaller==$PYINSTALLER_VERSION
...
...
此外,为什么在Python 2> = 2.7.9或Python 3> = 3.4 already includes pip
时必须安装pip
?
还要注意,recommended是在同一apt-get update/install
步骤中放置相关命令(RUN
)。