Docker FAQ 
                                                    
                        
                    
                    
  
                    
                    - 
Dockerfile 中 COPY指令和ADD指令有什么区别简单来说,最主要的区别是 ADD功能更为强大一些:- ADD允许- <src>是一个 URL
- 如果 ADD的<src>参数是可以识别的压缩格式存档文件,则对其进行解压如果 ADD 带一个 URL 是 xxx.tar.gz 的文件的话,是不会对其进行解压的 
 「书写 Dockerfiles 的最佳实践」推荐使用 COPY指令而不是使用ADD指令.
- 
Dockerfile 中 CMD指令和ENTRYPOINT指令有什么区别Docker 有一个默认的「入口点」 /bin/sh -c,但没有一个默认的命令.这里论述,感觉不对,主要看 Dockerfile 中的 CMD和ENTRYPOINT是基于 exec 还是 shell 模式
 若是 shell 模式则是利用 /bin/sh -c 调起命令执行的,exec 模式则是直接执行命令当你这样运行 docker的时候:docker run -i -t ubuntu bash,「入口点」就是默认的/bin/sh -c,镜像是ubuntu,命令是bash.
 该命令是通过「入口点」运行的,实际上执行的是/bin/sh -c bash. 这允许 Docker 依靠shell的解析器快速实现RUN.
 后来,用户要求能够自定义它,因此引入了ENTRYPOINT和--entrypoint.在上面的示例中, ubuntu之后的内容都是命令并且传递给了「入口点」.
 当使用CMD指令的时候,实际上就跟docker run -i -t ubuntu <cmd>一样,<cmd>就是「入口点」的参数.
 你仍然会在容器中启动一个 bash shell 是因为ubuntu的Dockerfile指定了一个默认的CMD:CMD ["bash"]因为所有内容都会传递到「入口点」,所以你可以从「镜像」获取到非常好的行为. 
 例如,把「镜像」用作「二进制」命令.
 当把["/bin/cat"]作为「入口点」并执行docker run img /etc/passwd的时候,你将会得到,
 由于/etc/passwd是命令并传递给「入口点」,因此最终执行的只是/bin/cat /etc/passwd.另外一个例子是将任何 cli作为「入口点」.
 假设有一个redis镜像,不用运行docker run redisimg redis -H something -u toto get key,而是简单定义ENTRYPOINT ["reids", "-H", "something", "-u", "toto"],然后运行类似这样的命令将会得到相同的结果:docker run redisimg get key.
- 
从主机复制文件到 Docker 容器 cp命令能够用来复制文件. 可以复制一个特定的文件,如docker cp foo.txt mycontainer:/foo.txt docker cp mycontainer:/foo.txt foo.txt特别强调, mycontainer是「容器」ID 而不是「镜像」ID.文件夹 src包含多个文件可以使用以下方法复制到target文件夹中docker cp src/. mycontainer:/target docker cp mycontainer:/src/. target小于 Docker 1.8 的版本,只能将文件从容器复制到主机,而不能从主机复制到容器. 
- 
如何移除旧的 Docker 容器 使用 docker container prune.也可以使用 docker system prune, 将会在一个命令中移除「容器」(containers),「镜像」(images),「卷」(volumes)以及「网络」(networks).
- 
如何从主机获取 Docker 容器的 IP 地址 inspect的--format选项可以获取到.
 现代 Docker 客户端语法docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id古代 Docker 客户端语法 docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id若是 windows 系统,则需要双引号(“)而不是单引号(‘) 
- 
在不使用仓库的情况下,如何将 Docker 镜像从一台主机复制到另一台 首先,把镜像保存为一个 tar文件.docker save -o < path for generated tar file > < image name >然后使用常规文件传输工具(如 cp或scp)将镜像复制到系统.
 之后再将镜像导入到 Docker 中.docker load -i < path to image tar file >
- 
如何处理 Docker 中的持久存储(例如:数据库) 使用 volume API docker volume create --name hello docker run -d -v hello:/container/path/for/volume container_image my_command这意味着必须放弃仅数据容器模式以支持新卷. 实际上 volume API只是实现数据容器模式的更好的方法.如果使用 -v volume_name:/container/fs/path创建容器,Docker 将自动为你创建一个命名卷,它可以- 通过 docker volume ls列出来
- 通过 docker volume inspect volume_name识别
- 备份为普通目录
- 像以前一样通过 --volumes-from连接备份
 新的 volume API增加了一个有用的命令,能够让你识别出悬空的卷docker volume ls -f dangling=true然后可以通过卷名移除 docker volume rm < volume name >可以只通过一条命令移除所有悬空的卷 docker volume rm $(docker volume ls -f dangling=true -q) # Or using 1.13.x docker volume prune
