在docker运行但不是在docker启动时产生CMD效果

背景:

我正在使用docker部署一个python-web(django)环境。

我想制作一个干净的docker镜像,只包含运行时环境,而不包含源代码,然后将代码放入其中。

我的docker图像存储库: https : //github.com/EaseCloud/docker-django

FROM python:latest MAINTAINER huangwc@easecloud.cn WORKDIR /var/app ENV PROJECT=app RUN apt-get update && apt-get upgrade -y && apt-get autoremove -y RUN pip install --upgrade pip && \ pip install gunicorn django greenlet eventlet COPY ./startup.sh /var RUN chmod +x /var/startup.sh VOLUME ["/var/app", "/var/app/media"] EXPOSE 8000 CMD ["/var/startup.sh"] 

所以,我现在使用CMD命令运行一个脚本startup.sh

脚本内容是:

 #!/bin/bash set -e if [ ! -e ./manage.py ]; then django-admin startproject $PROJECT . fi if [ -f ./requirements.txt ]; then pip install -r requirements.txt fi gunicorn -b 0.0.0.0:8000 -w 4 -k eventlet $PROJECT.wsgi 

在脚本中,我将执行以下操作:

  1. 尝试启动一个django项目,如果没有源卷;
  2. 在requirements.txt中安装PyPI requirements.txt ;
  3. 开始gunicorn服务;

题:

现在,因为普通的我会把源代码包括在requirements.txt ,所以我可能在不同的Docker容器实例上有不同的PyPI需求。

我想要这样做:

 pip install -r requirements.txt 

只有在我调用docker run时才会执行:

 docker run --name myproject \ -v /var/django/myproject:/var/app \ -e PROJECT=myproject \ huangwc/django 

但是当我打电话时,我不想让这个命令运行:

 docker start myproject 

有没有一个好的解决scheme来做到这一点?

我会稍微扩展Matt的评论,并根据我的理解,根据您的脚本添加另一个想法来实现最终目标。

想法#1:设置开发环境variables

如果将启动脚本修改为如下所示,则可以控制是否运行某些组件:

 #!/bin/bash set -e if [ $DEVELOPMENT ]; then if [ -f ./requirements.txt ]; then pip install -r requirements.txt fi if [ ! -e ./manage.py ]; then exec django-admin startproject $PROJECT . fi else exec gunicorn -b 0.0.0.0:8000 -w 4 -k eventlet $PROJECT.wsgi fi 

然后,在DEVELOPMENT环境中运行容器时,将DEVELOPMENT环境variables设置为true或其他文本。 没有它(默认情况下)容器启动gunicorn,并假定所有的依赖关系在那里,没有代码被安装在图像中内置的东西。

想法#2:分离出的行动

我是默认运行的图像的“风扇”。 所以,如果你可以规定你的默认是图像是用所有的代码和依赖关系(从构build过程中)构build的。 然后你的gunicorn -b 0.0.0.0:8000 -w 4 -k eventlet $PROJECT.wsgi应该足以做到这一点。

然后在开发方面只是有指示手动覆盖docker run CMD东西像pip install -r requirements.txt && django-admin startproject $PROJECT . 。 如果有帮助,你可以把它作为一个单独的脚本dev.sh

 #!/bin/bash set -e pip install -r requirements.txt exec django-admin startproject $PROJECT .