我正在考虑从pip和virtualenv切换到pipenv。但在研究了文档后,我仍然对pipenv的创建者如何构建部署工作流程感到茫然。
例如,在开发中我有一个定义环境的Pipfile
和Pipfile.lock
。使用我想部署的部署脚本
git pull
通过Github到生产服务器pipenv install
在部署用户的主目录中创建/刷新环境但是我需要在systemd或supervisor中配置的特定目录中使用venv。例如:command=/home/ubuntu/production/application_xy/env/bin/gunicorn module:app
pipenv在某些地方创造了环境,例如/home/ultimo/.local/share/virtualenvs/application_xy-jvrv1OSi
使用pipenv
部署应用程序的预期工作流程是什么?
那里你没什么选择。
pipenv run
运行你的gunicorn:
pipenv run gunicorn module:app
这会产生轻微的开销,但具有从$PROJECT_DIR/.env
(或其他$PIPENV_DOTENV_LOCATION
)加载环境的优势。
PIPENV_VENV_IN_PROJECT
环境变量。这将使pipenv的virtualenv保持在$PROJECT_DIR/.venv
而不是全球位置。我刚刚切换到pipenv
进行部署,我的工作流程大致如下(使用ansible管理)。对于一个名为“project”的假想项目,假设将一个正在运行的Pipfile.lock检入源代码控制:
git clone https://github.com/namespace/project.git /opt/project
cd /opt/project
git checkout $git_ref
virtualenv -p"python$pyver" /usr/local/project/$git_ref
VIRTUAL_ENV="/usr/local/project/$git_ref" pipenv --python="/usr/local/project/$git_ref/bin/python" install --deploy
当Pipfile.lock与Pipfile不匹配时,--deploy
将抛出错误。pip
安装项目本身(仅当它不在Pip文件中时才需要):
/usr/local/project/$git_ref/bin/pip install /opt/project
ln -s /usr/local/project/$git_ref /usr/local/project/current
我的应用程序可以调用,例如例如,与/usr/local/project/current/bin/project_exec --foo --bar
配置的supervisor。
当标签被推送到遥控器时,所有这一切都会被触发。
由于早期版本的virtualenvs保持不变,因此只需将current-
symlink设置回早期版本即可完成回滚。即如果标签1.5坏了,我想回到1.4,我所要做的就是ln -s /usr/local/project/1.4 /usr/local/project/current
并用supervisorctl
重新启动应用程序。
我认为pipenv非常适合管理依赖项,但速度太慢,繁琐且使用它进行自动部署仍然有点不稳定。
相反,我使用virtualenv(或virtualenvwrapper)和pip在目标机器上。
requirements.txt
创建一个pipenv lock -r
兼容的文本文件:
$ pipenv lock -r > deploy-requirements.txt
$ pip install -r deploy-requirements.txt