上一篇:docker 入门-容器(二)
之前也说过镜像是可以从 Docker Hub 上的仓库下载的,在 Docker Hub 上的仓库有用户仓库和顶层仓库,顶层仓库是官方的,我们个人也可以上传自己的镜像到用户仓库,和 GitHub 一样
如果想对镜像有一个较简洁的全面了解,可以看看第一篇文章:Docker 入门(一)
sudo docker images
本地镜像存于/var/lib/docker,容器也在该目录下的containers中
sudo docker pull 镜像名
这样拉取的是最新的镜像,可以用 tag 指定下载的版本
sudo docker pull 镜像名:tag
sudo docker run 镜像:tag
更多有关容器的操作请见文章:xxx
sudo docker push 仓库名/镜像名
sudo docker rmi 镜像名
sudo docker search 镜像名
# 或添加-s选项筛选星级:
sudo docker search -s 2 镜像名
构建镜像一般都是基于已有镜像构建新镜像,当然,也有从 0 开始构建的,我们暂且不讨论从 0 开始的
这个很简单的,就是对一个容器执行 commit 命令就可以了
sudo docker commit 容器名或ID 仓库名/镜像名
当然也可以在 commit 时指定更多的描述:
选项 | 全称 | 意思 | 例子 |
---|---|---|---|
-a | --author | 作者 | --author="xxx" |
-m | --message | 描述信息 | --message="xxxx" |
-p | --pause | 提交时是否暂停容器的运行 | --pause=true |
例子:
sudo docker commit -m="描述" -a="me" 容器名 仓库名/镜像名:tag
先创建一个目录,然后在目录里创建一个文件 Dockerfile:
mkdir project
cd project
touch Dockerfile
这里的 project 目录就是我们的构建环境或称构建上下文。
然后开始编写 Dockerfile,下面是一个例子:
vim Dockerfile
# version:0.0.1
FROM ubuntu:14.04
MAINTAINER 作者 "邮箱"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'hi' > /usr/share/nginx/html/index.html
EXPOSE 80
解释: 一般开头都是这四行,说明一下镜像版本、作者信息和基于什么镜像开始构建,其余的都是一行一行的指令,每个指令都是要大写,后面一定要有参数选项。指令从上往下执行,每个指令都会创建一个新的镜像层并提交,下一条指令会基于上一条指令创建的镜像层创建新的镜像层。
最后,在这个构建环境下 build:
sudo docker build -t="仓库名/镜像名" .
注意末尾的点:.
,表示 docker 要在本地目录找 Dockerfile ,当然也可以指定搜索目录,比如指定 GitHub 上的一个 Dockerfile 文件目录。
其实,我们在 Dockerfile 中编写的命令建议采用数组结构组织命令和参数选项,比如
CMD ["/bin/bash", "-l"]
,意思就是把-l
传给/bin/bash
官方文档:https://docs.docker.com/engine/reference/builder/
指令 | 解释 | 特别的 |
---|---|---|
RUN | 指定镜像被构建时要执行的指令,默认使用 shell 里面的命令包装器 /bin/sh -c 来执行 | |
CMD | 指定容器启动时要执行的命令,比如sudo docker run -it 镜像名 /bin/true翻译为 CMD 指令为:CMD ["/bin/true"] | 只能用一条,多条则只执行最后一条,会被 docker run 覆盖 |
ENTRYPOINT | 和CMD类似,但 Dockerfile 中的 CMD 命令在和 docker run 冲突时会被覆盖,而 ENTRYPOINT 则不会,而且还可以接受所有 docker run 传入的参数,比如sudo docker run 镜像名 -g "daemon off;"则是把-g "daemon off;"参数传给了该镜像的 Dockerfile 中的 ENTRYPOINT 指令。 | 我们可以结合 ENTRYPOINT 和 CMD 的特性,做出有默认选项的命令,具体怎么玩,自己想想 |
WORKDIR | 指定该镜像创建的容器的工作目录,ENTRYPOINT 和 CMD 等指令会在这个目录下执行,也可以为 Dockerfile 中不同指令指定不同的工作目录 | 举个例子吧:WORKDIR /opt/webapp/db,RUN bundle install,WORKDIR /opt/webapp,ENTRYPOINT ["rackup"]。当然,在运行时也可以添加-w标志覆盖工作目录sudo docker run -it -w /var/log ubuntu pwd |
ENV | 设置环境变量供后续的 RUN 指令使用,比如ENV RVM_PATH /home/rvm后再执行:RUN gem install unicorn就相当于:RVM_PATH=/home/rvm/ gem install unicorn。 | |
USER | 指定该镜像会以什么样的用户去运行,比如USER nginx是以 nginx 用户的身份来运行,我们也可以指定用户名或 UID 和 组或 GID。 | 默认用户是 root |
VOLUME | 给该镜像创建的容器添加卷。更多有关卷的内容,请见最后的拓展补充部分。 | |
ADD | 将构建环境下的文件和目录复制到镜像中。比如在安装一个应用程序时,需要制定源文件和目的文件的位置:ADD software.lic /opt/application/software.lic。以是否有/判断指定的是目录还是文件。 | 1、不能对构建环境之外的文件或目录进行 ADD 操作。2、会自动将压缩文件解压缩 |
COPY | 和 ADD 类似,但不会解压缩归档文件 | |
ONBUILD | 为镜像添加触发器。当镜像被用作其他镜像的基础镜像时,该镜像的触发器被执行。触发器是在构建过程中插入新指令,我们可以认为是在 FROM 指令之后执行,触发器可以使任何构建指令。例子:ONBUILD ADD . /app/src,ONBUILD RUN cd /app/src && make | 我们可以对镜像使用 docker inspect 查看 ONBUILD 的内容。只被执行一次,而不会被孙子镜像再次执行。FROM和MATINTAINER和ONBUILD本身不能在ONBUILD中出现,即防止递归执行。 |
其实就是一种共享的挂载点。
卷是存在于一个或多个容器内的共享数据目录。对卷的修改是立即生效的,但对卷的修改并不会对镜像产生影响,因为卷的存在是为了把一些内容如数据、源代码、数据库等添加到容器中,而不是镜像中。卷会一直存在直到没有容器在使用它。
sudo docker run -d -p 80 --name 容器名 仓库名/镜像名 nginx -g "daemon off;"
解释: -p 80
的意思是 docker 的宿主机随机找一个端口号映射到容器的 80 端口,我们也可以指定内外端口的具体映射关系:-p 80:80
,也可以指定 IP 地址:-p 127.0.0.1:80:80
。而如果采用大写的-P
,意思即是容器直接对外公开在 Dockerfile 中 EXPOSE 设置的所有端口。
通过绑定 Docker Hub 和 GitHub 账号,使得在 GitHub 上存在 Dockerfile 的仓库链接到 Docker Hub 从而在每次代码更新时由 Docker Hub 自动构建的方式。
但设置了自动构建的镜像就不能通过 docker push 来更新了,要通过 GitHub 来更新。