Я организую свой код в пакете Python (обычно в виртуальной среде, такой как virtualenv
и/или conda
), а затем обычно вызываю:
python <path_to/my_project/setup.py> develop
так что я могу использовать самую последнюю версию моего кода. Поскольку я разрабатываю в основном статистические алгоритмы или алгоритмы машинного обучения, я много прототипирую и ежедневно меняю свой код. Однако в последнее время рекомендуемый способ запуска наших экспериментов на кластерах, к которым у меня есть доступ, — через докер. Я узнал о докере и думаю, что у меня есть приблизительное представление о том, как заставить его работать, но я не был уверен, хороши ли мои решения или могут ли быть решения получше.
Первое решение, о котором я подумал, — это решение, которое копирует данные в моем образе докера с помощью:
COPY /path_to/my_project
pip install /path_to/my_project
а затем установите его. Проблема с этим решением заключается в том, что мне приходится каждый раз создавать новое изображение, что кажется глупым, и я надеялся, что у меня может быть что-то лучше. Для этого я думал о наличии файла bash, например:
#BASH FILE TO BUILD AND REBUILD MY STUFF
# build the image with the newest version of
# my project code and it pip installs it and its depedencies
docker build -t image_name .
docker run --rm image_name python run_ML_experiment_file.py
docker kill current_container #not sure how to do get id of container
docker rmi image_name
как я уже сказал, моя интуиция подсказывает мне, что это глупо, поэтому я надеялся, что есть одна команда, способная сделать это с помощью Docker или с одним файлом Dockerfile. Кроме того, обратите внимание, что команда должна использовать -v ~/data/:/data
, чтобы иметь возможность получить данные и какой-либо другой том/монтирование для записи (на хосте) после завершения обучения.
Еще одно решение, которое я подумал, заключалось в том, чтобы иметь все зависимости python или другие зависимости, которые нужны моей библиотеке, в файле Dockerfile (и, следовательно, в образе), а затем каким-то образом выполнять в работающем контейнере установку моей библиотеки. Возможно с docker exec [OPTIONS] CONTAINER COMMAND
как:
docker exec CONTAINER pip install /path_to/my_project
в работающем контейнере. После этого я мог бы запустить настоящий эксперимент, который хочу запустить, с той же командой exec:
docker exec CONTAINER python run_ML_experiment_file.py
тем не менее, я до сих пор не знаю, как систематически получать идентификатор контейнера (потому что я, вероятно, не хочу искать идентификатор контейнера каждый раз, когда делаю это).
В идеале, на мой взгляд, лучшим концептуальным решением было бы просто знать Dockerfile с самого начала, к какому файлу он должен подключаться (например, /path_to/my_project
), а затем каким-то образом выполнять python [/path_to/my_project] develop
внутри образа, чтобы он всегда был связан с потенциально изменяющимся python. пакет/проект. Таким образом, я могу проводить свои эксперименты с помощью одной команды docker, например:
docker run --rm -v ~/data/:/data python run_ML_experiment_file.py
и не нужно каждый раз явно обновлять образ (включая отсутствие необходимости переустанавливать части изображения, которые должны быть статичными), поскольку он всегда синхронизируется с реальной библиотекой. Кроме того, мне не нужно, чтобы какой-то другой скрипт каждый раз создавал новый образ с нуля. Кроме того, было бы неплохо иметь возможность избежать написания любого bash, если это возможно.
Думаю, я очень близок к хорошему решению. Что я буду делать вместо создания нового образа каждый раз, когда я просто запускаю команду CMD
для разработки python следующим образом:
# install my library (only when the a container is spun)
CMD python ~/my_tf_proj/setup.py develop
Преимущество заключается в том, что он будет устанавливать мою библиотеку только при запуске нового контейнера. Это решает проблему разработки, потому что повторное создание нового образа занимает много времени. Хотя я только что понял, что если я использую команду CMD
, я не могу запускать другие команды, заданные для моего запуска докера, поэтому я на самом деле имею в виду запуск ENTRYPOINT
.
Прямо сейчас единственная проблема для завершения этого заключается в том, что у меня возникают проблемы с использованием тома, потому что я не могу успешно связать мою библиотеку основного проекта в Dockerfile (для чего по какой-то причине требуется абсолютный путь) . В настоящее время я делаю (что, похоже, не работает):
VOLUME /absolute_path_to/my_tf_proj /my_tf_proj
почему я не могу связать с помощью команды VOLUME в моем Dockerfile? Мое основное намерение при использовании VOLUME — сделать мою библиотеку (и другие файлы, которые всегда нужны этому образу) доступными, когда команда CMD пытается установить мою библиотеку. Возможно ли, чтобы моя библиотека всегда была доступна при запуске контейнера?
В идеале я хотел, чтобы библиотека устанавливалась автоматически при запуске контейнера и, если возможно, поскольку самая последняя версия библиотеки всегда требуется, устанавливала ее при инициализации контейнера.
В качестве справки прямо сейчас мой нерабочий файл Dockerfile выглядит следующим образом:
# This means you derive your docker image from the tensorflow docker image
# FROM gcr.io/tensorflow/tensorflow:latest-devel-gpu
FROM gcr.io/tensorflow/tensorflow
#FROM python
FROM ubuntu
RUN mkdir ~/my_tf_proj/
# mounts my tensorflow lib/proj from host to the container
VOLUME /absolute_path_to/my_tf_proj
#
RUN apt-get update
#
apt-get install vim
#
RUN apt-get install -qy python3
RUN apt-get install -qy python3-pip
RUN pip3 install --upgrade pip
#RUN apt-get install -y python python-dev python-distribute python-pip
# have the dependecies for my tensorflow library
RUN pip3 install numpy
RUN pip3 install keras
RUN pip3 install namespaces
RUN pip3 install pdb
# install my library (only when the a container is spun)
#CMD python ~/my_tf_proj/setup.py develop
ENTRYPOINT python ~/my_tf_proj/setup.py develop
В качестве побочного замечания:
Кроме того, по какой-то причине мне нужно сделать RUN apt-get update
, чтобы иметь возможность даже установить pip или vim в моем контейнере. Люди знают, почему? Я хотел сделать это, потому что на тот случай, если я захочу подключиться к контейнеру с терминалом bash
, это было бы очень полезно.
Кажется, что Docker просто заставляет вас установить apt, чтобы всегда иметь самую последнюю версию программного обеспечения в контейнере?
docker run --name a_name your_image
, затем ссылаетесь на него вdocker exec a_name /your/command
. - person mustaccio   schedule 08.12.2016cid=$(docker run -d image)
, которая запускает контейнер отдельно (в фоновом режиме) и выводит идентификатор контейнера на стандартный вывод. - person Matt   schedule 09.12.2016