Ollama 在 /tmp 启动 runner 报 permission denied
Ollama 0.1.33 的真实案例涉及 noexec 临时目录。先核对实际报错路径与挂载选项,再设置受限的专用 OLLAMA_TMPDIR,保留 /tmp 加固并验证模型启动。
启动模型时,错误指向临时目录中的可执行文件:
fork/exec /tmp/ollama2604787016/runners/cpu_avx2/ollama_llama_server: permission denied
官方 issue #4229 报告了 Linux、Ollama 0.1.33 下的这个现象:用户将 /tmp 挂载为 noexec,运行器解压后不能从那里执行。目录名中的数字是当次临时路径,排查时使用自己的报错路径。
较新版本的运行器布局可能不同。只有实际失败文件仍落在受限临时目录,才按这条路径处理;单独一行 permission denied 还可能涉及文件权限、服务隔离或安全策略。
看实际文件落在哪个挂载点
先读同一次失败的日志,记录 runner 路径和服务版本。对于 systemd 安装:
journalctl -u ollama --since '10 minutes ago' --no-pager
systemctl show ollama -p User -p Group -p PrivateTmp -p RootDirectory
findmnt --target /tmp -o TARGET,FSTYPE,OPTIONS
检查 OPTIONS 是否含 noexec。路径不在 /tmp 时,改查它实际所在的挂载点。服务使用 PrivateTmp、容器或根目录隔离时,还要查看服务自身看到的路径,不能仅凭宿主机的挂载信息下结论。日志发给别人之前去掉账号、业务路径及凭据。
为文件补执行权限不会取消挂载的 noexec。确认是这个限制后,保留系统的 /tmp 策略,为 Ollama 准备专用目录。官方排障文档 支持通过 OLLAMA_TMPDIR 指定运行用户可写的另一处位置。
给服务设置自己的临时目录
下面假定已经核实 unit 使用 ollama 用户和组,且允许它在指定文件系统执行运行器。若实际身份不同,先替换用户与组;不要把一个不存在的服务账号套进命令。
示例使用新目录 /var/lib/ollama-runner-tmp。如果该路径已经存在,先检查归属和用途,不用下面的命令覆盖它的权限。
sudo install -d -m 0700 -o ollama -g ollama /var/lib/ollama-runner-tmp
findmnt --target /var/lib/ollama-runner-tmp -o TARGET,FSTYPE,OPTIONS
sudo -u ollama test -w /var/lib/ollama-runner-tmp
sudo -u ollama test -x /var/lib/ollama-runner-tmp
sudo systemctl edit ollama.service
目录权限的 test -x 检查可遍历性,不证明挂载允许执行文件。挂载信息仍需确认没有 noexec,服务沙箱及 SELinux/AppArmor 等策略也必须允许原本获准的操作。
在编辑器中给 drop-in 添加:
[Service]
Environment="OLLAMA_TMPDIR=/var/lib/ollama-runner-tmp"
保留已有配置。按官方 systemd 环境变量说明保存后执行:
sudo systemctl daemon-reload
sudo systemctl restart ollama
重启会中断请求,应在允许的窗口执行。只在终端 export OLLAMA_TMPDIR=...,不会改变已经运行的 systemd 服务。
如果文件系统本身也禁止执行,另选一个符合机器安全规则的专用位置。不要全局重挂载 /tmp,也不要给临时目录开放所有用户写权限。
用原来的模型启动入口确认
重启后,从原应用运行同一个小请求,或运行 ollama run 已安装模型的完整名称。查看新日志是否使用专用目录,确认不再因该 runner 的执行权限失败,并能取得模型响应。同时重新查看 /tmp 的挂载选项,确认原来的 noexec 保留。
如果版本已经不从临时目录执行 runner,或新路径仍报拒绝,继续查实际文件、服务访问范围和安全策略拒绝记录,别一律扩大权限。需要撤销配置时,只移除此次增加的 OLLAMA_TMPDIR 设置,重新加载并重启服务;不要用整体 systemctl revert 删除其他人的 drop-in,也不要在服务运行中删除它的临时目录。


