话不多说,直接开始!
一.Dockerfile制作jar包镜像
FROM openjdk:8-jdk-alpine
EXPOSE 8888
EXPOSE 9999
WORKDIR /opt/
COPY yourapp.jar app.jar
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
ENTRYPOINT ["java","-jar","yourapp.jar"]
CMD []
常用指令详解
FROM : 指定基础镜像,第一条必须是FROM
LABEL : 添加镜像元数据标签,如 version="1.0.0"
EXPOSE : 暴露端口
WORKDIR: 设置工作目录,相对路径会基于这个目录,如果不存在则会自动创建
USER : 指定容器运行时使用的用户,不指定默认为root
ADD : 复制宿主机文件或目录到镜像中,如 ADD app.jar /opt/
COPY : 复制宿主机文件或目录到镜像中,如 COPY app.jar /opt/
RUN : 执行命令并提交结果,把结果添加为一层镜像,如 RUN yum -y install vim
ENV : 设置环境变量,如 ENV JAVA_HOME=/usr/local/java/jdk1.8.0_192
VOLUME : 容器数据卷,可将宿主机目录与容器目录做映射,如 VOLUME “/var/log/applog”
ENTRYPOINT: 指定容器启动时默认的启动程序,“docker run” 指定 “--entrypoint” 时覆盖
CMD : 提供容器启动时默认执行的命令或参数,可以被 “docker run” 覆盖
ADD命令和COPY命令的区别
COPY:文件或目录复制命令
ADD :文件或目录复制命令,支持远程URL(可直接从URL下载文件)和自动解压tar文件
使用场景:推荐使用 COPY,因为 COPY 只完成复制任务,不会引入额外的复杂性。如果明确有其他特殊需求的情况下,使用 ADD。
CMD命令和ENTRYPOINT命令
CMD:提供容器启动时默认执行的命令或参数,可以被 “docker run” 覆盖,如果Dockerfile中有多个CMD,只有最后一个生效
ENTRYPOINT: 指定容器启动时默认的启动程序,“docker run” 指定 “--entrypoint” 时覆盖
使用场景:
1.仅使用CMD:容器更具有灵活性,允许用户在运行时指定任意命令或参数
2.仅使用ENTRYPOINT:专门用于执行特定应用程序的镜像,不希望用户轻易改变这个程序。例如构建Redis镜像
3.组合使用:最常见的用法。ENTRYPOINT设定不变的部分,CMD提供默认的参数,允许用户在运行时覆盖默认参数。
如:
ENTRYPOINT ["echo hello"]
CMD ["world"]
不特殊指定时,输出 “hello”, docker run <image> "java",输出为“hello java”
二、容器启动结束后立刻关闭
这是因为在容器启动时,指定的命令执行完成,进程退出,容器也就随之停止。如果需要容器长期存活,需要运行一个长期存活的进程。
比如CMD命令执行的是 “echo”、“ls”等。在容器启动时执行该命令,命令执行完毕,容器就会退出。
制作jar包镜像时,可直接运行java程序,这是一个长期存活进程,可以保证容器长期存活。但是要确保应用程序是以前台模式运行的。例如:
FROM openjdk:8-jdk-alpine
ENTRYPOINT ["java", "-jar", "app.jar"]
CMD []
在Dockerfile中定义了正确的CMD或者ENTRYPOINT,在使用docker-compose启动容器时,也要注意:docker-compose.yml文件中的command字段会覆盖Dockerfile中的CMD。如:
version: '3'
services:
app:
image: my-image
command: ["-Xmx512m", "-Dspring.profiles.active=prod"]
docker-compose.yml文件中的command命令作用是覆盖Dockerfile中的CMD部分。
- 如果ENTRYPOINT存在,command的内容会被当作ENTRYPOINT的参数。
- 如果没有ENTRYPOINT,command会完全取代CMD。
如果使用docker run命令,需要注意,docker run后面指定新的命令,会覆盖Dockerfile中的 CMD命令,并且忽略ENTRYPOINT。如:docker run my-image echo "hello world!"