我正在尝试使用docker run命令通过Dockerfile运行Docker容器。以下是我的Dockerfile。
FROM python:3.6
# for imaging stuff
RUN apt-get update
RUN apt install libmagickwand-dev
# Create app directory
RUN mkdir -p /home/test/app
# Install Libre Office and ghostscript for pdf conversion and repairing
RUN apt-get update -qq \
&& apt-get install -y -q libreoffice \
&& apt-get remove -q -y libreoffice-gnome \
&& apt-get update \
&& apt-get -y install ghostscript \
&& apt-get -y install nano \
&& apt-get -y install poppler-utils \
&& apt-get install -y nginx
# Cleanup after apt-get commands
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
/var/cache/apt/archives/*.deb /var/cache/apt/*cache.bin
# Activate WORKING DIR
WORKDIR /home/test/app
# Initiating devnull directory
RUN mkdir -p dev_null
# Copying requirements
COPY requirements/local.txt /tmp/requirements.txt
# Install the app dependencies
RUN pip install -r /tmp/requirements.txt
COPY id_rsa /root/.ssh/id_rsa
COPY requirements/private.txt /tmp/private.txt
RUN ssh-keyscan -T 60 bitbucket.org >> /root/.ssh/known_hosts \
&& chmod 600 /root/.ssh/id_rsa \
&& pip install -r /tmp/private.txt
# Envs
ENV DJANGO_SETTINGS_MODULE app.settings.local
ENV ENVIORNMENT local
# ADD the source code and entry point into the container
ADD . /home/test/app
ADD docker-entrypoint.sh /home/test/app/docker-entrypoint.sh
# Making entry point executable
RUN apt-get update && apt-get install -y supervisor \
&& apt-get install -y nginx
#RUN mkdir -p /var/log/test
#COPY supervisor.conf /etc/supervisor/conf.d/supervisor.conf
RUN chmod +x docker-entrypoint.sh
RUN mkdir -p /var/log/test
COPY supervisor.conf /etc/supervisor/conf.d/supervisor.conf
# Exposing port
# Copy entrypoint script into the image
COPY ./docker-entrypoint.sh /
COPY ./django_nginx.conf /etc/nginx/
RUN chmod +x start.sh
#RUN chmod +x /docker-entrypoint.sh
EXPOSE 8000
ENTRYPOINT ["bash", "/docker-entrypoint.sh"]
CMD ["bash", "/home/test/app/start.sh"]
以下是我的切入点。
#!/usr/bin/env bash
set -e
# ToDo Need to enable this
#until psql $DATABASE_URL -c '\l'; do
# >&2 echo "Postgres is unavailable - sleeping"
# sleep 1
#done
#
#>&2 echo "Postgres is up - continuing"
cd app
mkdir -p app/keys
if [[ ! -e /var/log/gunicorn-access.log ]]; then
touch /var/log/gunicorn-access.log
fi
if [[ ! -e /var/log/gunicorn-error.log ]]; then
touch /var/log/gunicorn-error.log
fi
if [ "x$DJANGO_MANAGEPY_MIGRATE" = 'xon' ]; then
echo "Django starting to migrate un-applied migrations"
python manage.py migrate --noinput
fi
if [ "x$DJANGO_MANAGEPY_COLLECTSTATIC" = 'xon' ]; then
echo "Django starting to collect static data"
python manage.py collectstatic --noinput
fi
if [ "x$DJANGO_LOADDATA" = 'xon' ]; then
python manage.py loaddata taxing/fixtures/province-taxing-table-initial-data.json
fi
if [ "x$LOAD_TEMPLATE_FROM_S3" = 'xtrue' ]; then
echo "loading s3"
python manage.py loadindex
fi
# Start Gunicorn processes
echo Starting Gunicorn.
exec gunicorn test.wsgi:application \
--name test \
--workers 3 \
--log-level=info \
--log-file=/srv/logs/gunicorn.log \
--access-logfile=/srv/logs/access.log &
exec service nginx start
然后是我的start.sh
#!/bin/bash
echo "I am running"
echo "Belive me"
/usr/bin/supervisord -n
并且我正在使用docker build -t test .
构建容器,并且构建得很好。但是,当我尝试使用docker run --name test --env-file ./env test
运行此容器时,我的容器在Dockerfile的["bash", "/docker-entrypoint.sh"]
命令上退出,没有任何错误/消息,但是如果我从Dockerfile中删除entrypoint命令,它就可以正常工作。我无法找出错误。任何帮助表示赞赏。
答案 0 :(得分:0)
如果图像构建成功,则可以尝试在start.sh中添加此行
tail -f /etc/issue
您的start.sh可能看起来像这样:
#!/bin/bash
echo "I am running"
echo "Belive me"
/usr/bin/supervisord -n
tail -f /etc/issue
答案 1 :(得分:0)
这是我看到的按此顺序发生的事情:
ENTRYPOINT ["bash", "/docker-entrypoint.sh"]
CMD ["bash", "/home/test/app/start.sh"]
启动容器时,Docker运行bash /docker-entrypoint.sh bash /home/test/app/start.sh
。但是,入口点脚本根本不会查看其命令行参数,因此,您在此处指定的任何CMD
或在docker run
命令行末尾给出的任何命令都将被完全忽略。
该入口点脚本运行时:
exec gunicorn ... &
exec service nginx start
# end of file
它作为后台进程开始gunicorn
并继续到下一行;然后将其替换为service
命令。该service
命令成为主容器进程,并具有进程ID1。它启动nginx,然后立即返回。现在,主容器进程已返回,容器将退出。
对于您编写的这段代码,应删除入口点脚本末尾的exec
行,并将其替换为just
exec "$@"
这将导致shell运行其命令行参数(即Dockerfile CMD
)。
但是,有一个随时可用的nginx Docker image。通常,如果您需要多个进程,则将它们作为两个单独的容器在同一Docker网络上运行会更容易,更好。这样可以避免尝试使多个容器在同一容器中运行的复杂性。