Более элегантная команда запуска docker

#python #linux #docker #dockerfile

#python #linux #docker #dockerfile

Вопрос:

Я создал образ docker, используя Dockerfile, который выполняет следующее:

 FROM my-base-python-image
WORKDIR /opt/data/projects/project/
RUN mkdir files
RUN rm -rf /etc/yum.repos.d/*.repo
COPY rss-centos-7-config.repo /etc/yum.repos.d/
COPY files/ files/
RUN python -m venv /opt/venv amp;amp; . /opt/venv/activate
RUN yum install -y unzip
WORKDIR files/
RUN unzip file.zip amp;amp; rm -rf file.zip amp;amp; . /opt/venv/bin/activate amp;amp; python -m pip install *
WORKDIR /opt/data/projects/project/
 

Это создает образ, который позволяет мне запускать пользовательскую команду. Например, в терминале вот команда commmand, которую я запускаю после активации моего проекта venv:

 python -m pathA.ModuleB -a inputfile_a.json -b inputfile_b.json -c
 

Аргументы a amp; b — это пользовательские теги для идентификации входных файлов. -c вызывает блок кода.

Итак, чтобы успешно запустить созданный образ, я запускаю контейнер и сопоставляю локальные файлы с входными файлами:

 docker run --rm -it -v /local/inputfile_a.json:/opt/data/projects/project/inputfile_a.json -v /local/inputfile_b.json:/opt/data/projects/project/inputfile_b.json image-name:latest bash -c 'source /opt/venv/bin/activate  amp;amp; python -m pathA.ModuleB -a inputfile_a.json -b inputfile_b.json -c'
 

Помимо сокращения путей к файлам, могу ли я что-нибудь сделать, чтобы сократить docker run команду? Я думаю, что добавление CMD и / или ENTRYPOINT в Dockerfile помогло бы, но я не могу понять, как это сделать, поскольку я получаю ошибки.

Комментарии:

1. Как насчет использования переменных среды? Или настройка скрипта через стандартный интерфейс?

2. как насчет использования docker-compose ? это вариант?

3. Сопоставьте /opt/data/projects/project/ /local вместо этого, чтобы получить все файлы за один раз (и, возможно, использовать $PWD , если он находится в текущем каталоге). Затем установите точку входа, чтобы вам не нужны bash source были части и .

4. Создание виртуальной среды внутри контейнера — это подход с поясом и подтяжками. Вы можете значительно упростить контейнер, установив все для всей системы.

Ответ №1:

Есть несколько вещей, которые вы можете сделать, чтобы улучшить это.

Самое простое — запустить приложение вне Docker. Вы упоминаете, что у вас есть рабочая виртуальная среда Python. Целью разработки Docker является то, что программы в контейнерах обычно не могут обращаться к файлам на хосте, поэтому, если ваше приложение предназначено для чтения и записи файлов хоста, Docker может не подойти.

Ваши пути к файлам внутри контейнера довольно длинные, и это увеличивает ваши -v параметры монтирования. Вам не нужен /opt/data/projects/project префикс; очень типично просто использовать короткие пути, такие как /app или /data .

Вы также устанавливаете свое приложение в виртуальную среду Python, но внутри образа Docker, который обеспечивает собственную изоляцию. Как вы видите в своей docker run команде и в других местах, механизм активации виртуальной среды в Docker немного запутан. Это также не обязательно; просто пропустите настройку виртуальной среды вообще. (Вы также можете запускать напрямую /opt/venv/bin/python , и он знает, что он «принадлежит» виртуальной среде, без ее явной активации.)

Наконец, в вашем setup.py файле вы можете использовать setuptools entry_points объявление для предоставления скрипта, который запускает ваш именованный модуль.

Это может уменьшить ваш Dockerfile до более или менее

 FROM my-base-python-image
# OS-level setup
RUN rm -rf /etc/yum.repos.d/*.repo
COPY rss-centos-7-config.repo /etc/yum.repos.d/
RUN yum install -y unzip
# Copy the application in
WORKDIR /app/files
COPY files/ ./
RUN unzip file.zip 
 amp;amp; rm file.zip 
 amp;amp; pip install *
# Typical runtime metadata
WORKDIR /app
CMD main-script --help
 

И затем, когда вы ее запустите, вы можете:

 docker run --rm -it 
  -v /local:/data     # just map the entire directory
  image-name:latest 
  main-script -a /data/inputfile_a.json -b /data/inputfile_b.json -c
 

Вы также можете рассмотреть docker run -w /data возможность изменения текущего каталога, что добавит аргумент уровня Docker, но немного сократит командную строку скрипта.