后端系统会部署很多服务,包括我们自己开发的服务,还有 mysql、redis 等中间件的服务,部署它们需要一系列依赖的安装、环境变量的设置等等。

如果你要部署多台机器的话,同样的操作要重复多次,万一哪一步漏掉了,服务就跑不起来了。

就很麻烦。

而 Docker 就能完美解决这个问题:

它把系统的所有文件封装成一个镜像,镜像跑起来作为容器,它可以在一台机器上跑多个容器,每个容器都有独立的操作系统环境,比如文件系统、网络端口等,在容器内跑各种服务。

这样整个环境都保存在这个镜像里,部署多个实例只要通过这个镜像跑多个容器就行。

这也是为什么它的 logo 是这样的:

Docker 提供了 Docker Hub 镜像仓库,可以把本地镜像 push 到仓库或者从仓库 pull 镜像到本地。

我们 pull 个镜像下来试试看:

首先需要安装 Docker,直接从官网下载 docker desktop 就行:

它内置了 docker 命令。

把它安装到系统之后,可以在命令行看下 docker 命令是否可用:

如果不可用,那要设置下这个:

点击 Settings > Advanced,里面有两种安装路径,如果是 /user/local/bin,那 docker 命令就是直接可用的,因为这个路径在 PATH 变量里。

如果是第二种,那就需要手动把 $HOME/.docker/bin 加到 PATH 环境变量里。

然后我们来看看 docker desktop 的界面:

images 是本地的所有镜像,containers 是镜像跑起来的容器。

docker desktop 可以可视化的管理它们,很方便。

我们 pull 一个镜像试试看。

搜索 nginx 镜像,点击 pull(搜索这步需要科学上网,不然搜不到)。

pull 下来之后,就可以在本地 images 看到了:

点击 run 会让你填一些参数:

首先是名字,如果不填,docker desktop 会给你生成随机的容器名字。

就是这种:

然后是端口,容器内跑的 nginx 服务是在 80 端口,你要把宿主机的某个端口映射到容器的 80 端口才可以访问。

接下来是数据卷 volume,这个是把宿主机某个目录挂到容器内。

因为容器是镜像跑起来的,下次再用这个镜像跑的还是同样的容器,那你在容器内保存的数据就会消失。

所以我们都是把某个宿主机目录,挂载到容器内的某个保存数据的目录,这样数据是保存在宿主机的,下次再用镜像跑一个新容器,只要把这个目录挂载上去就行。

至于环境变量,这个就很容易理解了。

我们分别设置一下:

挂载本地的 /tmp/aaa 到容器内的 /user/share/nginx/html 目录。

点击 run:

可以看到容器内的 nginx 服务跑起来了。

我们在 /tmp/aaa 目录下添加一个 index.html:

浏览器访问 http://localhost 就可以访问到:

这就说明数据卷挂载成功了。

点击 files 标签就可以看到容器内的文件。

可以看到 /usr/share/nginx/html 被标识为 mounted,就是挂载目录的意思:

我们再在本地添加一个文件:

你会发现容器内这个目录内容也变了:

这就是 volume 挂载的作用。

如果你挂载某些目录报错,是因为 docker desktop 挂载的目录是需要配置的,在 Settings > Resources > File Sharing 里加一下就行:

至于挂载到的目录,在镜像搜索结果页有写:

通过命令行  docker run 来跑镜像, -v 是指定挂载的数据卷,后面的 :ro 代表 readonly,也就是容器内这个目录只读,:rw 表示容器内可以读写这个目录。

这就是数据卷的作用。

此外,你还可以进入到容器内执行各种命令:

是不是感觉 docker 学起来还挺简单的?

docker 常用的就是这些东西。

当然,在服务器上没有 Docker Desktop 这种东西,还是要敲命令的。

比如我们点击 pull 按钮,就相当于执行了 docker pull:

docker pull nginx:latest

latest 是标签,也就是这个:

