Docker 入门
基础
不同操作系统下其安装包、运行环境是都不相同的!如果是手动安装,必须手动解决安装包不同、环境不同的、配置不同的问题
而使用Docker,这些完全不用考虑。就是因为Docker会自动搜索并下载MySQL。注意:这里下载的不是安装包,而是**镜像(image)
。镜像中不仅包含了MySQL本身,还包含了其运行所需要的环境、配置、系统级函数库。因此它在运行时就有自己独立的环境,就可以跨系统运行,也不需要手动再次配置环境了。这套独立运行的隔离环境我们称为容器(container)
**
💡 Docker安装软件的过程,就是自动搜索下载镜像,然后创建并运行容器的过程
Docker本身包含一个后台服务
,我们可以利用Docker命令告诉Docker服务,帮助我们快速部署指定的应用。Docker服务部署应用时,首先要去搜索并下载应用对应的镜像,然后根据镜像创建并允许容器,应用就部署完成
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
解读:
docker run -d
:创建并运行一个容器,d
则是让容器以后台进程运行-name mysql
: 给容器起个名字叫mysql
,你可以叫别的p 3306:3306
: 设置端口映射。- 容器是隔离环境,外界不可访问。但是可以将宿主机端口映射容器内到端口,当访问宿主机指定端口时,就是在访问容器内的端口了。
- 容器内端口往往是由容器内的进程决定,例如MySQL进程默认端口是3306,因此容器内端口一定是3306;而宿主机端口则可以任意指定,一般与容器内保持一致。
- 格式:
p 宿主机端口:容器内端口
,示例中就是将宿主机的3306映射到容器内的3306端口
e TZ=Asia/Shanghai
: 配置容器内进程运行时的一些参数- 格式:
e KEY=VALUE
,KEY和VALUE都由容器内进程决定 - 案例中,
TZ=Asia/Shanghai
是设置时区;MYSQL_ROOT_PASSWORD=123
是设置MySQL默认密码
- 格式:
mysql
: 设置镜像名称,Docker会根据这个名字搜索并下载镜像- 格式:
REPOSITORY:TAG
,例如mysql:8.0
,其中REPOSITORY
可以理解为镜像名,TAG
是版本号 - 在未指定
TAG
的情况下,默认是最新版本,也就是mysql:latest
- 格式:
Docker 常见命令
命令 | 说明 | 文档地址 |
---|---|---|
docker pull | 拉取镜像 | https://docs.docker.com/engine/reference/commandline/pull/ |
docker push | 推送镜像到DockerRegistry | https://docs.docker.com/engine/reference/commandline/push/ |
docker images | 查看本地镜像 | https://docs.docker.com/engine/reference/commandline/images/ |
docker rmi | 删除本地镜像 | https://docs.docker.com/engine/reference/commandline/rmi/ |
docker run | 创建并运行容器(不能重复创建) | https://docs.docker.com/engine/reference/commandline/run/ |
docker stop | 停止指定容器 | https://docs.docker.com/engine/reference/commandline/stop/ |
docker start | 启动指定容器 | https://docs.docker.com/engine/reference/commandline/start/ |
docker restart | 重新启动容器 | https://docs.docker.com/engine/reference/commandline/restart/ |
docker rm | 删除指定容器 | https://docs.docker.com/engine/reference/commandline/rm/ |
docker ps | 查看容器 | https://docs.docker.com/engine/reference/commandline/ps/ |
docker logs | 查看容器运行日志 | https://docs.docker.com/engine/reference/commandline/logs/ |
docker exec | 进入容器 | https://docs.docker.com/engine/reference/commandline/exec/ |
docker save | 保存镜像到本地压缩文件 | https://docs.docker.com/engine/reference/commandline/save/ |
docker load | 加载本地压缩文件到镜像 | https://docs.docker.com/engine/reference/commandline/load/ |
docker inspect | 查看容器详细信息 | https://docs.docker.com/engine/reference/commandline/inspect/ |
💡 docker run 相当于 docker create 和 docker start,启动镜像时不要使用 docker run
以Nginx
为例演示上述命令
# 第1步,去DockerHub查看nginx镜像仓库及相关信息
# 第2步,拉取Nginx镜像
docker pull nginx
# 第3步,查看镜像
docker images
# 结果如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB
# 第4步,创建并允许Nginx容器
docker run -d --name nginx -p 80:80 nginx
# 第5步,查看运行中容器
docker ps
# 也可以加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第6步,访问网页,地址:http://虚拟机地址
# 第7步,停止容器
docker stop nginx
# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第9步,再次启动nginx容器
docker start nginx
# 第10步,再次查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第11步,查看容器详细信息
docker inspect nginx
# 第12步,进入容器,查看容器内目录
docker exec -it nginx bash
# 或者,可以进入MySQL
docker exec -it mysql mysql -uroot -p
# 第13步,删除容器
docker rm nginx
# 发现无法删除,因为容器运行中,强制删除容器
docker rm -f nginx
给常用Docker命令起别名,方便访问:
# 修改/root/.bashrc文件
vi /root/.bashrc
内容如下:
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
数据卷
容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁
在上图中:
- 我们创建了两个数据卷:
conf
、html
- Nginx容器内部的
conf
目录和html
目录分别与两个数据卷关联。 - 而数据卷conf和html分别指向了宿主机的
/var/lib/docker/volumes/conf/_data
目录和/var/lib/docker/volumes/html/_data
目录
这样以来,容器内的conf
和html
目录就 与宿主机的conf
和html
目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data
就是在操作容器内的/usr/share/nginx/html/_data
目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了
💡 /var/lib/docker/volumes
这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data
为什么不让容器目录直接指向宿主机目录呢?
- 因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了
- 但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可
- 一般数据卷目录比较深,不好寻找,通常让容器直接与宿主机
目录
挂载而不使用数据卷
数据卷的相关命令有:
命令 | 说明 | 文档地址 |
---|---|---|
docker volume create | 创建数据卷 | https://docs.docker.com/engine/reference/commandline/volume_create/ |
docker volume ls | 查看所有数据卷 | https://docs.docker.com/engine/reference/commandline/volume_ls/ |
docker volume rm | 删除指定数据卷 | https://docs.docker.com/engine/reference/commandline/volume_prune/ |
docker volume inspect | 查看某个数据卷的详情 | https://docs.docker.com/engine/reference/commandline/volume_inspect/ |
docker volume prune | 清除数据卷 | https://docs.docker.com/engine/reference/commandline/volume_prune/ |
容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建
数据卷的目录结构较深,如果操作数据卷目录会不太方便。在很多情况下,会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件
💡 本地目录或文件必须以 /
或 ./
开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
参考
黑马程序员Docker快速入门到项目部署,MySQL部署+Nginx部署+docker自定义镜像+DockerCompose项目实战