我正忙着在AWS Elastic Beanstalk上部署matplotlib。 I gather我的问题来自某些依赖项以及EB部署使用PIP安装的软件包的方式,并试图遵循instructions here on SO来解决问题。
我首先尝试按照链接的答案中的建议逐步部署,将matplotlib包堆栈的各个部分分阶段添加到我的requirements.txt
文件中。但这需要永远(对于每个阶段)并且容易出现故障和超时(这似乎会使构建目录落后于后续软件包安装的停顿)。
所以在答案结尾处提到的简单解决方案对我很有吸引力:只需eb ssh
,用
source /opt/python/run/venv/bin/activate
手动和pip install
个包。但我也无法让这个工作。首先,我经常遇到left-beind构建目录(如上所述)
pip can't proceed with requirement 'xxxx' due to a pre-existing build directory.
location: /opt/python/run/venv/build/xxxx
This is likely due to a previous installation that failed.
pip is being responsible and not assuming it can delete this.
Please delete it and try again.
但即使删除了这些,我也一直得到
Exception:
Traceback (most recent call last):
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/basecommand.py", line 122, in main
status = self.run(options, args)
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/commands/install.py", line 278, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/req.py", line 1197, in prepare_files
do_download,
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/req.py", line 1375, in unpack_url
self.session,
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/download.py", line 582, in unpack_http_url
unpack_file(temp_location, location, content_type, link)
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/util.py", line 625, in unpack_file
untar_file(filename, location)
File "/opt/python/run/venv/lib/python2.7/site-packages/pip/util.py", line 533, in untar_file
os.makedirs(location)
File "/opt/python/run/venv/lib64/python2.7/os.py", line 157, in makedirs
mkdir(name, mode)
OSError: [Errno 13] Permission denied: '/opt/python/run/venv/build/xxxx'
回复pip install xxxx
(而sudo pip
与sudo: pip: command not found
失败。)
我可以做些什么来使用AWS-EB?特别是,我需要做些什么来使简单的SSH + PIP方法工作;还是有其他更好的 - 更简单! - 接近我应该尝试。
FWIW,我有.ebextensions/software.config
packages:
yum:
gcc-c++: []
gcc-gfortran: []
python-devel: []
atlas-sse3-devel: []
lapack-devel: []
libpng-devel: []
freetype-devel: []
zlib-devel: []
和以{/ p>结尾的requirements.txt
pytz==2014.10
pyparsing==2.0.3
python-dateutil==2.4.0
nose==1.3.4
six>=1.8.0
mock==1.0.1
numpy==1.9.1
matplotlib==1.4.2
大约4个小时之后,我已经变得很笨拙了(正如{virtusalenv中pip list
报道的那样)。
并且(如果重要)正在进行SSHing的用户属于具有策略的组
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticbeanstalk:*",
"ec2:*",
"elasticloadbalancing:*",
"autoscaling:*",
"cloudwatch:*",
"s3:*",
"sns:*",
"cloudformation:*",
"rds:*",
"sqs:*",
"iam:PassRole"
],
"Resource": "*"
}
]
}
答案 0 :(得分:5)
我在Windows和Linux系统上使用了很多方法来构建和部署numpy / scipy / matplotlib。我使用过系统提供的软件包管理器(aptitude,rpm),第三方软件包管理器(pypm),Python软件包管理器(easy_install,pip),源代码发布,使用不同的构建环境/工具(GCC,还有英特尔MKL,OpenMP) )。在这样做的同时,我遇到了许多非常烦人的情况,但也学到了很多关于每种方法的利弊。
我没有Elastic Beanstalk(EB)的经验,但我有EC2的经验。我看到你可以通过SSH连接到一个实例并进行搜索。所以,我在下面进一步建议是基于
我的建议:从没有自己构建这些东西开始。不要使用pip。如果可能的话,尝试使用Linux发行版的软件包管理器,让它通过一个命令(例如sudo apt-get install python-matplotlib
)处理所需的一切的安装。
缺点:
优点:
所以,我希望你可以在这些机器上使用aptitude或rpm或其他任何东西,并继承分发包维护者为你做的伟大的工作,在幕后。
一旦您对应用程序有信心并发现了一些瓶颈或问题,您可能有理由使用较新的版本的numpy / matplotlib / ...或者您可能有理由拥有<通过创建优化的构建,可以实现更快的版本。
与此同时,我们了解到EB默认运行基于Red Hat Enterprise Linux的Amazon Linux。同样,它使用yum
作为包管理器,包使用RPM格式。
亚马逊提供有关可用软件包的文档。在Amazon Linux 2014.09中,可以使用以下软件包:http://aws.amazon.com/de/amazon-linux-ami/2014.09-packages/
在此列表中我们找到了
此版本的matplotlib非常陈旧,根据changelog它是从2009年9月开始的:&#34; 2009-09-21标记为0.99.1版本&#34;。
我没想到它如此旧,但仍然可能足以满足您的需求。所以我们继续我们的计划(但我知道这是否是一个阻止者)。
现在,我们have learned系统Python和EB Python相互隔离。这并不意味着EB Python无法访问系统Python站点包。我们只是需要这样说。一个简单而干净的方法是使用EB Python可以访问的包建立一个正确的目录结构,并通过sys.path
将该目录传递给EB Python。
显然,我们需要自定义EB容器的引导阶段。可用工具在此处记录:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html
显然,我们希望使用packages
方法,并告诉EB通过yum安装numpy
和python-matplotlib
个包。因此相应的配置文件部分应包含:
packages:
yum:
numpy: []
python-matplotlib: []
明确提及numpy
可能没有必要,它可能是python-matplotlib的依赖。
另外,我们需要使用commands
部分:
您可以使用命令键在EC2实例上执行命令。 命令按名称按字母顺序处理,然后运行 在应用程序和Web服务器设置和应用程序之前 提取版本文件。
以下三个命令创建上述目录,并设置指向numpy / mpl安装路径的符号链接(希望这些路径在执行这些命令时可用):
commands:
00-create-dir:
command: "mkdir -p /opt/py26-selected-site-packages"
01-link-numpy:
command: "ln -s /usr/lib64/python2.6/site-packages/numpy /opt/py26-selected-site-packages/numpy"
02-link-mpl:
command: "ln -s /usr/lib64/python2.6/site-packages/matplotlib /opt/py26-selected-site-packages/matplotlib"
两个不确定因素:AWS文档未明确packages
在执行commands
之前处理。你得试试。它不起作用,使用container_commands
。其次,在安装python-matplotlib之后,只有一个有根据的猜测/usr/lib64/python2.6/site-packages/matplotlib
可用。它应该安装到这个地方,但它可能会在其他地方结束。需要测试。 Numpy最终应该从this文章中推断出来。
[SEB更新] AWS文档说&#34; cfn-init帮助程序脚本按以下顺序处理这些配置部分:包,组,用户,源,文件,命令,然后是服务。&#34; http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html
所以,你的方法是安全的 [/ UPDATE]
正如本答案的评论中所指出的,关键步骤是告诉您的Python应用程序在哪里查找软件包。在尝试导入之前直接修改sys.path
是控制此操作的可靠方法。以下代码将我们的特殊目录添加到Python查找包的目录选择中,然后尝试导入matplotlib:
sys.path.append("/opt/py26-selected-site-packages")
from matplotlib import pyplot
sys.path
中的顺序定义了优先级,因此如果其他目录中有任何其他matplotlib或numpy包可用,那么
sys.path.insert(0, "/opt/py26-selected-site-packages")
然而,如果我们对整个方法进行深思熟虑,那就不应该这样做了。
答案 1 :(得分:3)
添加到Jan-Philip答案:
AWS Elastic Beanstalk正在使用Amazon Linux发行版(.Net环境除外)。 Amazon Linux使用yum
包管理器。 MatPlotLib可在亚马逊的软件存储库中使用。
[ec2-user@ip-1-1-1-174 ~]$ yum list | grep matplot
python-matplotlib.x86_64 0.99.1.2-1.6.amzn1 amzn-main
如果此版本是您的应用程序所需的版本,我会尝试简单地修改您的.ebextensions/software.config
文件,并将软件包添加到它的yum部分:
packages:
yum:
python-matplotlib: []
python-devel: []
atlas-sse3-devel: []
lapack-devel: []
libpng-devel: []
freetype-devel: []
zlib-devel: []
关于AWS Elastic BeansTalk和SSH的最后一点说明。
虽然亚马逊为您提供了连接到Elastic Beanstalk实例的可能性,但您应该仅将这种可能性用于调试目的,以了解您的应用程序失败或未按照建议进行安装的原因。
除此之外,您的部署必须是100%自动的。当Elastic Beanstalk(精确的Auto Scaling)将扩展您的基础架构(添加更多实例)或根据您的应用程序工作负载将其扩展(终止实例)时,您的所有手动配置都将丢失。
最佳做法是不在生产环境中安装SSH密钥,它进一步减少了攻击的范围。
答案 2 :(得分:1)
我对这个问题可能有点迟了,但是随着AWS和许多云服务提供商进入Docker并考虑到你没有指定平台。我快速解决了你的问题:
Python 2.7(这个也有你为numpy和matplotlib指定的版本)
sudo docker pull chuseuiti/pynuscimat2.7
Python 3.4
sudo docker pull chuseuiti/pynusci
但是,您可以创建自己的图像或修改现有图像。
如果您想自动化实例,可以使用图像定义将Dockerfile传递给AWS。
提示,如果您不了解泊坞广告:
需要先登录才能拉:
sudo docker login
拉动图像后,您可以使用下一个代码生成并处理使用图像创建的容器:
sudo docker run -i -t chuseuiti/pynuscimat2.7 bash
PS。至少对于免费层,AWS总是抱怨scipy和matplotlib耗尽时间,安装它们需要花费太多时间,这就是我使用此选项的原因。