需求:利用dockerfile的ENTRYPOINT在容器启动时自动执行脚本

一、编写测试dockerfile

# version: 0.0.1
FROM dialogserver
MAINTAINER bob "bob@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
EXPOSE 80
ENTRYPOINT ["./startup.sh"]  

二、构建镜像

docker build -t sh_test .

三、启动脚本startup.sh的内容

 #!/bin/bash
echo 'hello diango'
uwsgi dialog.xml
nginx 

三、启动镜像(挂载数据卷)

docker run -it -p 8001:80 -v /home/startup.sh:/root/dialog_core/startup.sh --rm 7782e94816a6

四、报错

在这里插入图片描述

/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "exec: \"./startup.sh\": permission denied".

分析原因:权限不足

解决:

给容器添加特权

在dockerfile中添加run指令执行chmod a+x startup.sh

# version: 0.0.2
FROM dialogserver
MAINTAINER bob "bob@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
RUN chmod a+x startup.sh
EXPOSE 80
ENTRYPOINT ["./startup.sh"]   

报错:没有脚本文件
在这里插入图片描述

chmod: cannot access 'startup.sh': No such file or directory

重新编写dockerfile

# version: 0.0.2
FROM dialogserver
MAINTAINER wanglong "wanglongtin@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
RUN mkdir startup && chmod -R 755 startup
EXPOSE 80
ENTRYPOINT ["./startup.sh"] 

构建新镜像

# 位置在Dockerfile所在的目录
docker build -t sh_test2 . 

启动新镜像

docker run -it -p 8001:80 -v /home:/root/dialog_core/startup --rm bf5d1253388f

报错 :原因还是没有文件,这才意识到ENTRYPOINT执行的命令必须是已有镜像中存在的

/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "exec: \"./startup.sh\": stat ./startup.sh: no such file or directory".
重新编写dockerfile0.3版本
# version: 0.0.3
FROM dialogserver
MAINTAINER bob "bob@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
RUN touch startup.sh && chmod a+x startup.sh
EXPOSE 80
ENTRYPOINT ["./startup.sh"] 

构建并启动

docker build -t sh_test3 .
# 启动
docker run -it -p 8001:80 -v /home/startup.sh:/root/dialog_core/startup.sh --rm sh_test3 

报错:依然是文件权限问题
在这里插入图片描述
普通启动

docker run -it sh_test3 /bin/bash

报错:

standard_init_linux.go:178: exec user process caused "exec format error"

解决:未解决

修改docker中阻止selinux转换的无新特权的解决方法

vim /etc/sysconfig/docker

–selinux-enabled 删除 或者–selinux-disabled

构建dockerfile0.5版本
# version: 0.0.5
FROM dialogserver
MAINTAINER wanglong "wanglongtin@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
RUN touch startup.sh && chmod a+x startup.sh
EXPOSE 80
CMD ["./startup.sh"]
     

启动

docker run -u root -it -p 8001:80 -v /home/startup.sh:/root/dialog_core/startup.sh  sh_test /bin/bash -c 'sh ./startup.sh' 

添加参数后可以启动,但是不是理想的样子,继续尝试

构建dockerfile0.6版本,在ENTRYPOINT中加入参数‘sh’
# version: 0.0.6
FROM dialogserver
MAINTAINER wanglong "wanglongtin@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
RUN touch startup.sh
EXPOSE 80
ENTRYPOINT ["sh","./startup.sh"]
~                                

启动1

docker run -u root -it -p 8001:80 -v /home/startup.sh:/root/dialog_core/startup.sh  sh_test6

启动2

docker run -it --rm -p 8001:80 -v /home/startup.sh:/root/dialog_core/startup.sh  sh_test6

终于可以正常启动,达到设想的效果

五、dialogweb终极版的dockerfile(脚本执行)

# version: 0.0.7
FROM sh_test6
MAINTAINER bob "bob@163.com"
ENV MYPATH /root/dialog_core
WORKDIR $MYPATH
RUN touch startup.sh
EXPOSE 80
CMD ["sh","./startup.sh"]    

说明:

基础镜像是基于原有的 sh_test6,CMD可以换成ENTRYPOINT,只是我想在docker run后接参数可以覆盖CMD里的命令

启动容器的命令

docker run -it --rm -p 8001:80 -v /home/startup.sh:/root/dialog_core/startup.sh dialogweb

宿主机上的脚本内容为

 #!/bin/bash
echo 'hello diango'
cd /root/dialog_core/
uwsgi dialog.xml
nginx
echo 'server start'
/bin/bash

启动容器后,输入ctrl +p+q,退出bash

关键点总结:

1、CMD和ENTRYPOINT里想要执行的脚本文件必须是在容器构建过程中的某一层容易里存在的文件。
2、脚本要保证大于1个进程,如果脚本中不写最后一条,容器启动后就会自动关闭
3、docker run 后面必须跟的参数是 -it,没有也不行(具体原因,暂时未知)

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