- 通过 
- 
如何在 Docker 中列出容器 只显示正在运行的「容器」 docker ps显示所有的「容器」 docker ps -a显示最新创建的「容器」(包括所有状态) docker ps -l显示 N 个最新创建的「容器」(包括所有状态) docker ps -n=-1显示总的文件大小 docker ps -s在新版本的 Docker, 命令有更新,新增了一些管理命令 列出正在运行的「容器」 docker container ls列出所有的容器(不管状态) docker container ls -a
- 
如何删除 Docker 中的镜像 使用 docker rmi node列出所有创建的「容器」 docker ps -a移除所有现有的「容器」(不是「镜像」),执行 docker rm $(docker ps -aq)
- 
如何进入 Docker 容器的 shell 使用 docker exec, 例如docker exec -it < mycontainer > bash
- 
Docker 镜像存储在主机那个位置 /var/lib/docker目录的内容主要依赖于 driver Docker is using for storage默认是 aufs,但也可以为overlay,overlay2,btrfs,devicemapper或者zfs,主要是取决于你的「内核」支持.
 大多数情况下都会是aufs,但是RedHats的是devicemapper.可以使用 -s或者--storage-dirver=选项为Docker daemon手动设置存储的驱动.- /var/lib/docker/{dirver-name}包含了指定存储驱动的镜像内容
- /var/lib/docker/graph/{id}仅包含镜像的元数据,存储在- json和- layersize文件
 若是 aufs- /var/lib/docker/aufs/diff/{id}包含了镜像文件内容
- /var/lib/docker/repositories-aufs是一个- JSON文件,包含了本地镜像信息. 可以使用- docker images命令查看
 若是 devicemapper- /var/lib/docker/devicemapper/devicemapper/data存储了镜像
- /var/lib/docker/devicemapper/devicemapper/metadata存储了元数据- 这些文件是精简配置的’稀疏‘文件,因此不像它们看起来那么大 
 
- 
Docker 容器和镜像的区别 「镜像」的运行实例被称作「容器」. 一个「镜像」,实质是一组 layer层的描述. 当你启动此「镜像」,则会有一个运行此「镜像」的「容器」. 可以创建许多同一个「镜像」的运行「容器」.docker images可以查看所有的「镜像」, 而docker ps可以查看所有运行中的「容器」,docker ps -a查看所有的「容器」.因此,「镜像」的运行实例就是「容器」. 
- 
如何移除旧的不用的 Docker 镜像 docker system prune会删除所有的悬空数据(例如:停止运行的「容器」,没有「容器」的「卷」,没有「容器」的「镜像」),甚至不使用的数据,使用-a选项.还可以使用: - docker container prune
- docker image prune
- docker network prune
- docker volume prune
 对于不使用的「镜像」,使用 docker image prune -a(删除悬空和不使用的「镜像」).不使用的「镜像」是指未被任何「容器」引用 把 --filter选项与docker xxx prune组合使用,是一种限制prune的好方法.
- 
如何将环境变量传递给 Docker 容器 使用 -e选项.sudo docker run -d -t -i -e REDIS_NAMESPACE='staging' \ -e POSTGRES_ENV_POSTGRES_PASSWORD='foo' \ -e POSTGRES_ENV_POSTGRES_USER='bar' \ -e POSTGRES_ENV_DB_NAME='mysite_staging' \ -e POSTGRES_PORT_5432_TCP_ADDR='docker-db-1.hidden.us-east-1.rds.amazonaws.com' \ -e SITE_URL='staging.mysite.com' \ -p 80:80 \ --link redis:redis \ --name container_name dockerhub_id/image_name或者,不想在 ps命令行看到这样赋值的参数,则可以这样sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]如果有很多环境变量特别是它们出于安全考虑不能暴露的话,可以使用 env-file.$ docker run --env-file ./env.list ubuntu bashenv.list文件每一行要符合VAR=VAL这样的格式
- 
强制 Docker 不使用缓存构建镜像 使用 --no-cache选项.docker build --no-cache -t u12_core .
- 
Docker 如何修改仓库名或者镜像名 docker tag server:latest myname/server:latest或者 docker tag d583c3ac45fd myname/server:latest如果不要旧的名字,在重新标记之后可以移除它 docker rmi server这仅仅移除 alias/tag. 因为d583c3ac45fd有其他名字,真实的「镜像」不会被移除.
- 
在 Docker 中 expose 和 publish 有什么不同 expose是一种文档化的方式,与Dockerfile相关.expose 只是定义了那些端口被使用,是一种文档化定义,实际上不进行端口映射或打开端口的操作 --publish(-p) 是一种将主机端口映射到正在运行的容器端口的方法,与docker run相关.-p 会告诉容器在网络接口打开那些端口 
- 
如何 attach 和 detach Docker 进程 使用 CTRL-cdetach「容器」,会导致 Docker 「容器」退出.使用 --sig-proxy选项,可以避免「容器」退出.docker attach --sig-proxy=false 304f5db405ec使用 CTRL-p CTRL-q也可以detach而「容器」不退出, 不过只有在「容器」是使用-t和-i选项启动的时候,才会生效.$ docker run -i -t -d nginx af203c3e997b94c7a519463c26c9290c777942556be4682738a8892af1f7062b $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af203c3e997b nginx "nginx -g 'daemon of…" 3 seconds ago Up 2 seconds 80/tcp keen_lumiere $ docker attach keen_lumiere read escape sequence # 这里使用 CTRL-p CTRL-q detach 「容器」 $ docker ps # 「容器」没有退出 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af203c3e997b nginx "nginx -g 'daemon of…" 20 seconds ago Up 19 seconds 80/tcp keen_lumiere也可以自定义 detach键:--detach-keys
 详情参考:set your own detach sequence
