我正试图从Dockerfile构建一个Docker镜像,该镜像复制并提取包含可执行文件(myapp
和其他文件)的.zip
档案。有一个运行可执行文件的docker-entrypoint.sh
脚本。docker build
成功完成,但是当我运行映像时,入口点脚本失败,表示找不到可执行文件。
$ docker build .
Successfully built 890ec2f09ad4
$ docker run 890ec2f09ad4
./docker-entrypoint.sh: line 3: ./myapp: not found
我已经通过在docker-entrypoint.sh
脚本中执行ls -l
验证了可执行文件是否已从存档中提取,并且命令是否在正确的目录中运行。
-rwxrwxr-x 1 root root 45 Jan 20 22:16 docker-entrypoint.sh
-rwxr-xr-x 1 root root 71473 Jan 20 22:16 myapp
-rw-r--r-- 1 root root 177 Jan 20 22:16 myapp.ini
如果我在Docker映像之外,在可执行文件旁边运行相同的docker-entrypoint.sh
脚本,那么一切都会完美运行。
我也试过:
- 直接从Dockerfile运行可执行文件(导致类似的"找不到文件"错误)
- 使用
ubuntu:latest
基础图像(相同错误) - 使用dos2unix确保行尾正确(无更改)
我还能尝试什么?我是Docker的新手,这似乎应该很容易完成,所以我不确定我哪里错了。。。
Dockerfile:
FROM alpine:latest
RUN mkdir -p /opt/app/
WORKDIR /opt/app/
COPY target/products/myapp.zip .
RUN unzip myapp.zip && rm myapp.zip
COPY docker-entrypoint.sh .
RUN chmod +x docker-entrypoint.sh
ENTRYPOINT ["./docker-entrypoint.sh"]
docker-entrypoint.sh:
#!/bin/sh
./myapp
感谢@VolArt将我的注意力集中在可执行类型上。
事实证明,问题在于可执行文件(一个ELF64位LSB可执行文件,动态链接)和Alpine之间的兼容性。解决方案是简单地使用不同的基础图像。最后我还需要JRE 8,所以我决定使用openjdk:8-jre
基本映像。(我还需要手动安装unzip
)
帮助解决问题的相关帖子:
- https://serverfault.com/questions/883625/alpine-shell-cant-find-file-in-docker
- https://askubuntu.com/questions/133389/no-such-file-or-directory-but-the-file-exists
Dockerfile:
FROM openjdk:8-jre
RUN mkdir -p /opt/app/
WORKDIR /opt/app/
RUN apt-get update && apt-get upgrade -y
RUN apt-get install unzip -y
COPY target/products/myapp.zip .
RUN unzip myapp.zip && rm myapp.zip
COPY docker-entrypoint.sh .
RUN chmod +x docker-entrypoint.sh
EXPOSE 8081
ENTRYPOINT ["/opt/app/docker-entrypoint.sh"]
docker-entrypoint.sh:
#!/bin/sh
/opt/app/myapp