自定义镜像
镜像的分层结构
常见的镜像在DockerHub就能找到, 如果我们自己要部署一个Java项目就要手动把它打包为一个镜像
- 部署一个Java应用的大概流程:
准备一个Linux运行环境(CentOS或者Ubuntu均可)--> 安装并配置JDK --> 上传Jar包 --> 运行jar包
- 将Java应用打包成镜像大概流程:
准备Linux运行环境(只需要包括Java项目的基础运行环境即可)-- > 安装并配置JDK --> 拷贝jar包 --> 配置启动脚本
Layer层
: 打包镜像过程中的每一次操作其实都是在生产一些磁盘文件如系统运行环境文件、函数库文件、配置文件
,这些文件不是随意堆放的而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一Id形成层
重复利用镜像文件
: 如果我们构建某个镜像时用到的某些层其他人已经制作过,就可以直接拷贝使用别人已经制作好的层,在别人制作的镜像基础上进行打包基础镜像层
: 构建镜像的第一步需要的Linux运行环境文件
通用性就很强,所以Docker官方就制作了这样只包含Linux运行环境的镜像,如CentOS或Ubuntu
操作系统镜像或其他人制作好的镜像openjdk:8
自定义镜像本质就是依次将应用程序
和其运行时所需的基础运行环境、依赖、应用本身、运行配置
等文件按照顺序打包成一个完整的镜像文件
Dockerfile指令
由于在制作镜像时需要逐层处理和打包比较复杂, 所以Docker提供了自动打包镜像的功能,我们只需要向Docker提供一个Dockerfile文件剩下的交给Docker去执行即可
Dockerfile
是一个包含指令的文本文件,通过Docker提供的指令
记录镜像的打包过程以及每一层要做的事情,每一个指令都会形成一层Layer
-
构建自定义镜像时只需要告诉Docker我们镜像的
基础镜像,拷贝的文件,安装的依赖,启动的脚本
内容, 将来Docker会帮助我们构建镜像 -
Dockerfile文件的第一行必须使用
FROM
指定基础镜像来构建
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像(基本操作系统或其他人制作好的镜像),镜像不存在时需要先下载 | FROM centos:6 |
ENV | 设置环境变量,可在后面指令使用 | ENV key value |
COPY | 将本地文件如jar包拷贝到镜像的指定目录中,如果目录不存在Docker会自动创建 | COPY ./xx.jar /tmp/app.jar |
RUN | 执行Linux的shell命令如解压缩,一般是安装过程的命令 | RUN yum install gcc |
EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 | EXPOSE 8090 |
ENTRYPOINT | 镜像中应用的启动命令,将来容器运行时自动调用 | ENTRYPOINT java -jar xxjar |
基于基础镜像构镜像
需求: 基于Ubuntu基础镜像
构建一个新镜像,基于构建的镜像创建并启动容器运行一个Java项目
第一步: 创建一个空文件夹/root/docker-demo
,将docker-demo.jar(监听8090端口)和jdk8.tar.gz(Java运行环境)
文件拷贝到该目录下
mkdir -p /root/docker-demo
第二步: 进入docker-demo目录, 在docker-demo
目录下新建Dockerfile(文件名称固定)
文件告诉Docker如何构建镜像
# 在docker-demo目录下创建Dockerfile文件记录镜像的构建过程
cd /root/docker-demo
vi Dockerfile
# 文件内容
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量为JDK的安装目录
ENV JAVA_DIR=/usr/local
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 将当前目录下存放的jdk8.tar.g文件拷贝到/usr/local/目录下
COPY ./jdk8.tar.gz $JAVA_DIR/
# 将当前目录下存放的docker-demo.jar包拷贝到根目录下并重命名为app.jar
COPY ./docker-demo.jar /app.jar
# 安装JDK,解压/usr/local包下的压缩文件jdk8.tar.gz,将得到的解压文件jdk1.8.0_44重命名为java8目录
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置JDK的环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定容器运行时暴露的端口,如果你之前没有关闭防火墙,请关闭防火墙或打开对应端口,云服务器同理
EXPOSE 8090
# 入口即java项目的启动命令
ENTERPOINT java -jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
第三步:在docker-demo
目录下使用docker build -t 镜像名称及其版本 Dockerfile文件所在的目录(文件名称必须为Dockerfile)
命令构建镜像
docker build
: 构建一个docker镜像-t
: 指定镜像的名称包括repository和tag
,不指定tag时默认为latest.
: 指定构建镜像的Dockerfile文件所在的目录,.
代表当前所在目录,也可以通过绝对路径的方式直接指定Dockerfile文件所在目录
# 进入docker-demo目录执行构建命令,将来镜像就会存放在该目录下
cd /root/docker-demo
# 开始构建镜像,相对路径
docker build -t docker_demo:1.0 .
# 开始构建镜像,绝对路径
docker build -t docker-demo:1.0 /root/docker-demo
# 查看本地所有镜像
[root@localhost docker-demo] docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker_demo 1.0 c8acd2dd02cf About a minute ago 722MB
redis latest 29ab4501eac3 2 days ago 117MB
nginx latest 3964ce7b8458 5 days ago 142MB
ubuntu 16.04 b6f507652425 15 months ago 135MB
mysql 5.7.25 98455b9624a9 3 years ago 372MB
第四步: 根据构建的镜像创建并运行容器
# 1.创建并运行容器
docker run -d --name javaDemo -p 8090:8090 docker_demo:1.0
# 2.查看容器详情信息
dps
# 结果
CONTAINER ID IMAGE PORTS STATUS NAMES
78a000447b49 docker-demo:1.0 0.0.0.0:8080->8080/tcp, :::8090->8090/tcp Up 2 seconds javaDemo
f63cfead8502 mysql 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp Up 2 hours mysql
# 3.在虚拟机内直接访问项目接口
curl localhost:8090/hello/count
# 结果:
<h5>欢迎访问黑马商城, 这是您第1次访问<h5>
第五步: 浏览器访问http://虚拟机主机IP地址:8090/hello/count查看页面效果
基于JDK构建镜像
直接基于Ubuntu基础镜像
来构建镜像比较麻烦,大多数情况下我们可以在一些已经安装了部分软件和基础系统镜像
的镜像上做改造
我们刚刚构建Java项目时安装JDK并配置环境变量的步骤是固定死的,所以我们可以找一个已经安装好JDK的基础镜像并在其基础上来构建我们Java项目的镜像
需求: 在原先/root/docker-demo
目录的基础上修改Dockerfile文件, 基于JDK
作为基础镜像将一个Java项目构建为镜像
# 将JDK作为基础镜像的方式,如果本地没有需要下载
FROM java:8-alpine
FROM openjdk:8
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包到跟目录下并重命名为app.jar
COPY ./docker-demo.jar /app.jar
# 入口
ENTRYPOINT java -jar /app.jar
构建镜像,创建并运行一个docker_demo容器(在此之前停止之前的docker_demo容器),然后浏览器访问查看页面效果
# 构建镜像
docker build -t docker_demo:2.0 .
# 创建并运行容器
docker run -d --name javaDemo02 -p 8090:8090 docker_demo:2.0