构建Postgres镜像时docker-compose报错:postgres可执行文件未找到
你遇到的错误是因为修改官方Postgres镜像的WORKDIR后,破坏了其默认启动流程的执行环境。官方postgres:14.5-alpine镜像的默认工作目录是/var/lib/postgresql,其ENTRYPOINT脚本(/usr/local/bin/docker-entrypoint.sh)依赖这个工作目录完成初始化操作,当你将WORKDIR改为/app后,脚本执行时的上下文发生变化,间接导致postgres命令无法被正确查找(或者脚本执行逻辑出错,最终触发找不到postgres的错误)。
另外,虽然理论上WORKDIR不会修改$PATH,但如果镜像构建过程中出现缓存问题,也可能导致$PATH变量异常,使得/usr/local/bin(postgres所在路径)不在$PATH中。
方法1:移除自定义的WORKDIR设置
直接删除Dockerfile中的WORKDIR /app指令,保持官方镜像的默认工作目录。这是最简单且最稳妥的方案,因为官方Postgres镜像的启动流程完全依赖默认的目录结构和上下文。
修改后的Dockerfile:
FROM postgres:14.5-alpine # 移除WORKDIR /app
方法2:显式指定ENTRYPOINT和CMD
如果你确实需要设置WORKDIR /app,可以在Dockerfile中显式继承官方镜像的ENTRYPOINT和CMD,确保启动流程不受工作目录影响:
FROM postgres:14.5-alpine WORKDIR /app # 显式指定官方的ENTRYPOINT和CMD ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] CMD ["postgres"]
方法3:清理构建缓存后重新构建
如果是镜像缓存导致的异常,执行以下命令清理缓存并重新构建:
docker compose build --no-cache docker compose up
你可以先运行自定义镜像查看$PATH是否正常,确认postgres所在路径是否在$PATH中:
docker run --rm <你的自定义镜像名> sh -c 'echo $PATH && which postgres'
如果输出包含/usr/local/bin且which postgres返回/usr/local/bin/postgres,说明$PATH正常,问题大概率出在ENTRYPOINT脚本的执行上下文。
内容的提问来源于stack exchange,提问作者Joe Shmo