然后我们点击 run 按钮,填了个表单,就相当于执行了 docker run:

docker run --name nginx-test2 -p 80:80 -v /tmp/aaa:/usr/share/nginx/html -e KEY1=VALUE1 -d nginx:latest

-p 是端口映射

-v 是指定数据卷挂载目录

-e 是指定环境变量

-d 是后台运行

对照下前面可视化界面,是不是瞬间就懂了:

docker run 会返回一个容器的 hash:

就是这里的 id:

这个界面可以用 docker ps 来获取:

它是显示容器列表的,默认是运行中的。

想显示全部的,可以加个 -a

除了 container 列表,image 镜像列表也可以通过 docker images 命令获取:

我们在容器的 terminal 里执行命令,对应的是  docker exec 命令:

-i 是 terminal 交互的方式运行

-t 是 tty 终端类型

然后指定容器 id 和 shell 类型,就可以交互的方式在容器内执行命令了。

查看日志,对应 docker logs 命令:

输入 exit 退出:

docker inspect 可以查看容器的详情

对应 desktop 里的 inspect 的 tab:

docker volume 可以管理数据卷:

对应 desktop 的这部分:

此外,还有这些常用命令:

  • docker start:启动一个已经停止的容器

  • docker rm:删除一个容器

  • docker stop:停止一个容器

都可以通过 docker desktop 很方便的操作。

那如果我们要自己制作一个这样的镜像,怎么做呢?

docker 容器内就是一个独立的系统环境,想想如果在这样一个系统上,要安装 nginx 服务,怎么做呢?

需要执行一些命令、复制一些文件进来,然后启动服务。

制作镜像自然也要进行这样的过程,不过可以自动化。

只要在 dockerfile 里声明要做哪些事情,docker build 的时候就会根据这个 dockerfile 来自动化构建出一个镜像来。

比如这样:

FROM node:latestWORKDIR /appCOPY . .RUN npm install -g http-serverEXPOSE 8080CMD ["http-server", "-p", "8080"]

这些指令的含义如下:

  • FROM:基于一个基础镜像来修改

  • WORKDIR:指定当前工作目录

  • COPY:把容器外的内容复制到容器内

  • EXPOSE:声明当前容器要访问的网络端口,比如这里起服务会用到 8080

  • RUN:在容器内执行命令

  • CMD:容器启动的时候执行的命令

我们先通过 FROM 继承了 node 基础镜像,里面就有 npm、node 这些命令了。

通过 WORKDIR 指定当前目录。

然后通过 COPY 把 Dockerfile 同级目录下的内容复制到容器内,这里的 . 也就是 /app 目录

之后通过 RUN 执行 npm install,全局安装 http-server

通过 EXPOSE 指定要暴露的端口

CMD 指定容器跑起来之后执行的命令,这里就是执行 http-server 把服务跑起来。

把这个文件保存为 Dockerfile,然后在同级添加一个 index.html

然后通过 docker build 就可以根据这个 dockerfile 来生成镜像。

docker build -t aaa:ccc .

aaa 是镜像名,ccc 是镜像的标签

FROM 是继承一个基础镜像,看输出也可以看出来,前面都是 node 镜像的内容,会一层层下载下来。

最后才是本地的我们添加的那些。

这时你在 desktop 的 images 列表里就可以看到这个镜像了:

然后执行 docker run 把这个镜像跑起来,用 desktop 我们就直接点击 run 按钮了:

会让你输入这些内容:

是不是前面用 nginx 镜像的感觉回来了?这次是我们自己 build 的镜像。

指定容器名、映射的端口、点击 run:

然后可以看到容器内的日志,服务启动成功了:

当然,容器内打印的是 8080 端口,但在容器外要用映射的 8888 端口访问:

访问 http://localhost:8888 就可以看到我们在 html 写的内容了:

在容器内页打印了一条访问日志:

至此,我们写的第一个 dockerfile 和 build 出的第一个镜像就跑成功了!

