Docker 的三个基本概念,镜像、容器、仓库
镜像:相当于一个操作系统,可以通过 Dockerfile 自行定制
容器:由镜像生成的一个实例
仓库:保存镜像,类似 github 管理代码,Docker 也有一个 DockerHub
安装
MacOS Docker 安装
手动下载
https://docs.docker.com/desktop/mac/install/
启动终端后,通过命令可以检查安装后的 Docker 版本
$ docker --version
查看各个命令或参数介绍
$ docker --help
镜像
查看本地已经下载的镜像列表
$ docker image ls
列表包含了 仓库名
、标签
、镜像 ID
、创建时间
以及 所占用的空间
如果列表很多的话,可以通过增加参数进行筛选
根据仓库名列出镜像
$ docker image ls ubuntu
列出特定的某个镜像,也就是说指定仓库名和标签
$ docker image ls ubuntu:18.04
除此之外还可以通过 –filter 参数或 -f,进行筛选
删除本地镜像
$ docker rmi -f imageID
到 docker 上查找镜像,例如 centos 镜像,可以根据需要找到不同版本的 centos
https://hub.docker.com/_/centos?tab=tags
制作镜像
一、使用 commit 构建镜像
先开启一个容器
$ docker run --name webserver -d -p 80:80 nginx
然后根据需求修改内容,例如下面我将 webserver 容器
$ docker exec -it webserver bash
root@3729b97e8226:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
root@3729b97e8226:/# exit
exit
我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 docker diff
命令看到具体的改动。
当我们运行一个容器的时候,我们做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个 docker commit
命令,可以将容器的存储层保存下来成为镜像。就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
docker commit
的语法格式为:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
将容器保存为镜像:
$ docker commit \
--author "Ryan Zheng <zhengjianhong95@gmail.com>" \
--message "修改了默认网页" \
webserver \
nginx:v2
接下来就可以使用 docker image ls 看到新定制的镜像
查看镜像内的历史记录
$ docker history nginx:v2
二、使用 Dockerfile 定制镜像
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
新建一个文本文件,名称为 Dockerfile,内容如下
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
FROM 指定基础镜像
RUN 执行命令行命令
构建镜像
在 Dockerfile
文件所在目录执行
$ docker build -t nginx:v3 .
命令的格式为 docker build [选项] <上下文路径/URL/->
在这里我们指定了最终镜像的名称 -t nginx:v3
,构建成功后,我们可以像之前运行 nginx:v2
那样来运行这个镜像,其结果会和 nginx:v2
一样。
容器
查看所有容器
$ docker ps -a
查看容器的信息
$ docker inspect ContainerID
查看正在运行中的容器
$ docker container ls
删除容器
$ docker rm -vf ContainerID
开启容器
$ docker start ContainerID
停止容器
$ docker stop ContainerID
重启容器
$ docker restart ContainerID
运行容器
$ docker run --name webserver -d -p 8080:80 nginx
–name 指定容器的名称为 webserver
-p 8080:80 表示将本地的 8080 端口映射到容器的 80 端口,此时访问本机的 8080 端口即可访问容器内 NGINX 默认页面。
-d 容器在后台运行,并输出容器ID
nginx 表示使用 nginx 镜像
进入容器
$ docker exec -it ContainerID bash
持久化存储
在容器中管理数据主要有两种方式:
- 数据卷(Volumes)
- 挂载主机目录 (Bind mounts)
一、数据卷(Volumes)是一个可供一个或多个容器使用的特殊目录,可以在容器之间共享和重用,而且修改后立即生效,对数据卷的修改不会影响到镜像,数据卷默认一直存在,即使容器被删除
创建数据卷 ryan_vol
$ docker volume create ryan_vol
查看所有数据卷
$ docker volume ls
查看指定数据卷信息
$ docker volume inspect ryan_vol
删除数据卷
$ docker volume rm ryan_vol
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷
。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v
这个命令。
无主的数据卷可能会占据很多空间,要清理请使用以下命令
$ docker volume prune
启动一个挂载数据卷的容器
$ docker run -d -P --name web --mount source=ryan_vol,target=/usr/share/nginx/html nginx:alpine
二、挂载目录作为数据卷
$ docker run -d -P --name web --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html nginx:alpine
上面的命令加载本机的 /src/webapp
目录到容器的 /usr/share/nginx/html
目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,以前使用 -v
参数时如果本地目录不存在 Docker 会自动为你创建一个文件夹,现在使用 --mount
参数时如果本地目录不存在,Docker 会报错。
仓库
仓库(Repository
)是集中存放镜像的地方,目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 2,650,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
登陆/退出 DockerHub
$ docker login
$ docker logout
查找官方仓库中的镜像
$ docker search centos
在查找的时候通过 --filter=stars=N
参数可以指定仅显示收藏数量为 N
以上的镜像。
下载镜像到本地
$ docker pull centos
docker 对免费用户有拉取镜像的限制,具体解决方法可以参考文章
https://www.chenshaowen.com/blog/how-to-cross-the-limit-of-dockerhub.html
将镜像推送到 DockerHub
$ docker push username/ubuntu:18.04
查看 DockerHub 账号下的公开镜像
$ docker search username
有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用
其他
一、官方的 nginx 镜像使用的 Linux 版本为 Debian,而且默认没有安装 vim 等常用工具,如果要使用这些工具的话,得手动安装,相关命令如下:
// 查看当前系统版本
cat /etc/issue
// 安装 systemctl、vim 等工具
apt-get update
apt-get upgrade -y
apt-get -y install vim
apt-get -y install systemctl
二、容器内访问宿主机网络
使用宿主机 IP、使用 host.docker.internal
这个特殊的DNS名称来解析宿主机IP
常见报错
mac 下安装完成后发现在终端执行docker命令报错 command not found
找到 docker 的安装路径,然后添加到 .zshrc 里面,最后执行下 source ~/.zshrc
export PATH=”$PATH:/Applications/Docker.app/Contents/Resources/bin”