Python 如何在docker容器中提供django机密

Python 如何在docker容器中提供django机密,python,django,dockerfile,Python,Django,Dockerfile,我的环境 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.load

我的环境

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)
# 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!
#!/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_KEY = os.environ.get('SECRET_KEY')
它从SECRET_CONFIG环境变量获取文件路径

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

我已经创建了一个dockerfile,它使用python3 onbuild映像

我的Dockerfile看起来像这样

# 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)
# 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!
#!/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_KEY = os.environ.get('SECRET_KEY')
dockder-entrypoint.sh文件如下所示

# 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)
# 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!
#!/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_KEY = os.environ.get('SECRET_KEY')
我尝试在使用此命令启动容器时设置环境变量SECRET\u CONFIG

docker run -e SECRET_CONFIG=/home/stokvis/dev/app/secrets.json --name django-app-test -it django-app:latest
但docker似乎不想加载变量

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


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

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

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

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

# 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)
# 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!
#!/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_KEY = os.environ.get('SECRET_KEY')
然后我在kubernetes部署中使用以下设置来调用settign

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

我可能弄错了,但是,如何将项目文件复制到docker容器中?是否确定docker容器中的项目路径与本地环境中的项目路径相同(/home/stokvis/dev/app/)?您可能需要像处理logs文件夹一样将secrets.json文件装载到docker文件中的docker项目中。您是对的,我可以将secrets文件装载到容器中,挑战是我正在尝试将任何需要保密的内容保存在容器外。我将继续调查这个问题,目前的最佳实践建议不要这样做。通过docker中的环境变量管理的秘密很容易查看,不应该被认为是安全的。好的,所以这个答案是不安全的。克里斯托弗·亨特,你有什么建议?您愿意自己回答这个问题吗?@Rakaim我使用的解决方案可能比这里描述的更复杂,但本质上是:将所有机密添加到vault并设置一个可以检索机密的python连接对象。将
设置.py
文件中的所有
os.environ.get
或类似调用替换为从Vault获取该机密的方法。初始Vault连接凭据可以存储为docker swarm secret,也可以存储在Jenkins或任何其他可以进行加密秘密存储的系统中,并且不会在日志等中公开。非常感谢。