在 docker 运行 但在 docker 启动时不执行 CMD
Make a CMD effect on docker run but not in docker start
背景:
我正在使用 docker.
部署 python-web(django) 环境
而且我想制作一个干净的docker镜像,只包含运行-time环境,但不包含源代码,然后将代码卷进去。
我的 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
在脚本中,我将执行以下操作:
- 如果没有源卷,尝试启动一个 django 项目;
- 在
requirements.txt
中安装 PyPI 要求;
- 启动 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
有什么好的解决办法吗?
我将稍微扩展 Matt 的评论并添加另一个想法以实现我根据您的脚本理解的最终目标。
想法 #1:设置开发环境变量
如果您将启动脚本修改为如下内容,则可以控制某些组件是否 运行:
#!/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
环境变量设置为 true
或其他一些文本。如果没有它(默认情况下),容器将启动 gunicorn 并假定所有依赖项都在那里,并且没有代码安装在图像中构建的内容上。
想法 #2:分离操作
默认情况下 运行 时,我非常喜欢图像 "that just work"。因此,如果您可以规定您的默认设置是使用所有代码和依赖项构建映像(来自构建过程)。那么你得到的 CMD
of gunicorn -b 0.0.0.0:8000 -w 4 -k eventlet $PROJECT.wsgi
应该足以做到这一点。
然后在开发方面,只需使用 pip install -r requirements.txt && django-admin startproject $PROJECT .
之类的指令手动覆盖 docker run
处的 CMD
。如果有帮助,您可以将其设为单独的脚本 dev.sh
:
#!/bin/bash
set -e
pip install -r requirements.txt
exec django-admin startproject $PROJECT .
背景:
我正在使用 docker.
部署 python-web(django) 环境而且我想制作一个干净的docker镜像,只包含运行-time环境,但不包含源代码,然后将代码卷进去。
我的 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
在脚本中,我将执行以下操作:
- 如果没有源卷,尝试启动一个 django 项目;
- 在
requirements.txt
中安装 PyPI 要求; - 启动 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
有什么好的解决办法吗?
我将稍微扩展 Matt 的评论并添加另一个想法以实现我根据您的脚本理解的最终目标。
想法 #1:设置开发环境变量
如果您将启动脚本修改为如下内容,则可以控制某些组件是否 运行:
#!/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
环境变量设置为 true
或其他一些文本。如果没有它(默认情况下),容器将启动 gunicorn 并假定所有依赖项都在那里,并且没有代码安装在图像中构建的内容上。
想法 #2:分离操作
默认情况下 运行 时,我非常喜欢图像 "that just work"。因此,如果您可以规定您的默认设置是使用所有代码和依赖项构建映像(来自构建过程)。那么你得到的 CMD
of gunicorn -b 0.0.0.0:8000 -w 4 -k eventlet $PROJECT.wsgi
应该足以做到这一点。
然后在开发方面,只需使用 pip install -r requirements.txt && django-admin startproject $PROJECT .
之类的指令手动覆盖 docker run
处的 CMD
。如果有帮助,您可以将其设为单独的脚本 dev.sh
:
#!/bin/bash
set -e
pip install -r requirements.txt
exec django-admin startproject $PROJECT .