如何使用配置文件部署 Flask 应用程序?

How to deploy a flask application with a config file?

我有一个 Flask 应用程序,我使用了一个包含一些敏感信息的配置文件。我想知道如何使用配置文件部署我的应用程序而不释放它包含的敏感信息。

TLDR;创建一个 class 来保存您的配置机密,将实际机密存储在主机上的环境变量中,并在您的应用程序中读取环境变量。

下面是详细的实现。

这是我的文件夹结构:

api
|_cofig
  |_config.py
|_app.py

然后在我的 app.py 内部,它实际上启动了我的 Flask 应用程序,它看起来大致像这样(我已经排除了无关紧要的所有内容)。

from config.config import config
def create_app(app_environment=None):
    if app_environment is None:
        app = Flask(__name__)
        app.config.from_object(config[os.getenv('FLASK_ENV', 'dev')])
    else:
        app = Flask(__name__)
        app.config.from_object(config[app_environment])

if __name__ == "__main__":
    app = create_app(os.getenv('FLASK_ENV', 'dev'))
    app.run()

这允许您动态指定应用程序环境。例如,您可以通过设置环境变量并在调用 create_app() 之前读取它来传递应用程序环境。如果您使用 Docker 或其他虚拟化工具将 Flask 应用程序容器化,这将非常有用。

最后,我的 config.py 文件如下所示。您可以将我的每个环境配置中的属性更改为您的机密。

import os

class ProdConfig:
    # Database configuration
    API_TOKEN = os.environ.get('PROD_MARKET_STACK_API_KEY_SECRET')


class DevConfig:
    # Database configuration
    API_TOKEN = os.environ.get('API_KEY_SECRET')

class TestConfig:
    # Database configuration
    API_TOKEN = os.environ.get('MARKET_STACK_API_KEY')

config = {
    'dev': DevConfig,
    'test': TestConfig,
    'prod': ProdConfig
}

此外,您可以通过以下方式在 Flask 应用程序的任何模块中访问您的配置机密...

from flask import current_app
current_app.config['API_TOKEN']`

我认为您问题的答案可能与您的应用程序部署位置更相关,而不是您使用的网络框架。

据我所知,在源文件中 store/track 敏感信息(例如密码和 API 密钥)是一种不好的做法,您应该避免这种做法。

如果您已经提交了该敏感数据并且想将其从您的 git 历史记录中完全删除,我建议您检查此 GitHub page

一些高级解决方案可能是:

  1. 您是否配置了文件访问环境变量而不是硬编码值。
  2. 如果您使用的是 Google Cloud Platform or AWS 等云服务,您可以使用秘密管理器来存储您的数据并从您的应用中安全地获取数据。
  3. 另一种方法可能是存储加密信息(可能使用 KMS 之类的东西),并在需要时解密(我最不喜欢)。

我已经在 azure 上部署了我的 Flask Web 应用 api。我有很多配置文件,为此我创建了一个单独的目录,用于保存所有配置文件。这是我的项目目录的样子

configs
   -> app_config.json
   -> client_config.json
logs
   -> app_debug.log
   -> app_error.log
data
   -> some other data related files
app.py

app.py 是我的主要 python 文件,我从中导入了所有配置文件,下面是我如何使用它

config_file = os.path.join(os.path.dirname(__file__), 'configs', 'app_config.json')

# Get the config data from config json file
json_data = open(config_file)
config_data = json.load(json_data)
json_data.close()

之后我可以轻松地在代码中的任何地方使用 config_data

mongo_db = connect_mongodb(username=config_data['MongoUsername'], password=config_data['MongoPassword'], url=config_data['MongoDBURL'], port=config_data['Port'], authdbname=config_data['AuthDBName'])