- 
Docker daemon 日志的位置 这主要取决于你的系统,以下是几个位置以及包含几个操作系统的命令. - Ubuntu(使用 upstart) -/var/log/upstart/docker.log
- Ubuntu(使用 systemd) -journalctl -fu docker.service
- Amazon Linux AMI - /var/log/docker
- Boot2Docker - /var/log/docker.log
- Debian GNU/Linux - /var/log/daemon.log
- CentOS - /var/log/daemon.log | grep docker
- CoreOS - journalctl -u docker.service
- Fedora - journalctl -u docker.service
- Red Hat Enterprise Linux Server - /var/log/messages | grep docker
- OpenSuSE - journalctl -u docker.service
 
- Ubuntu(使用 
- 
Dockerfile 中如何更新 PATH 环境变量 ENV PATH="/opt/gtk/bin:${PATH}"
- 
如何检查 docker build失败的文件系统Docker每次从Dockerfile成功执行一个RUN指令,都会提交一个新的layer层到「镜像」文件系统.
 你可以方便地使用这些layer层 ID 作为一个「镜像」启动一个新的「容器」.使用这样的 DockerfileFROM busybox RUN echo 'foo' > /tmp/foo.txt RUN echo 'bar' >> /tmp/foo.txt构建一个「镜像」 $ docker build -t so-2622957 . Sending build context to Docker daemon 47.62 kB Step 1/3 : FROM busybox ---> 00f017a8c2a6 Step 2/3 : RUN echo 'foo' > /tmp/foo.txt ---> Running in 4dbd01ebf27f ---> 044e1532c690 Removing intermediate container 4dbd01ebf27f Step 3/3 : RUN echo 'bar' >> /tmp/foo.txt ---> Running in 74d81cb9d2b1 ---> 5bd8172529c1 Removing intermediate container 74d81cb9d2b1 Successfully built 5bd8172529c1你可以使用 00f017a8c2a6,044e1532c690和5bd8172529c1启动一个新的「容器」.$ docker run --rm 00f017a8c2a6 cat /tmp/foo.txt cat: /tmp/foo.txt: No such file or directory $ docker run --rm 044e1532c690 cat /tmp/foo.txt foo $ docker run --rm 5bd8172529c1 cat /tmp/foo.txt foo bar当 Dockerfile中的一个指令执行失败时,你需要做的是查找上一个layer层的 ID, 并在从该 ID 创建的「容器」中运行shelldocker run --rm -it <id_last_working_layer> bash -il一旦进入到「容器」 - 尝试失败的命令,重现该问题
- 然后修复该命令并测试它
- 最后使用修复之后的命令更新你的 Dockerfile
 若是想直接在失败的 layer层排查问题而不是在最后一个工作的layer层,则可以:
 首先,找到失败的「容器」$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6934ada98de6 42e0228751b3 "/bin/sh -c './utils/" 24 minutes ago Exited (1) About a minute ago sleepy_bell然后,把它提交到一个「镜像」 $ docker commit 6934ada98de6 sha256:7015687976a478e0e94b60fa496d319cdf4ec847bcd612aecf869a72336e6b83之后,运行这个「镜像」 $ docker run -it 7015687976a4 [bash -il]这样,就处于构建失败时的状态了. 
说明
文章主要是参考了 StackOverflow  docker 标签的问题列表
本作品采用《CC 协议》,转载必须注明作者和本文链接
 
           Codcodog 的个人博客
 Codcodog 的个人博客
         
             
                     
                     
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: