# Docker镜像制作

制作镜像有两种方式，通过修改现有容器，将之手动构建为镜像，通过Dockerfile文件，批量构建为镜像。

**docker commit**

```bash
#拉取基础镜像
docker pull centos:centos7
 
#运行并安装内容
docker run -it centos:centos7 bash
 
#提交为镜像
docker commit -a "centos7 system" -m "install nmap" 容器ID giao/centos7-pte:v1
 
#从制作的镜像中启动容器
docker run -it --name centos-pte giao/centos7-pte:v1 bash
```

**Dockerfile**

**Dockerfile文件格式**

* &#x20;指令不区分大小写，但惯例使用大写；
* &#x20;\#作为注释；
* &#x20;一行只支持一条指令，每条指令可以携带多个参数；
* &#x20;指令按照文件顺序从上至下执行；

**FROM**

* &#x20;指定基础镜像

```bash
FROM ubuntu
```

**LABEL**

* &#x20;指定镜像元数据

```bash
LABEL version="1.0"
```

**RUN**

* &#x20;执行shell命令
* &#x20;每一个RUN指令都会建立一个镜像层，所以尽可能合并成一条。

```bash
RUN echo 'test' > /var/www/html/index.html
 
RUN ["bin/bash","-c","test"]
 
RUN yum -y install epel-release \
&& yum -y install vim \
&& yum -y install nmap
```

**ENV**

* &#x20;设置环境变量
* &#x20;定义的环境变量会被持续的指令（ADD,COPY,RUN）进行引用。

```bash
ENV FIleName="/etc/shadow" VERSION=1.0
RUN cat $FileName
```

**COPY**

* &#x20;复制文本
* &#x20;必需是Dockerfile所在目录的相对路径
* &#x20;如果是目录，自身不会被复制

```bash
COPY home* /dockerdir/
```

**ADD**

* &#x20;复制和解包文件

```bash
ADD web.tar.gz /var/www/html/
```

**CMD**

* &#x20;容器启动命令
* &#x20;只能有一个CMD用来指定启动容器时默认执行的一个命令
* &#x20;每个Dockerfile只能有一条CMD命令，如果有多条会执行最后一条
* &#x20;如果启动时指定命令，将会覆盖CMD指定命令

```bash
CMD ["nginx","-g","daemon off;"]
 
CMD /bin/httpd -f -h ${ROOT}
```

**VOLUME**

* &#x20;匿名卷
* &#x20;用于存放数据库和需要保持的数据
* &#x20;VOLUME实现是匿名数据卷，无法指定宿主机路径和容器目录挂载关系

```bash
#宿主机目录为
/var/lib/docker/volumes/<volume_id>/_data
 
#创建两个挂载点
VOLUME ["/data1","/data2"]
```

**EXPOSE**

* &#x20;暴露端口
* &#x20;即声明容器打算使用什么端口，不会自动端口映射,需要配合docker run -P

```bash
EXPOSE 80 443
EXPOSE 11211/udp 11211/tcp
```

**WORKDIR**

* &#x20;指定工作目录

```bash
WORKDIR /app
```

**USER**

* &#x20;指定当前用户
* &#x20;须事先建立好，否则无法执行

```bash
RUN groupadd -r mysql && useradd -r -g mysql mysql
USER mysql
docker build
docker build .
docker build -f /path/Dockerfile .
docker build -t centos7-base:v1 .
```
