Docker
构建镜像的方式有两种,分别为 使用 docker commit
命令的方式以及利用 Dockerfile
方式。
我通过在 Windows 10
操作系统的虚拟机,安装的 CentOS 7.0
, CentOS
是最小安装版,安装后需要将服务器内核和补丁全部更新一遍。
在 CentOS
安装 Docker
后,可以查看 Docker
版本为 20.10.17
,截止当前是 Docekr
社区版当中的最新版本。
我用一个自己写的 SpringBoot Web
项目,已经运行的 boot-app
作为源镜像,通过它再制作一个镜像名为 clone-boot
。
docker commit
制作镜像,步骤可分为:运行容器脚本、镜像打包、导入镜像三个部分。
docker commit
的参数有四个,按照顺序,它们的含义分别是:指定作者、将 Dockerfile
指令应用于创建的镜像、提交的描述信息、以及提交期间暂停容器。
Flag shorthand -h has been deprecated, please use --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Options:
-a, --author string Author (e.g., "John Hannibal Smith ")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
docker commit boot-app clone-boot
docker run -di --name clone-boot -p 19091:19090 clone-boot
使用的命令为 docker exec
,具体用法如下表,此处也把它所有包含的命令罗列出来。
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
名称 | 描述 | 备注 |
---|---|---|
-d | 以守护进程运行 | |
-e | 设置环境变量 | |
-i | 保持 STDIN 打开,即使没有连接 | |
-t | TTY 模式 | |
-u | 用户 | |
-w | 容器内的工作目录 |
docker exec -it clone-boot /bin/bash
java -version
我在容器里头,更新 yum
命令,并且最后安装了 vim
文本,当然实际上还可以做自己想做的任何事情。
利用 docker save [OPTIONS] IMAGE [IMAGE...]
将运行中的容器打包,通过 -o
输出到某个磁盘路径中。
docker save -o /data/clone-boot.tar clone-boot
有了镜相报,我们导入docker load [OPTIONS]
,它只有两个参数
tar
文件中读取
docker load -i /data/clone-boot.tar
Dockerfile
使用基本的基于 DSL
指令,构建一个 Docker
镜像,而后我们直接使用 docker builder
命令基于该 Dockerfile
中的指令构建一个新的镜像。
Flag shorthand -h has been deprecated, please use --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default
"default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
用于指定 基础镜像
,写在 Dockerfile
文件首行。后续所有指令都依赖指定的 基础镜像
。 FROM
指令指定的 基础镜像
可以是官方远程仓库的,也可以位于私有仓库或者本地仓库。
由于是必选,所以在使用上遇到需要多个镜像过程中,可以指定多个 FROM
指令。
实际使用中该指令有两种书写格式:
FROM $IMAGE
: 指定 基础镜像
为该镜像的最后修改的版本,我们经常默认不屑,即版本截止镜像使用时的 latest
。FROM $IMAGE:$TAG
: 为该 基础镜像
指定其在镜像分支版本这个指令指定这个镜像创建者的基本信息,镜像创造者对这个镜像的标记。
当仓库中的镜像不能满足我们的要求,我们需要在构建镜像过程中安装定制的软件。常见的我们需要在镜像中安装 RUN yum install ‐y vim
。
实际使用中该指令有两种书写格式:
RUN $COMMAND
RUN ["executable", "param1", "param2" ... ]]
ADD
、 COPY
这两个指令比较类似,作用都是复制宿主机上的文件到目标镜像中。使用上的区别主要在于 ADD
还支持使用 tar
文件和 URL
路径。
ADD/COPY ...
WORKDIR
指令,用于在镜像中,切换所在的工作目录,类似于 cd
命令。
注意:通过 WORKDIR
设置工作目录后, Dockerfile
中其后的命令 RUN
、 CMD
、 ENTRYPOINT
、 ADD
、 COPY
等命令都会在该目录下执行。但是在使用 docker run
运行容器时,可以通过 -w
参数覆盖构建时所设置的工作目录。
WORKDIR /usr/local/
VOLUME
指令用于指定容器中需要持久化目录,防止因容器关闭造成容器中的更改出现丢失。但是它只能在指定容器内的路径,不能指定宿主机的路径。
Dockerfile
生成镜像容器,/data/mysql
目录中的数据在容器关闭后,里面的数据还存在
FROM base
VOLUME ["/data/mysql"]
$Source_Container
的 /data/mysql
共享给 $Target_Container
。
docker run ‐t ‐i ‐rm ‐volumes‐from $Source_Container $Target_Container bash
EXPOSE
指令,声明该容器的端口映射会到宿主机的端口,默认是 tcp
方式,还有 udp
使用上需要注意下。
Dockerfile
使用 EXPOSE
设置需要映射的容器端口。‐P
参数,加上 EXPOSE
设置的端口,这样 EXPOSE
设置的端口号会被随机映射成宿主机高阶端口。此处的 ‐P
是大写如果 EXPOSE
暴露的端口确定要和宿主机端口之间建立映射关系,一定要用到 docker run -p
此处的 ‐p
是小写
CMD
指令指定启动容器的默认要运行的程序,也就是 PID
为 1
的进程命令,且其运行结束后容器也会终止。如果不指定,默认是 bash
。该指令只能在 Dockerfile
文件中存在一次,如果有多个,则只执行最后一条。
实际使用中该指令有三种书写格式:
RCMDUN ["executable","param1","param2"]
CMD command param1 param2
CMD ["param1","param2"]
ENTRYPOINT
指令指定启动容器的默认要运行的程序,与 CMD
较为类似。但是 ENTRYPOINT
只能使用 JSON
方式指定执行命令,而不能指定参数,这一点需要和 CMD
配合来使用。
实际使用中该指令有两种书写格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
在执行方式上: ENTRYPOINT 单独执行,如果此时还有 CMD ,则 CMD 和 ENTRYPOINT 会互相覆盖,只有最后一个 CMD 或 ENTRYPOINT 有效。
USER
指令,设置启动容器的用户,默认是 root
用户。
以下样例我是将我本地磁盘一个 JavaWeb
文件打包为一个镜像,并指定了运行参数,这是最简单一个样例。
FROM openjdk:8
ADD demo-will.jar /demo.jar
ENTRYPOINT ["java", "-jar", "demo.jar"]