我们在 files 里看看 /app 下是啥内容:

双击 index.html,可以看到这就是我们 build 镜像的时候 COPY 进去的文件。

但是我们想修改静态文件怎么办呢?

进入容器内改太麻烦,不如把这个 /app 目录设置为挂载点吧。

这样改下 Dockerfile:

然后重新 build 出一个镜像来:

docker build -t aaa:ddd -f 2.Dockerfile

因为现在不是默认的 Dockerfile 了,需要用 -f 指定下 dockefile 的文件名。

构建完之后再 run 一下这个新镜像:

这次把桌面目录作为数据卷挂载到 /app 目录了:

容器跑起来后可以看到确实挂载上去了,也标识为了 mount:

浏览器访问下:

在 inspect 这里也可以看到挂载的目录:

有同学说,就算不在 dockerfile 里指定 VOLUME,还是可以 docker run 的时候通过 -v 挂载数据卷呀。

那为啥还要指定 VOLUME?

在 dockerfile 里指定 VOLUME 之后,如果你 docker run 的时候没有带 -v,那会放在一个临时的目录里。

比如直接点击 run,不设置参数:

docker 会随机给他生成一个名字。

还会随机生成一个目录作为数据卷挂载上去:

inspect 可以看到这时候的路径是一个临时的目录:

这样就算你删了容器,数据也可以在这里找回。

设想下,如果你跑了个 mysql 容器,存了很多数据,但是跑容器的时候没指定数据卷。有一天,你把容器删了,所有数据都没了,可不可怕?

为了避免这种情况,mysql 的 dockerfile 里是必须声明 volume 的,这样就算你没通过 -v 指定数据卷,将来也可以找回数据。

在镜像详情可以看到 mysql 的 dockerfile,确实声明了 volume

这样就能保证数据不丢失。

总结

Docker 可以把环境封装成镜像,镜像跑起来是一个独立的容器。通过这种方式可以快速部署多个相同的实例。

docker 提供了一个 desktop 工具,可以可视化的操作 docker,包括容器、镜像、volume 等

我们 pull 了一个 nginx 镜像下来,指定端口映射、挂载的数据卷,并把它跑起来了。

这就是 docker 的基本用法。

当然,这些可视化的操作都有对应的命令,当服务器上没有桌面的时候,就需要用命令行操作了。

docker 镜像是通过 dockerfile 构建出来的。

我们写了第一个 dockerfile,通过 FROM、WORKDIR、COPY、RUN、EXPOSE、CMD 等指令声明了一个 http-server 提供静态服务的镜像。

docker run 这个镜像就可以生成容器,指定映射的端口、挂载的数据卷、环境变量等。

VOLUME 指令看起来没啥用,但能保证你容器内某个目录下的数据一定会被持久化,能保证没挂载数据卷的时候,数据不丢失。

写完这个 dockerfile,相信你会对 docker 镜像、容器有更具体的理解了。

不得不说,用 desktop 来学 docker 真是太简单了。

