【问题标题】:How do I make django secrets available inside docker containers如何使 django 机密在 docker 容器中可用
【发布时间】:2018-01-31 19:26:54
【问题描述】:

我的环境

docker 17.12-ce
python 3.6.3
django 1.10.8

我有一个想要容器化的 django 应用程序。

为了保持最佳实践,我已按照建议将 settings.py 文件拆分为一个基本文件,然后每个阶段一个文件

所以我加载秘密设置的 base.py 文件看起来像这样

# Settings imported from a json file
with open(os.environ.get('SECRET_CONFIG')) as f:
 configs = json.loads(f.read())
def get_secret(setting, configs=configs):
 try:
     val = configs[setting]
     if val == 'True':
         val = True
     elif val == 'False':
         val = False
     return val
 except KeyError:
     error_msg = "ImproperlyConfigured: Set {0} environment      variable".format(setting)
     raise ImproperlyConfigured(error_msg)

它从 SECRET_CONFIG 环境变量中获取文件路径。

这在没有 docker 的情况下在本地运行应用程序时效果很好。

我创建了一个使用 python3 onbuild 映像的 dockerfile。

我的 Dockerfile 看起来像这样

# Dockerfile
# FROM directive instructing base image to build upon
FROM python:3.6.4-onbuild

MAINTAINER Lance Haig

RUN mkdir media static logs
VOLUME ["$WORKDIR/logs/"]

# COPY startup script into known file location in container
COPY docker-entrypoint.sh /docker-entrypoint.sh

# EXPOSE port 8000 to allow communication to/from server
EXPOSE 8000

# CMD specifcies the command to execute to start the server running.
CMD ["/docker-entrypoint.sh"]
# done!

docker-entrypoint.sh 文件如下所示

#!/bin/bash
python manage.py migrate                  # Apply database migrations
python manage.py collectstatic --noinput  # Collect static files

# Prepare log files and start outputting logs to stdout
touch /usr/src/app/logs/gunicorn.log
touch /usr/src/app/logs/access.log
tail -n 0 -f /usr/src/app/logs/*.log &

export DJANGO_SETTINGS_MODULE=django-app.settings.development

# Start Gunicorn processes
echo Starting Gunicorn.
# exec gunicorn django-app.wsgi:application --bind 0.0.0.0:8000 --workers 3
exec gunicorn django-app.wsgi:application \
    --name sandbox_django \
    --bind 0.0.0.0:8000 \
    --workers 3 \
    --log-level=info \
    --log-file=/usr/src/app/logs/gunicorn.log \
    --access-logfile=/usr/src/app/logs/access.log \
    "$@"

我尝试在使用此命令启动容器时设置环境变量 SECRET_CONFIG

docker run -e SECRET_CONFIG=/home/stokvis/dev/app/secrets.json --name django-app-test -it django-app:latest

但似乎 docker 不想加载变量。

如果要在 docker 主机或 kubernetes 集群上运行图像,是否有更好的方法来为图像提供秘密?

我错过了一些基本的东西吗?

【问题讨论】:

  • 我可能有一个错误,但是,你如何将你的项目文件复制到 docker 容器中?您确定 docker 容器中的项目路径与本地环境(/home/stokvis/dev/app/)中的项目路径相同吗?您可能需要像使用 logs 文件夹一样将您的 secrets.json 文件挂载到 Dockerfile 中的 docker 项目。
  • 你是对的,我可以将秘密文件挂载到容器中,挑战是我试图将任何需要保密的东西保存在容器之外。我会继续调查这个

标签: python django dockerfile


【解决方案1】:

我决定使用 kubernetes / docker secrets 来提供这些解决方案。

我使用了一个基本设置文件,然后将特定设置文件用于开发和生产,这些文件作为系统内环境变量的一部分加载。

例如,base.py 中的 SECRET_KEY 设置如下所示

SECRET_KEY = os.environ.get('SECRET_KEY')

然后我在kubernetes部署中使用下面的设置来调用settign out of the secret。

- name: SECRET_KEY
  valueFrom:
    secretKeyRef:
      name: sandbox-app-secret
      key: SECRET_KEY

【讨论】:

  • 当前的最佳实践建议不要完全这样做。通过 docker 中的环境变量管理的机密很容易查看,不应被视为安全。
  • 好的,所以这个答案并不安全。你会建议@ChristopherHunter 什么?你愿意自己回答这个问题吗?
  • @Rakaim 我使用的解决方案可能比这里完全描述的要复杂,但本质上是:将所有秘密添加到保险库并设置一个可以检索秘密的 python 连接对象。将 settings.py 文件中的所有 os.environ.get 或类似调用替换为从 Vault 获取该机密的方法。初始的 Vault 连接凭据可以存储为 docker swarm secret,或存储在 Jenkins 或任何其他可以实际进行加密存储的系统中,并且不会在日志等中公开它。
  • 不错。谢谢!
  • 对于以后发现这个的人来说,上面的评论是不正确的。在 Dockerfile 的环境变量中使用凭据非常糟糕。然而,这不是这里发生的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多