Docker 入门(二):从实例来看 Dockerfile 和 Compose
上一文中提到,每次对容器做了改动,如果不把它 commit 成新的镜像,在删除容器后,数据也会丢失,有没有什么更好的办法来保存数据呢?使用数据卷就可以解决这个问题。
另外,相对于用 commit 容器创建镜像,使用 Dockerfile 在创镜像的同时还可以包含很多命令进去,可以简化后续操作。
对于需要用到多个容器的应用,Docker 也提供了更强大的工具 Compose 来管理容器。
本文就将浅谈 Docker 的 数据管理、Dockerfile、Compose 这三个方面,同时用实例来演示,助你快速掌握 Docker 基本技能。
环境说明:上一篇文章我用的是 Ubuntu,这篇文章换 win 来玩玩。用的 shell 是 CMD(美化版)。
win 下,配置镜像加速也非常方便,只需要在如下位置填写阿里云的专属加速地址就可以了。
从 MySQL 实例来看数据管理
如果我们运行了一个 MySQL 容器,数据库等信息就是存放在容器内的,停止容器到还没事,一旦我们在删除容器之前忘了导出数据,那么所有的数据就会丢失。这是非常 不安全
的。
况且就算我们不会忘了在删除容器之前导出数据,如果要用到多个需要存储数据的容器,我们也要一个一个把数据导出来吗?这是非常 不方便
的。
而 Docker 就提供了一个独立于容器之外的存储技术 数据卷(Volume),数据卷的本质是一个文件目录
,它可以是本机的目录也可以是一个容器中的目录(如果把数据卷放在了一个单独的容器中,这个容器也被称为 数据卷容器)。
使用 数据卷 就可以将多个容器内的数据单独 持久化
在一个本机目录或者一个单独的容器中了。
例如下面这个例子:
$ docker run -d -p 3307:3306 --name sql -v E:/jpress/mysql:/var/lib/mysql -e MYSQL_DATABASE=jpress -e MYSQL_ROOT_PASSWORD=root mysql
-d
后台运行,-p
映射本机端口 3307 到容器内的 3306 ,--name
是指定容器的别名,-v local-dir:container-dir
将本地的目录作为数据卷挂载到容器内的目录进行数据持久化,-e
是 mysql 的参数,后面跟上 MySQL 的环境变量,/var/lib/mysql
是 MySQL 存储数据的目录。
-e MYSQL_DATABASE=
可以指定运行容器时创建一个数据库,-e MYSQL_ROOT_PASSWORD=
指定 MySQL 的密码,MySQL 用户名默认是 root。
上面的那条命令虽长,但主要的操作是数据持久化的那一步,下面我们来验证一下,数据究竟有没有被持久化:
$ docker pull mysql $ docker run -d -p 3307:3306 --name sql -v E:/jpress/mysql:/var/lib/mysql -e MYSQL_DATABASE=jpress -e MYSQL_ROOT_PASSWORD=root mysql $ docker stop sql $ docker rm sql $ docker run -d -p 3307:3306 --name sql -v E:/jpress/mysql:/var/lib/mysql mysql $ docker exec -it sql bash $ SHOW DATABASES;
有图有真相:
图中的文字已经足够说明做数据持久化的好处了。
Dockerfile
Dockerfile 是一个 配置文件
,里面可以放多条处理命令,一次配置好了可以简化后续的部分操作。需要注意的是,一个 Dockerfile 只能包含一个基础镜像
,就像函数一样,一个配置文件只干一件事。
一个 Dockerfile 里面一般有两类信息:
- 基础镜像和维护者的信息
- 多条操作镜像和容器的命令
下面通过创建自己的 Tomcat 镜像来演示 Dockerfile 的用法(Tocmcat 已包含 JDK):
vi Dockerfile
在 Dockerfile 中写入以下信息,#后面的是注释:
#基础镜像和维护者的信息 #使用一个 Tomcat 镜像作为基础镜像 From tomcat #注明创建者的信息,也可以不写 MAINTAINER stormxing <[email protected]> #多条操作镜像和容器的命令(这里举例一条) #复制 war 包到镜像内的 webapps 目录里 COPY jpress.war /usr/local/tomcat/webapps
这里用到的 war 包是一个开源的 Java 博客,官网是:
https://github.com/JpressProj...
war 包我已经打好了,下载地址是:
http://stormxing.oss-cn-beiji...
接下来用 Dockerfile 构建我们的镜像:
docker build -t myweb .
-t myweb
是为新的镜像起一个名字,.
表示 Dockerfile 的路径,由于是它在当前路径所以是 .
然后,运行镜像后访问localhost:8080/jpress
,就可以看到网页了。
$ docker run -d -p 8080:8080 myweb
点下一步之后按提示输入信息,还记得吗,上面我们已经搞定数据库了(没想到吧),这里直接填写信息既可以了,这个数据库主机并不是 localhost ,而是容器外的 ip,也就是我们的本机 ip,用 ipconfig
就能查到。
最后点下一步,按提示设置后台登陆的用户名和密码,输入localhost:8080/jpress/admin
就可以进入到后台管理页面。
至此,我们还 顺便 知道了如何用 Docker 搭建 JavaWeb 环境了。
多容器应用工具(Compose)
一个 Dockerfile 能包含一个基础镜像,而比较复杂的项目是要用多个容器部署的,一个一个创建还是有点麻烦的,而 Compose 就是一个管理多容器应用的工具。
Compose 安装
Docker-compose 只有在 Linux 上是需要单独下载的,Windows 和 Mac 自带。并且它是放在 GitHub 上面维护的,所以国内从 GitHub 上下载它速度非常慢,可以访问下面的地址从 daocloud 下载镜像。
https://get.daocloud.io/#inst...
执行以下两条命令即可完成安装。
$ curl -L https://get.daocloud.io/docker/compose/releases/download/1.20.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose $ chmod +x /usr/local/bin/docker-compose
安装完成后,可以用以下命令查看下版本信息。
$ docker-compose --version
从 jpress 来看 docker-compose
docker-compose 类似于 Dockerfile,也是一个配置文件,但不同的是,一个 Dockerfile 只能跑一个镜像,而 docker-compose 就能一次跑多个,而且还能配合 Dockerfile 来使用。
这里我们演示用 docker-compose 来跑 jpress。
- 编写配置文件(这个文件名同 Dockerfile 一样是约定好的)
vi docker-compose.yml
填写以下内容:
version: "3" services: mysql: image: mysql ports: - "3307:3306" volumes: - "E:/jpress/sql:/var/lib/mysql" container_name: sql environment: MYSQL_DATABASE: jpress MYSQL_ROOT_PASSWORD: root tomcat: build: . ports: - "8080:8080" container_name: web
注意缩进,tomcat 和 mysql 都是包含在 services 下面的。build: .
指调用之前写的 Dockerfile 来运行 Tomcat,MySQL 的数据卷注意要重新创建,否则会使用之前的数据,其他的在之前都见到过,看字段的名字就知道意思了。
我这个文件是新建在 Dockerfile 的同一个目录里的:
- 执行一下命令就能运行了,结果跟上面的构建方式是一样的
$ docker-compose up -d
- 如此看来用 docker-compose 果然简化了很多操作,只需要一次配置好,然后直接运行就可以了。
- 另外,如果要删除刚运行的两个容器,可以:
$ docker-compose stop $ docker-compose rm
总结
本文从数据持久化开始说起,浅谈了 Dockerfile 和 docker-compose 并附送
如何用这两种方式分别搭建 JavaWeb 环境,并在对比中展示了它们各自的特点。
最后结合 上篇文章 画张导图送给你,可不是用来收藏的哟:
本文用到的所有文件已整理到 GitHub: