# 镜像

## 理解
1. Docker把应用程序及其依赖，打包在 image 文件里面。

## 基本操作
```
# 列出本机的所有 image 文件。
$ docker image ls

# 删除 image 文件
$ docker image rm [imageName]

# 获取镜像
$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

# 将v2镜像变成最新镜像
$ docker tag -f image:v2 image:latest 
```

## commit构建镜像

#### 语法
$ docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

#### 例子
```
$ docker commit \
    --author "BING <zhubing@mail.com>" \
    --message "初始化" \
    webserver \
    nginx:v2
sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214
```

#### 缺点
1. 如果是安装软件包、编译构建，那会有大量的无关内容被添加进来，将会导致镜像极为臃肿。
2. docker commit 意味着所有对镜像的操作都是黑箱操作，生成的镜像也被称为黑箱镜像，换句话说，就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像，别人根本无从得知。 

## 使用 Dockerfile 定制镜像

#### 定义
Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像，之后使用docker build命令基于Dockerfile中的指令来构建一个新的镜像。 Dockerfile是Docker构建镜像的基础，也是Docker区别于其他容器的重要特征，正是有了Dockerfile，Docker的自动化和可移植性才成为可能。


#### Dockerfile语法：
链接：https://yeasy.gitbooks.io/docker_practice/content/image/dockerfile/

#### 加快构建的技巧

https://www.cnblogs.com/stulzq/p/9339250.html

ADD sources.list /etc/apt/sources.list.d/sources.list

#### 示例
```
# 用Python runtime作为一个父image
FROM python:2.7-slim
# 设置工作目录 /app
WORKDIR /app
# 只有在build镜像的时候运行一次，后面运行Container的时候不会再重新加载了。
ADD . /app
# 镜像操作指令
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 定义容器端口
EXPOSE 80
# 定义环境变量
ENV NAME World
# 执行
CMD ["python", "app.py"]
```

#### 构建镜像

一、创建镜像
1. 使用当前目录的Dockerfile创建镜像。
docker build -t runoob/ubuntu:v1 .  (-t: tag)
2. 使用URL github.com/creack/docker-firefox 的 Dockerfile 创建镜像。
docker build github.com/creack/docker-firefox
3. 其他
* [更多语法](https://docs.docker.com/engine/reference/commandline/build/#options)
* 第一次构建会比较慢

二、标记镜像
docker tag SOURCE_IMAGE[:TAG] url/project/IMAGE[:TAG]

三、推送镜像到仓库
docker push url/project/IMAGE[:TAG]





## 参考资料
* [Docker的学习（二）----构建镜像](https://www.jianshu.com/p/8b0b973ab0fe)
* [Dockerfile指令详解](http://seanlook.com/2014/11/17/dockerfile-introduction/)
