常见的镜像在Docker Hub就能找到,但是要部署自己的服务可能需要自己构建镜像。构建镜像可以使用Dockerfile。Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
镜像结构
镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
以MySQL镜像的组成结构为例:
镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。构建镜像,其实就是实现上述打包的过程。
语法
构建自定义的镜像时,并不需要一个个文件去拷贝,打包。我们只需要告诉Docker,镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么。Dockerfile就是描述上述信息的文件。Docker会通过Dockerfile构建镜像。
Dockerfile是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。
指令 | 说明 | 示例 |
---|---|---|
FROM |
指定基础镜像。必须在Dockerfile的第一行指定。 | FORM centos:6 |
ENV |
设置环境变量。在使用docker run 时可以通过-e 重设环境变量值。 |
ENV key=value |
COPY |
拷贝本地文件到镜像的指定目录。 | 复制当前目录下的mysql-5.7.rpm 到镜像的/tmp 目录:COPY ./mysql-5.7.rpm /tmp |
RUN |
执行Linux的Shell命令,一般是安装过程的命令。RUN 在docker build 时执行。 |
RUN yum install gcc |
EXPOSE |
指定容器运行时监听的端口。 | EXPOSE 8080 |
CMD |
(可以被覆盖)指定容器创建时的默认命令。CMD 在docker run 时执行。 |
|
ENTRYPOINT |
(不可被覆盖)镜像中应用的启动命令,容器运行时调用。 | ENTRYPOINT java -jar xxx.jar |
VOLUME |
为容器创建挂载点或声明卷。 | |
WORKDIR |
设置后续指令的工作目录。 | |
USER |
指定后续指令的用户上下文。 | |
SHELL |
覆盖Docker中默认的Shell,用于RUN、CMD和ENTRYPOINT指令。 |
更新详细语法说明,请参考官网文档:Dockerfile reference。
在使用Ubuntu、Debian这样的容器的时候,我们可能没办法使用它们的systemctl
命令。这是因为它们在启动时默认没有初始化系统(init
进程没有运行)。新的Debian和Ubuntu镜像中移除了init
软件包,我们可以通过Dockerfile在创建一个包含init
软件包的Debian镜像:
FROM debian:latest
# 设置环境变量
ENV APT_ETC_DIR=/etc/apt SOURCES_LIST_PATH=./sources.list
# 将在本地配置好的镜像源文件拷贝到镜像
COPY $SOURCES_LIST_PATH $APT_DIR
# 更换镜像源
RUN apt update && apt-get update
# 安装init软件包
RUN apt-get install init -y
# 安装ssh
RUN apt-get install -y openssh-server
RUN apt-get clean all
# 暴露端口
EXPOSE 22
接着通过docker build
命令构建镜像:
docker build -f ./Dockerfile . -t linner/debian
然后使用以下命令运行容器:
docker run -ti \
--name my-debian \
--privileged=true \
-e SOURCES_LIST_PATH=/etc/apt/sources.list \ # 把本地上使用的镜像源配置拷贝到容器中
linner/debian \
/sbin/init # 启动时运行init
评论