如何在Docker容器中持续保存Julia包

7
我在树莓派4上运行Julia。由于我的需求,我需要Julia 1.5版本,好在这里有一个Docker镜像:https://github.com/Julia-Embedded/jlcross 我的问题是,因为这是正在开发中的项目,我需要在工作过程中不断添加软件包。最佳方法是何种方式能够持久地保存更新后的环境?
以下是我的问题:
  1. 我很难理解如何保存Julia软件包管理器中的软件包,以便下次运行容器时保留它们。
  2. 每次安装软件包时提交Docker容器似乎不太合适。
是否有关于最佳方式的共识?或者也许有其他方法可以实现我想做的事情吗?
3个回答

4
你可以通过将专用卷挂载到容器内的/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 REPL中运行以下命令来检查它是否位于非标准位置:

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

你做得很好!感谢你帮我找到了如何使用Docker轻松完成这个任务。为了让它在这种特殊情况下工作,以下是有效的命令:$ docker run --mount source=juliadotfolder,target=/root/.julia -it terasakisatoshi/jlcross:rpizero-v1.5.0 julia - user1026169

3
您可以通过 Julia 的 Project.toml 文件来管理包及其版本。 该文件可同时保存您的依赖列表。
以下是一个 Julia 会话示例:
julia> using Pkg

julia> pkg"generate MyProject"
 Generating  project MyProject:
    MyProject\Project.toml
    MyProject\src/MyProject.jl

julia> cd("MyProject")

julia> pkg"activate ."
 Activating environment at `C:\Users\pszufe\myp\MyProject\Project.toml`

julia> pkg"add DataFrames"

现在的最后一步是向您的Project.toml文件提供软件包版本信息。我们先检查“有效”的版本号:

julia> pkg"st DataFrames"
Project MyProject v0.1.0
Status `C:\Users\pszufe\myp\MyProject\Project.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/)。 在移动安装程序时,如果您想要控制所有软件包的实际安装位置,则有时可能会非常方便。例如,您可能希望在具有相同Julia安装的2个Docker之间复制JULIA_DEPOT_PATH文件夹,以避免安装软件包所需的时间,或者您可能正在构建没有互联网连接等的Docker镜像。


1
也许将 Manifest.toml 文件进行版本控制,而不是在 Project.toml 中手动固定依赖项的特定版本,会更有趣。 - François Févotte
是的!但不知怎么的,我觉得在每个新环境中重新实例化项目时,Julia包管理器更加健壮。我曾经有过一些从Manifest.toml恢复状态的不良经历。此外,如果您添加了一个新的包,它将每次重写您的清单,并且包管理器操作可能会更新您的版本。Docker环境总是更加脆弱,因此我更喜欢自己掌控。最终,这当然是品味的问题;-) - Przemyslaw Szufel
感谢您详细的回复!但我仍在努力弄清楚如何将其应用于我的Docker容器。您能帮我解决这个问题吗?我假设每次运行容器时都不必重新安装和预编译每个软件包。 - user1026169
1
所有软件包的安装状态以及预编译都保存在 JULIA_DEPOT_PATH 中。您也可以构建一个 Julia 系统映像并将其分发到 Docker 上,但这种方法不太方便。 - Przemyslaw Szufel

0
在我的 Dockerfile 中,我只需像使用 pip 一样安装软件包即可:
FROM jupyter/datascience-notebook

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

我从一个基础的数据科学笔记本开始,其中包括Julia,并从命令行调用Julia来执行安装软件包所需的代码。目前唯一的缺点是每次在VS Code中加载容器时都会触发软件包预编译。

如果我需要新的软件包,我只需将它们添加到列表中即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接