我的基本问题:如何设置在Elastic Beanstalk部署过程中有效的环境变量?
我不是在讨论在部署期间设置环境变量,部署后我的应用程序可以访问它,我想设置环境变量来修改Elastic Beanstalk构建脚本的特定行为。
要明确 - 我一般认为这是一个坏主意,但在这种情况下可能没问题,所以我尝试将其作为实验。这里有一些关于我为什么要研究这个问题的背景,以及为什么我认为它可能没问题:
我正在将服务器从美国的AWS转移到中国的AWS,并且发现服务器部署在50%~100%的时间内失败,具体取决于当天。这是开发过程中的一个主要痛苦,但我主要关注的是如何在生产中完成这项工作。
这是运行Python 2.7的Amazon Linux服务器,日志表明失败主要是读取超时错误,偶尔会抛出几次连接重置,所有这些都是由 pip install 尝试从pypi下载包时。为了验证这一点,我已经在我的实例中ssh到手动安装一些软件包,并且在一个小的样本大小上看到类似的故障率。请注意,这在尝试访问中国GFW另一端的内容时非常常见。
所以,我编写了一个脚本, pip download 包裹到我的本地机器,然后 aws sync 将它们发送到位于与我相同区域的S3桶中服务器。这样就无需在部署时跨越GFW。
我最初的计划是添加一个.ebextension aws cp s从S3到pip缓存的软件包,但是(除非我遗漏了一些东西)这有点令人惊讶地看起来不是直截了当
因此,作为计划B,我将包重定向到实例上的本地目录。这工作得很好,但是我无法通过 pip install 从本地目录中提取包,而不是从pypi下载包。
在pip文档之后,我预计将PIP_FIND_LINKS环境变量指向我的包目录会从我的目录中自然地拉出包,而不是pypi。这将使更改对EB构建脚本透明,以及为什么我认为这可能是一个合理的解决方案。
到目前为止,我已经尝试过:
1)命令导出PIP_FIND_LINKS = / path / to / package,没有运气。我认为这是因为部署步骤是从另一个会话调用的,所以我尝试了:
2)命令(除了上一次导出之外)将导出PIP_FIND_LINKS = / path / to / package 附加到〜。/ profile,以尝试这适用于任何新会议。
我已尝试通过ec2_user和root发出命令,但都不起作用。
我希望那些对EB,pip等细微差别有更多经验的人可以提供一些指导,而不是一直坚持这一点。
答案 0 :(得分:1)
经过一番思考后,我认为pip config file应该是比环境变量更可靠的解决方案。
事实证明,使用.ebextensions很容易实现。我首先创建下载脚本,然后直接在virtualenv文件夹中创建配置文件:
files:
/home/ec2-user/download_packages.sh:
mode: "000500"
owner: root
group: root
content: |
#!/usr/bin/env bash
package_dir=/path/to/packages
mkdir -p $package_dir
aws s3 sync s3://bucket/packages $package_dir
/opt/python/run/venv/pip.conf:
mode: "000755"
owner: root
group: root
content: |
[install]
find-links = file:///path/to/packages
no-index=false
最后,命令用于调用我们刚刚创建的脚本:
commands:
03_download_packages:
command: bash /home/ec2-user/download_packages.sh
一个潜在的问题是pip绕过本地包目录并下载存储在我们的私有git仓库中的包,因此仍有可能出现超时错误,但这些只代表需要安装的软件包的一小部分所以它应该是可行的。
仍然不确定这是否是一个长期的解决方案,但它非常简单,并且(经过一天的测试......)失败率从50%~100%下降到0%。