问题:如何为多个环境自定义requirements.txt?

我有两个分支,开发和生产。每个都有依赖关系,其中一些是不同的。开发指向自身在开发中的依赖项。生产同样如此。我需要部署到Heroku,它期望每个分支的依赖性都在一个名为“ requirements.txt”的文件中。

最好的组织方式是什么?

我想到的是:

  • 维护单独的需求文件,每个分支中一个(必须在频繁合并中生存!)
  • 告诉Heroku我要使用哪个需求文件(环境变量?)
  • 编写部署脚本(创建临时分支,修改需求文件,提交,部署,删除临时分支)

I have two branches, Development and Production. Each has dependencies, some of which are different. Development points to dependencies that are themselves in development. Likewise for Production. I need to deploy to Heroku which expects each branch’s dependencies in a single file called ‘requirements.txt’.

What is the best way to organize?

What I’ve thought of:

  • Maintain separate requirements files, one in each branch (must survive frequent merges!)
  • Tell Heroku which requirements file I want to use (environment variable?)
  • Write deploy scripts (create temp branch, modify requirements file, commit, deploy, delete temp branch)

回答 0

您可以级联需求文件,并使用“ -r”标志告诉pip将一个文件的内容包含在另一个文件中。您可以将需求分解成模块化的文件夹层次结构,如下所示:

`-- django_project_root
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   `-- prod.txt
`-- requirements.txt

文件的内容如下所示:

common.txt:

# Contains requirements common to all environments
req1==1.0
req2==1.0
req3==1.0
...

dev.txt:

# Specifies only dev-specific requirements
# But imports the common ones too
-r common.txt
dev_req==1.0
...

prod.txt:

# Same for prod...
-r common.txt
prod_req==1.0
...

在Heroku之外,您现在可以设置如下环境:

pip install -r requirements/dev.txt

要么

pip install -r requirements/prod.txt

由于Heroku在项目根目录中专门查找“ requirements.txt”,因此应仅镜像prod,如下所示:

requirements.txt:

# Mirrors prod
-r requirements/prod.txt

You can cascade your requirements files and use the “-r” flag to tell pip to include the contents of one file inside another. You can break out your requirements into a modular folder hierarchy like this:

`-- django_project_root
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   `-- prod.txt
`-- requirements.txt

The files’ contents would look like this:

common.txt:

# Contains requirements common to all environments
req1==1.0
req2==1.0
req3==1.0
...

dev.txt:

# Specifies only dev-specific requirements
# But imports the common ones too
-r common.txt
dev_req==1.0
...

prod.txt:

# Same for prod...
-r common.txt
prod_req==1.0
...

Outside of Heroku, you can now setup environments like this:

pip install -r requirements/dev.txt

or

pip install -r requirements/prod.txt

Since Heroku looks specifically for “requirements.txt” at the project root, it should just mirror prod, like this:

requirements.txt:

# Mirrors prod
-r requirements/prod.txt

回答 1

今天发布原始问题和答案时不存在的可行选择是使用pipenv而不是pip管理依赖项。

使用pipenv,不再需要像pip一样手动管理两个单独的需求文件,而是通过命令行上的交互来管理开发和生产包本身。

要安装用于生产和开发的软件包:

pipenv install <package>

要仅为开发环境安装软件包:

pipenv install <package> --dev

通过这些命令,pipenv在两个文件(Pipfile和Pipfile.lock)中存储和管理环境配置。Heroku当前的Python buildpack本机支持pipenv,如果存在Pipfile.lock而不是requirements.txt,它将从Pipfile.lock进行配置。

有关该工具的完整文档,请参见pipenv链接。

A viable option today which didn’t exist when the original question and answer was posted is to use pipenv instead of pip to manage dependencies.

With pipenv, manually managing two separate requirement files like with pip is no longer necessary, and instead pipenv manages the development and production packages itself via interactions on the command line.

To install a package for use in both production and development:

pipenv install <package>

To install a package for the development environment only:

pipenv install <package> --dev

Via those commands, pipenv stores and manages the environment configuration in two files (Pipfile and Pipfile.lock). Heroku’s current Python buildpack natively supports pipenv and will configure itself from Pipfile.lock if it exists instead of requirements.txt.

See the pipenv link for full documentation of the tool.


回答 2

如果您的要求是能够在同一台计算机上的环境之间进行切换,则可能有必要为需要切换到的每个环境创建不同的virtualenv文件夹。

python3 -m venv venv_dev
source venv_dev/bin/activate
pip install -r pip/common.txt
pip install -r pip/dev.txt
exit
python3 -m venv venv_prod
source venv_prod/bin/activate
pip install -r pip/common.txt
exit
source venv_dev/bin/activate
# now we are in dev environment so your code editor and build systems will work.

# let's install a new dev package:
# pip install awesome
# pip freeze -r pip/temp.txt
# find that package, put it into pip/dev.txt
# rm pip/temp.txt

# pretty cumbersome, but it works. 

If your requirement is to be able to switch between environments on the same machine, it may be necessary to create different virtualenv folders for each environment you need to switch to.

python3 -m venv venv_dev
source venv_dev/bin/activate
pip install -r pip/common.txt
pip install -r pip/dev.txt
exit
python3 -m venv venv_prod
source venv_prod/bin/activate
pip install -r pip/common.txt
exit
source venv_dev/bin/activate
# now we are in dev environment so your code editor and build systems will work.

# let's install a new dev package:
# pip install awesome
# pip freeze -r pip/temp.txt
# find that package, put it into pip/dev.txt
# rm pip/temp.txt

# pretty cumbersome, but it works. 

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。