Успешно создал virtualenv (используя "mkproject") в Dockerfile, но не может правильно запустить "workon"
Редактировать: Решено-опечатка
У меня есть Dockerfile, который успешно создает virtualenv с помощью virtualenvwrapper (наряду с настройкой кучи "стандартных" настроек / пакетов в нашей обычной среде). Я использую полученное изображение в качестве "базового изображения" для дальнейшего использования. Пока все хорошо. Однако следующий Dockerfile (основанный на первом изображении, "base_image_14.04") падает в последней строке:
FROM base_image_14.04
USER root
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && apt-get install -y \
libproj0 libproj-dev \
libgeos-c1v5 libgeos-dev \
libjpeg62 libjpeg-dev \
zlib1g zlib1g-dev \
libfreetype6 libfreetype6-dev \
libgdal20 libgdal-dev \
&& rm -rf /var/lib/apt/lists
USER webdev
RUN ["/bin/bash", "-ic", "mkproject maproxy"]
EXPOSE 80
WORKDIR $PROJECT_HOME/mapproxy
ADD ./requirements.txt .
RUN ["/bin/bash", "-ic", "workon mapproxy && pip install -r requirements.txt"]
"Mkproject mapproxy" работает нормально. Если я закомментирую последнюю строку, которую он успешно строит, и я могу раскрутить контейнер и запустить "workon mapproxy" вручную, не проблема. Но когда я пытаюсь собрать с последней строкой, это дает ошибку работы:
ERROR: Environment 'mapproxy' does not exist. Create it with 'mkvirtualenv mapproxy'.
Workon называется, но по какой-то причине он не может найти mapproxy virtualenv.
WORKON_HOME и PROJECT_HOME оба существуют (определены в родительском изображении) и указывают на правильные местоположения (и успешно используются "mkproject mapproxy").
Так почему workon возвращает ошибку, когда существует mapproxy virtualenv? Та же самая ошибка происходит, когда я изолирую эту последнюю строку в третьем здании Dockerfile на втором.
2 ответа
Решено: Это была простая опечатка. mkproject maproxy вместо mapproxy.:вздох:
Я пытаюсь создать образ докера и сталкиваюсь с подобными проблемами.
Первый вопрос: зачем использовать виртуальную среду в докере? Основной причиной в двух словах является минимизация усилий по переносу существующего и рабочего подхода в докер-контейнер. В конечном итоге я буду использовать docker-compose, но я хотел начать с того, что намочил все это в одном контейнере Docker.
В первой попытке я установил почти все с помощью apt-get, включая uwsgi. Я установил свое приложение "глобально" с помощью pip3. Приложение имеет функциональность командной строки и отдельное веб-приложение на флешке, поэтому требуется uwsgi. Функциональность командной строки работает, но когда я делаю запрос приложения фляги, у uwsgi / python возникает проблема с локалью: Fatal Python error: Py_Initialize: Unable to get the locale encoding and ImportError: No module named 'encodings
Я убрал все специфические дополнения моего приложения, чтобы сузить проблему. Это Dockerfile, который я использую:
# Docker image definition for testing
FROM ubuntu:xenial
# Create a user
RUN useradd -G sudo -ms /bin/bash tester
RUN echo 'tester:password' | chpasswd
WORKDIR /home/tester
# Skipping apt-get update to save some build time. Some are kept
# to insure they are the same as on host setup.
RUN apt-get install -y python3 python3-dev python3-pip \
virtualenv virtualenvwrapper sudo nano && \
apt-get clean -qy
# After above, can we use those installed in rest of Dockerfile?
# Yes, but not always, such as with virtualenvwrapper. What about
# virtualenv? How do you "source" the script? Doesn't appear to be
# installed, as bash complains "source needs a single parameter"
ENV VIRTUALENVWRAPPER_PYTHON /usr/bin/python3
ENV VIRTUALENVWRAPPER_VIRTUALENV /usr/bin/virtualenv
RUN ["/bin/bash", "-c", "source", "/usr/share/virtualenvwrapper/virtualenvwrapper.sh"]
# Create a virtualenv so uwsgi can find locale
# RUN mkdir /home/tester/.virtualenv && virtualenv -p`which python3` /home/bts_tools/.virtualenv/bts_tools
RUN mkvirtualenv -p`which python3` bts_tools && \
workon bts_tools && \
pip3 --disable-pip-version-check install --upgrade bts_tools
USER tester
ENTRYPOINT ["/bin/bash"]
CMD ["--login"]
Сборка завершается с ошибкой, которую я пытаюсь найти в сценарии virtualenvwrapper. Bash жалуется, что источнику нужен аргумент - файл для поиска. Поэтому я закомментирую строки RUN, и он собирается без ошибок. Когда я запускаю полученный контейнер, я вижу все дополнения к ENV, которые делает virtualenvwrapper (вы можете увидеть их все, выполнив команду "set" без каких-либо аргументов), и сценарий, который нужно найти, тоже там.
Поэтому мой вопрос: почему докер их не находит? Как работает процесс сборки Docker, если результаты любых предыдущих RUN или ENV не применяются для последующего использования в Dockerfile? Я знаю, что некоторые вещи применяются и работают, например, если вы apt-get nginx
Вы можете обратиться к /etc/nginx или изменить вещи в этой папке. Например, вы можете создать пользователя и установить его пароль или компакт-диск в его домашнюю папку. Если я перенесу WORKDIR до RUN useradd -G
Я вижу предупреждение от useradd: домашняя папка уже существует. Я пытался использовать программу "время" для определения времени, которое требуется для выполнения различных операций в Dockerfile, и докер жалуется, что не может найти "время".
Так что именно происходит? Я провел последние 3 дня, пытаясь выяснить это. Это просто не должно быть так сложно. Что мне не хватает?
Части приложения фляги bts_tools работали, когда я не использовал виртуальные envs. Большая часть приложения не работала, и проблема заключалась в этой языковой проблеме. Поскольку все работает на хосте за пределами докера, и после попытки изменить PATH, PYTHONHOME, PYTHONPATH в моем стартовом скрипте uwsgi для преодоления страшной фатальной ошибки "кодировки локали", я решил попытаться максимально точно скопировать настройки хоста так как у этого не было языкового вопроса. Когда у меня возникла эта проблема, прежде чем я мог бежать dpkg-reconfigure python3
или исправить с изменениями в настройках PATH или ENV. Если вы решите проблему, вы увидите, что у многих людей возникают проблемы с питоном и локалью. Это почти достаточная причина, чтобы избежать использования Python!
Я отправил это в другом месте о проблеме локали, если это помогает.