为何Dockerfile的ENTRYPOINT无法执行Server.sh,但run命令指定却可行?
使用以下Dockerfile构建镜像后,ENTRYPOINT无法正常执行:
# Use an official Ubuntu as the base image ARG BASE_IMAGE=eclipse-temurin:8-jdk FROM ${BASE_IMAGE} # Set environment variable for non-interactive apt installs ENV DEBIAN_FRONTEND=noninteractive # Install necessary dependencies RUN apt-get update && apt-get install -y \ wget \ curl \ unzip \ sudo \ screen \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Set the working directory WORKDIR /tekkit2 # Download Tekkit 2 Server (make sure to replace URL with the official one) RUN wget -O Tekkit2.zip https://servers.technicpack.net/Technic/servers/tekkit-2/Tekkit-2_Server_v1.2.4.zip \ && unzip Tekkit2.zip \ && rm Tekkit2.zip RUN echo "#!/bin/bash\njava -server -Xmx5G -Dfml.queryResult=confirm -jar forge-1.12.2-14.23.5.2860.jar nogui" > Server.sh \ && chmod 755 Server.sh # Accept Minecraft EULA (skip this if you want to manually accept the EULA) # RUN echo "eula=true" > eula.txt # Expose the Minecraft default port EXPOSE 25565 ENTRYPOINT [ "./Server.sh" ]
启动容器时收到报错:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./Server.sh": stat ./Server.sh: no such file or directory: unknown
但执行命令 docker run -it --entrypoint ./Server.sh tekkit2-server 却能成功运行容器。已确认Server.sh位于WORKDIR指定的/tekkit2目录中,尝试覆盖解压得到的LaunchServer.sh脚本失败,但echo "eula=true" > eula.txt可正常生效,因此创建了新的Server.sh脚本,仍出现文件找不到的问题,希望了解Docker运行机制中导致该现象的原因。
核心问题出在Docker ENTRYPOINT的两种格式差异以及容器启动时的工作目录处理逻辑:
ENTRYPOINT的exec格式vs shell格式
Dockerfile中使用的ENTRYPOINT [ "./Server.sh" ]是exec格式,这种模式不会启动shell进程,而是直接调用指定的可执行文件。此时Docker不会自动切换到WORKDIR设置的目录,而是默认从容器根目录(/)查找文件,自然找不到相对路径的./Server.sh。
而docker run --entrypoint ./Server.sh命令在执行时,会结合镜像中设置的WORKDIR来解析路径,本质是通过shell间接执行,因此能正确找到/tekkit2/Server.sh。路径解析规则差异
若要使用exec格式的ENTRYPOINT,必须指定文件的绝对路径,比如ENTRYPOINT [ "/tekkit2/Server.sh" ],这样Docker能直接定位到文件。如果想保留相对路径,可改用shell格式的ENTRYPOINT:ENTRYPOINT ./Server.sh,这种模式会启动shell,shell会先切换到WORKDIR指定的目录再执行脚本。RUN命令与ENTRYPOINT的逻辑差异
你提到echo "eula=true" > eula.txt能生效,是因为RUN命令始终会继承WORKDIR的上下文执行,和ENTRYPOINT的exec格式逻辑完全不同。
内容的提问来源于stack exchange,提问作者Blaise Place

