Docker 入门(二):从实例来看 Dockerfile 和 Compose

xnng

上一文中提到,每次对容器做了改动,如果不把它 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 <stormxing@foxmail.com>

#多条操作镜像和容器的命令(这里举例一条)

#复制 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:

https://github.com/stormxing/...

阅读 11.3k

xnng
分享一个程序员的日常
221 声望
5 粉丝
0 条评论
221 声望
5 粉丝
宣传栏