как я должен постоянно сохранять пакеты Julia в контейнере Docker

#docker #package #containers #julia #persistent-storage

#docker #пакет #контейнеры #джулия #постоянное хранилище

Вопрос:

Я запускаю Julia на Raspberry pi 4. Для того, что я делаю, мне нужна Julia 1.5, и, к счастью, здесь есть ее изображение в docker: https://github.com/Julia-Embedded/jlcross

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

Вот мои проблемы:

  1. Мне трудно сосредоточиться на томах, которые будут сохранять пакеты из менеджера пакетов Julia и сохранять их при следующем запуске контейнера

  2. Кажется неудобным каким-то образом фиксировать мой контейнер docker каждый раз, когда я устанавливаю пакет.

Есть ли консенсус относительно наилучшего способа или, может быть, есть другой способ сделать то, что я пытаюсь сделать?

Ответ №1:

Вы можете сохранить состояние загруженных и предварительно скомпилированных пакетов, установив выделенный том /home/your_user/.julia внутри контейнера:

 $ docker run --mount source=dot-julia,target=/home/your_user/.julia [OTHER_OPTIONS]
  

В зависимости от того, как (и каким пользователем) julia запускается внутри контейнера, вам может потребоваться настроить указанный выше целевой путь, чтобы указать на первую запись в Julia DEPOT_PATH .

Вы можете управлять этим путем, установив его самостоятельно через переменную JULIA_DEPOT_PATH среды. Кроме того, вы можете проверить, находится ли он в нестандартном расположении, выполнив следующую команду в репозитории Julia в контейнере:

 julia> println(first(DEPOT_PATH))
/home/francois/.julia
  

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

1. Вы справились! Спасибо, что помогли мне найти, как легко сделать это с помощью docker. чтобы заставить его работать в этом конкретном случае, это то, что сработало: $ docker run --mount source=juliadotfolder,target=/root/.julia -it terasakisatoshi/jlcross:rpizero-v1.5.0 julia

Ответ №2:

Вы можете управлять пакетом и их версиями с помощью Project.toml файла Julia. Этот файл может содержать как список ваших зависимостей.

Вот пример сеанса Julia:

 julia> using Pkg

julia> pkg"generate MyProject"
 Generating  project MyProject:
    MyProjectProject.toml
    MyProjectsrc/MyProject.jl

julia> cd("MyProject")

julia> pkg"activate ."
 Activating environment at `C:UserspszufemypMyProjectProject.toml`

julia> pkg"add DataFrames"
  

Теперь последний шаг — предоставить информацию о версии пакета вашему Project.toml файлу. Мы начинаем с проверки номера версии, который «работает хорошо»:

 julia> pkg"st DataFrames"
Project MyProject v0.1.0
Status `C:UserspszufemypMyProjectProject.toml`
  [a93c6f00] DataFrames v0.21.7
  

Теперь вы хотите отредактировать Project.toml файл [compat] , чтобы исправить этот номер версии, чтобы он всегда был v0.21.7 :

 name = "MyProject"
uuid = "5fe874ab-e862-465c-89f9-b6882972cba7"
authors = ["pszufe <pszufe@******.com>"]
version = "0.1.0"

[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"

[compat]
DataFrames = "= 0.21.7"
  

Обратите внимание, что в последней строке оператор равенства дважды, чтобы исправить точный номер версии см. Также https://julialang.github.io/Pkg.jl/v1/compatibility /.

Теперь, чтобы повторно использовать эту структуру (например, другой docker, перемещение между системами и т. Д.), Все, что вам нужно сделать, это

 cd("MyProject")
using Pkg
pkg"activate ."
pkg"instantiate"
  

Дополнительное примечание

Также взгляните на JULIA_DEPOT_PATH переменную (https://docs.julialang.org/en/v1/manual/environment-variables /). При перемещении установок между docker здесь и там иногда может быть также удобно контролировать, где на самом деле установлены все ваши пакеты. Для примера вы можете скопировать JULIA_DEPOT_PATH папку между 2 docker, имеющими одинаковые установки Julia, чтобы избежать времени, затрачиваемого на установку пакетов, или вы могли бы создавать образ Docker без подключения к Интернету и т. Д.

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

1. Также может быть интересно управлять версиями файла Manifest.toml вместо того, чтобы вручную привязывать зависимости к определенным версиям в Project.toml

2. Да! Но почему-то я чувствую, что менеджер пакетов Julia более надежен при повторном создании проекта в каждой новой среде. Раньше у меня был неудачный опыт восстановления состояния Manifest.toml . Более того, если вы добавите новый пакет, он будет переписывать ваш манифест каждый раз, и операции диспетчера пакетов могут обновлять вашу версию. Среды Docker всегда более хрупкие, поэтому я предпочитаю сам контролировать. В конце концов, это, конечно, дело вкуса 😉

3. спасибо за подробный ответ! я все еще пытаюсь понять, как применить его к моим контейнерам docker. можете ли вы мне помочь? я предполагаю, что мне не придется переустанавливать и предварительно компилировать каждый пакет при каждом запуске контейнера.

4. Все состояние установки пакета вместе с предварительной компиляцией сохраняется JULIA_DEPOT_PATH . Вы также можете создать системный файл Julia и распространять его по docker, но это менее удобно.

Ответ №3:

В моем Dockerfile я просто устанавливаю пакеты так же, как вы бы сделали с pip :

 FROM jupyter/datascience-notebook

RUN julia -e 'using Pkg; Pkg.add.(["CSV", "DataFrames", "DataFramesMeta", "Gadfly"])'
  

Здесь я начинаю с базовой записной книжки datascience, в которую входит Julia, а затем вызываю Julia из командной строки, инструктируя ее выполнить код, необходимый для установки пакетов. Единственным недостатком на данный момент является то, что предварительная компиляция пакета запускается каждый раз, когда я загружаю контейнер в VS Code.

Если мне нужны новые пакеты, я просто добавляю их в список.