Общая библиотека libpython3.5 не найдена в контейнере Docker (но переопределение работает нормально) - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь развернуть веб-сервис Python (с флягой), который использует CNTK в Docker-контейнере.Я использую Ubuntu-Base-Image от Microsoft, который должен содержать все необходимые и правильные программы и библиотеки для запуска CNTK.

Скрипт работает локально (в Windows), а также при запуске контейнера и запускеbash из cmd-строки с

docker exec -it <container_id> bash

и запуск скрипта из «контейнера».

Важным дополнением является то, что скрипт python использует два предварительно скомпилированных модуля * .pydфайлы для windows и * .so файлы для Linux.Поэтому для образа докера я заменил первый на второй для запуска скрипта из контейнера.

Проблемы начинаются, когда я запускаю скрипт с CMD в Dockerfile.Создание изображения не показывает проблем.Но когда я запускаю контейнер с

docker run -p 1234:80 app

, я получаю следующую ошибку:

...
ImportError: libpython3.5m.so.1.0: не удается открыть общий доступобъектный файл: нет такого файла или каталога

Кажется, что библиотека отсутствует.Но (я повторяю), когда я запускаю скрипт изнутри bash, запущенного в контейнере (который должен иметь только библиотеки контейнеров, насколько я вижу), все работает нормально.Я даже могу посмотреть библиотеку с помощью

ldd $(which python)

И файл определенно находится в папке.Поэтому вопрос в том, почему python не может найти свою зависимость при запуске контейнера Docker.

Это даже страннее, когда я пытаюсь явно указать путь к библиотеке, записав ее в переменную окружения:

ENV LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/root/anaconda3/pkgs/python-3.5.2-0/lib/"

Тогда библиотека, кажется, библиотека найдена, но она не принята как правильная:

ImportError: динамический модуль не определяет функцию инициализации (initcython_bbox)

"cython_bbox" - это имя одного из файлов / библиотек * .pyd / * .so, которые необходимо импортировать.Это, очевидно, типичная ошибка для таких типов файлов.Но у меня нет никакого опыта с ними.

Я также не в состоянии (в моем личном развитии), чтобы иметь возможность компилировать мои собственные файлы из внешнего источника или создавать само изображение докера самостоятельно,Я полагаюсь на части, которые я получил от Microsoft.Но я был бы открыт для предложений.

Я также уже пытался заново установить библиотеку внутри моего Dockerfile после импорта базового образа с помощью

RUN apt-get install -y libpython3.5

Но это вызвало ту же ошибку, что и когда япоместите путь в переменную окружения.

Я действительно хочу узнать, что здесь не так.Почему все работает гладко «внутри контейнера», а не с помощью автозапуска при инициализации контейнера с CMD?

Для дополнительной информации я добавляю Dockerfile:

# Использовать официальный Pythonвремя выполнения как родительский образ ИЗ microsoft / cntk: 2.5.1-cpu-python3.5

# Установить рабочий каталог

в / app WORKDIR / app

# Копироватьтекущее содержимое каталога в контейнер в / app ADD./ app

RUN apt-get update && apt-get install -y python-pip RUN pip install --upgrade pip

# Установить все необходимые пакеты, указанные в needs.txt Установка RUN pip --trusted-host pypi.python.org -r needs.txt

# Сделать порт 80 доступным для мира вне этого контейнера EXPOSE 80

# Запустить app.py, когда контейнер запустит CMD ["python", "test.py"]

Остальная часть проекта представляет собой довольно простое флеш-веб-приложение, которое запускается без проблем, когда я закомментирую весь импорт реального CNTK-проекта.Кстати, это обнаружение объектов CNTK с помощью Faster-RCNN , как это можно найти в репозитории cntk-git.

РЕДАКТИРОВАТЬ:

Я выяснил, в чем собственно проблема, но у меня все еще нет способа ее решить.Дело в том, что когда я запускаю bash с помощью «docker exec», при запуске запускается скрипт, который активирует среду anaconda с python3.5 и всеми аккуратными библиотеками.Но когда CMD только запускает python, это делается стандартной оболочкой Bourne "sh", которая (как я уже пробовал) работает с python2.7.

Так что мне нужен способ, чтобы запустить мой контейнер с помощью bash (включая сценарии автозапуска) или как-то активировать среду при запуске другим способом.

Я посмотрел сценарий, и он в основном проверяетесли bash является текущей оболочкой, устанавливает некоторые переменные среды и активирует среду.

if [ -z "$BASH_VERSION" ]; then
  echo Error: only Bash is supported.
elif [ "$(basename "$0" 2> /dev/null)" == "activate-cntk" ]; then
  echo Error: this script is meant to be sourced. Run 'source activate-cntk'
else
  export PATH="/cntk/cntk/bin:$PATH"
  export LD_LIBRARY_PATH="/cntk/cntk/lib:/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH"
  source "/root/anaconda3/bin/activate" "/root/anaconda3/envs/cntk-py35"

  cat <<MESSAGE

************************************************************
CNTK is activated.

Please checkout tutorials and examples here:
  /cntk/Tutorials
  /cntk/Examples

To deactivate the environment run

  source /root/anaconda3/bin/deactivate

************************************************************
MESSAGE
fi

Я пробовал несколько десятков вещей, таких как связывание sh с bash

RUN ln -fs /bin/bash /bin/sh

или использование bash в качестве ENTRYPOINT.

Ответы [ 2 ]

0 голосов
/ 22 июня 2018

Я также обнаружил, что GIT Repository делает почти то же самое, что и я.И они также должны начать свою среду.Понимая, что мне нужно научиться лучше писать Dockerfiles.Я думаю, что это правильный способ сделать это, то есть использовать сценарий оболочки в качестве ENTRYPOINT

ENTRYPOINT ["/app/run.sh"]

, который активирует среду, устанавливает дополнительные пакеты Python (это может быть проблемой) и запуска фактического приложения.

#!/bin/bash
source /root/anaconda3/bin/activate root
pip install easydict
pip install azure-ml-api-sdk==0.1.0a9
pip install sanic
python3 /app/app.py
0 голосов
/ 23 мая 2018

Я нашел обходной путь, который работает на данный момент.

Сначала я вручную связываю python с python3 в своей среде:

RUN ln -fs /root/anaconda3/envs/cntk-py35/bin/python3.5 /usr/bin/python

Затем я добавляю библиотеки среды в путь к библиотеке:

ENV LD_LIBRARY_PATH "/cntk/cntk/lib:/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH"

И чтобы быть уверенным, что я добавляю все важные папки в PATH:

ENV PATH "/cntk/cntk/bin:$PATH"
ENV PATH "/root/anaconda3/envs/cntk-py35/bin:$PATH"

Затем мне нужно снова установить пакеты python:

RUN pip install flask

И, наконец, могу просто запустить мой скрипт с:

CMD ["python", "app.py"]
...