通过 Desktop 学 Docker 也太简单了相关推荐

  1. 看我在项目里怎么用设计模式,这么学设计模式也太简单了!

    V-xin:ruyuanhadeng获得600+页原创精品文章汇总PDF 目录 一次请求执行流程 java 代码是如何运行的? 堆内存满了后怎么办? 用单例模式如何优化系统性能呢? 大家好,今天给大家 ...

  2. python做客户端适合吗_太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端...

    原标题:太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端 作者:Adil Moujahid 编译:kou.Eli 本文转自区块链大本营(ID:blockchai_camp),转载需授权 区 ...

  3. 开发小程序,05 后程序员直呼“太简单”?

    作者 | 伍杏玲 出品 | CSDN(ID:CSDNnews) 在今年 Stack Overflow 的开发者调查报告里,我们发现一项有趣的数据:调查的 9 万名开发者中,70.8% 的开发者早在 1 ...

  4. 跟风学Docker之四:Docker网络解决方案

    2019独角兽企业重金招聘Python工程师标准>>> 跟风学Docker之四:Docker网络解决方案 博客分类: docker 前言:前面的部分一直都是单机跑docker,但实际 ...

  5. python大游戏_玩游戏就能学Python?太炫酷了!

    原标题:玩游戏就能学Python?太炫酷了! 要说现在最火的语言,那一定是Python了. 各种排行榜里,Python的排名都是蹭蹭蹭地往上涨.Python也确实是最适合新手入门的语言了,语法简单,应 ...

  6. 其实英语实在太简单了

    先别急,这是真的,今天没什么时间就简单说说.. 首先我的英语水平:讲纯正美语,看英文原著,看英文原声电影不需要字幕...告诉大家我的一些心得.. 因为英语和汉语太大不同,让很多人看着一个个字母太有距离 ...

  7. 【云原生 | 从零开始学Docker】一、Docker的安装,启动以及工作原理

    [从零开始学Docker]安装篇 一丶Docker浅谈 1.1Docker为什么出现 1.2Docker能干吗 二.Docker的安装 2.1 Docker的组成 2.2 安装前提 2.3 安装步骤 ...

  8. 用Python爬取手机壁纸,太简单了吧

    用Python爬取手机壁纸,太简单了吧! 人生苦短,快学Python! 在Python爬虫的学习过程中,爬取图片几乎是每个初学者都练习过的项目,比如我们之前就分享过:如何用Python快速爬取小姐姐的 ...

  9. 3d建模一般学多久?太长的话,我就不玩了。

    一 3d建模一般学多久?太长的话,我就不玩了. 3d建模学多久这个问题不是很好回答,鬼才知道你的实力怎么样,努力的态度怎么样,如果你三天打鱼两天晒网,我估计一万年也学不会.如果你全力以赴认真的学,五六 ...

最新文章

  1. extern quot;Cquot; 的含义:实现C++与C及其他语言的混合编程
  2. Java监听器用法(三):外部类监听器
  3. 关于排序速度效率数组集合选择那点事
  4. 列表初始化和赋值初始化的使用注意事项
  5. javaone_JavaOne 2012覆盖率
  6. 传统反病毒软件厂商学会新把戏
  7. 腾讯优图提出LCVR-MQVI算法,勇夺NTIRE 2021双赛道冠亚军
  8. Unity 用mono打开脚本时修改其显示分格,可VS风格等显示
  9. Cisco 证书查询
  10. 数据结构c语言版第二版(严蔚敏)第一章笔记
  11. DllRegisterServer调用失败的解决办法
  12. office2019选框虚线_手把手教你分析PS2019里怎么画虚线
  13. Python编程——实现屏幕广告语的滚动
  14. 如何用C++写一个简单的小游戏?
  15. vue---向后台校验用户名/手机号码/邮箱等唯一性的参数是否被注册
  16. iVMS-4200 Vs区别_55436红单足球预测 法甲 21:00 安格斯 VS 梅斯
  17. 如何使用工厂模式让自己的代码更加优雅
  18. 计算机基础知识(下)(操作系统简介)
  19. 5.4 文本分析与加密
  20. 【C语言】极坐标转换为直角坐标

热门文章

  1. 使用AlexNet网络区分宝可梦和数码宝贝
  2. 美团笔试——小美的划分蛋糕
  3. 讨论面向对象及方法学的特点?为什么要用面向对象方法开发软件?
  4. 主键的概念作用及特点
  5. 配置OpenGL(Linux)
  6. 解锁新技能《docker如何搭建Redis哨兵模式》
  7. ApexSql Log 数据库操作的后悔药
  8. 微慕插件二开wordpress微信小程序源码下载 星尘UI v1.3.1
  9. Python中的安全密码处理,非常重要!知道这些hei客也奈何不了你
  10. Android Webview 漏洞复现