Heroku部署Docker镜像时Julia依赖未保存问题求助
问题:Docker部署Julia应用到Heroku时依赖包丢失
我写了一个Dockerfile用来安装Julia及相关依赖,之后调用脚本,脚本第一行是using JSServe,这个依赖应该已经安装好了。
Dockerfile内容
# Runs ubuntu commands FROM ubuntu # Install wget and other RUN apt-get update && \ apt-get install -y wget && \ apt-get install -y tar # Downloads and install julia ENV JULIA_NAME "julia-1.9.0-beta2-linux-x86_64.tar.gz" RUN wget https://julialang-s3.julialang.org/bin/linux/x64/1.9/${JULIA_NAME} && \ tar -xvzf ${JULIA_NAME} && \ mv julia-1.9.0-beta2 /opt/ && \ ln -s /opt/julia-1.9.0-beta2/bin/julia /usr/local/bin/julia && \ rm ${JULIA_NAME} # Copy files COPY Project.toml ./Project.toml COPY JSServe_app.jl ./JSServe_app.jl # Install deps RUN julia --project -e "import Pkg; Pkg.instantiate(); Pkg.precompile()" # Run apps CMD julia --project -e 'include("JSServe_app.jl")'
这个配置在本地运行完全正常,但部署到Heroku远程服务器时,出现如下错误:
Starting process with command `/bin/sh -c julia\ -e\ \'include\(\"JSServe_app.jl\"\)\'` ERROR: LoadError: ArgumentError: Package JSServe not found in current path.
我搞不懂原因……JSServe应该已经安装了,Docker构建在本地能正常完成。
补充日志
后来发现似乎已安装的包被莫名移除:
2023-01-31T14:38:11.444805+00:00 heroku[web.1]: Starting process with command `/bin/sh -c julia\ --project\=\.\ -e\ \"import\ Pkg\;\ Pkg.status\(\)\"` 2023-01-31T14:38:13.572537+00:00 app[web.1]: Installing known registries into `~/.julia` 2023-01-31T14:38:17.410042+00:00 heroku[web.1]: Process exited with status 0 2023-01-31T14:38:17.466348+00:00 heroku[web.1]: State changed from starting to crashed 2023-01-31T14:38:17.176302+00:00 app[web.1]: Status `~/Project.toml` 2023-01-31T14:38:17.212226+00:00 app[web.1]: → [824d6782] JSServe v2.1.0 2023-01-31T14:38:17.212346+00:00 app[web.1]: → [276b4fcb] WGLMakie v0.8.6 2023-01-31T14:38:17.212445+00:00 app[web.1]: Info Packages marked with → are not downloaded, use `instantiate` to download
解决方法
1. 明确指定工作目录与项目路径
从日志能看出,Heroku运行时的项目路径是~/Project.toml,但原Dockerfile未固定工作目录,导致--project参数找不到正确的依赖目录。修改Dockerfile,创建并固定工作目录:
# 创建并切换到工作目录 WORKDIR /app # 复制文件到工作目录 COPY Project.toml ./ COPY JSServe_app.jl ./ # 安装依赖时指定绝对项目路径 RUN julia --project=/app -e "import Pkg; Pkg.instantiate(); Pkg.precompile()" # 启动应用时同样使用绝对路径 CMD julia --project=/app -e 'include("/app/JSServe_app.jl")'
2. 清除Heroku构建缓存
Heroku可能缓存了旧的镜像层,导致依赖安装步骤未正确执行。执行以下命令清除缓存后重新部署:
heroku builds:cache:purge -a <你的应用名称>
3. 锁定依赖版本
本地生成Manifest.toml文件,确保Heroku安装的依赖与本地完全一致:
- 本地执行
julia --project -e "import Pkg; Pkg.resolve()"生成Manifest.toml - 在Dockerfile中添加复制该文件的命令:
COPY Manifest.toml ./
4. 构建时验证依赖状态
在Dockerfile的依赖安装步骤后,添加验证命令,确保构建阶段依赖已正确安装:
RUN julia --project=/app -e "using JSServe; println('JSServe加载成功')"
如果本地构建失败,说明本地环境存在问题;如果本地成功但Heroku失败,可排除构建逻辑问题,聚焦Heroku运行环境。
内容的提问来源于stack exchange,提问作者Alexandre Renchon
相关产品推荐
相关产品推荐

