使用 Docker 来构建一个 Tomcat 服务
Docker 作为一种轻量级的虚拟机技术,目前已经得到了广泛的应用。Docker 能够把你从繁琐的项目配置中拯救出来,并且提高项目的统一性,开发人员在开发好了项目之后,完全可以把项目打包成为一个 Docker 镜像,然后把其交给运维即可。
1. 安装 Docker
如果你是在 Ubuntu 上(需要 64 位操作系统),只需要一行命令就可以搞定
sudo apt-get install docker.io
此时可以运行以下命令来查看 Docker 的相关信息
docker info
在其它的操作系统上安装 Docker 可以参考官方文档。
2. 理解容器
容器就是我们在 Docker 中运行服务的地方,一个宿主机上可以运行着多个容器,他们可以分别包含着不同的服务。
例如,我们现在运行着三个容器,分别运行了 MySQL、Tomcat 和 Nginx(不同的服务其实是可以运行在同一个容器中的,但是我们一般还是建议不同的服务应该运行在不同的容器中)这三个服务,那么我们就好像拥有了三台不同的物理机一样,这三台机器是相互独立的,你可以把其想象成三台运行着服务的真正的机器。Docker 提供了三台机器间互相通信的方式,但在这里我们不会做过多的涉及,因为这一次我们只会构建一个容器。
想要查看当前主机上运行着的容器,可以使用命令
docker ps
想要查看当前主机上所有(包括已停止)的容器,使用命令
docker ps -a
目前我们还启动任何容器,所以列表为空。
3. 理解镜像
上面已经讲到了容器的概念,镜像其实就是由容器生成的一种只读的文件。
打个比方,小 A 自己花了三个小时,手动构建了一个容器,小 A 感到很高兴。此时小 A 的同事小 B 也想要用小 A 的这个容器,该怎么办呢?此时小 A 可以通过以下命令把他自己构建的容器打包成为一个镜像
docker commit -m "Build a image" <容器ID> <镜像名称>
-m 就是构建镜像的时候提交的相关信息,这里的-m是可选项。容器 ID 就是容器的唯一的标识,在显示容器列表的时候可以查看到,而镜像名称就是你想给自己镜像所取的名字,这里镜像名字也是有一套规则的,但是本着简单起见,本文不做涉及,读者有兴趣可自行查阅。
Docker 提供了以下几种方式来获得/创建一个镜像:
- 直接从外部仓库中 pull 别人已经做好的镜像;
- 自己手动的构建好一个容器,然后然后把其 commit 为一个镜像(就是上面提到的那种方式);
- 通过 Dockerfile 来以文本的方式记录下你创建一个容器的过程,别人可以直接用这个文件来生成对应的镜像;
关于 docker-compose.yml,其作用就是对多个 Dockerfile 进行处理,即处理包含有多个镜像的过程;
其中方式 1 和方式 3 使用的较多,如果想要获取一个别人已经制作好的镜像,可选择方式 1,如果想要自定义一个镜像,一般选择方式 3。
4. 从外部仓库获取一个镜像
上面介绍了一点容器和镜像的基础知识,想必你已经能够大概的明白容器和镜像的概念了,下面我就来获取我们的第一个镜像,这里我们就以 Tomcat 镜像为例。执行以下命令
docker pull hub.c.163.com/public/tomcat:7.0.28
- 关于中央仓库: Docker 中的中央仓库就是存放了大量的 Docker 镜像的地方,如果你用过 Maven 或者 Python 的 pip 命令,那么你对这种概念一定不会陌生,全球最大的中央仓库是 Docker 官方的docker hub。不过在这里我使用的是网易蜂巢的 Docker 镜像服务,其服务器在国内,速度也会更快一点。
上面的命令会执行一系列的下载操作,执行完毕之后,如果不出错,那么你已经获取到了一个 Tomcat 的镜像。此时执行命令
sudo docker images
将会列出所有的镜像列表,我的镜像列表如下所示
可以看到,这是一个从 163 仓库下载下来的镜像,并且他的名字是十分有规律的。至此,我们已经成功得从远程仓库获取了一个 Tomcat 镜像,下面我会讲如何启动这个镜像使其成为一个容器并运行。
关于 Dockerfile
Dockerfile 也是一种创建镜像的及其常用并且也是非常重要的方式,有些时候可能会是唯一的方式(比如在使用 Daocloud 服务的时候)。
我们可以手动书写一个 Dockerfile 文件,然后
- 通过 EXPOSE 来开放镜像端口;
- 通过 COPY 来复制宿主机文件到镜像中的指定位置;
- 其他的一些命令;
- 最后,根据 Dockerfile 文件创建一个名为image-name的镜像:
docker build -t image-name .
。
关于 Dockerfile 的内容也非常多,在这里我们不会更多的涉及,有兴趣的读者可自行查阅相关资料学习。
5. 通过镜像来启动一个容器
通过上面的步骤,我们已经成功的拥有了一个 Tomcat 的镜像,接下来,是时候把他启动起来了。执行命令
docker run --name tomcat -d -p 80:8080 8e17306cf050
run
表示要通过一个镜像启动一个容器;--name tomcat
是给这个启动的容器起了个名字,名字是 tomcat。如果不加此项,Docker 会自动给这个容器起一个名字;-d
表示此容器会以守护进程(daemon)的方式来执行。如果想要以命令行的方式来执行,可以使用-it
选项,并且需要在最后加上bash命令,即:
docker run –name tomcat -it -p 80:8080 8e17306cf050 bash
事实上,更加一般的做法是先以守护进程的方式启动容器,之后通过命令
docker exec -it 8e17306cf050 bash
来进入容器的bash,我比较推荐使用第二种做法注;
-p 80:8080
表示把当前宿主机的 80 端口映射到容器的 8080 端口;8e17306cf050
就是上面的 Tomcat 镜像的 ID,通过docker images
可以查看到,表示我们想要启动的容器是对应于这个镜像的。
启动完毕后,在浏览器中打开http://127.0.0.1/
,应该能够看到如下内容,表示容器已成功启动,并且对应的 Tomcat 服务已经在正常运行。
之后,执行以下命令显示所有正在运行的容器
docker ps
我们可以查看到正在运行的名称叫做 tomcat 的容器,并且可以查看到它的容器 ID。
为了后面的操作能够顺利进行,我们需要先执行 docker stop <容器ID>
和 docker rm <容器ID>
来停止并删除这个容器。
如上图所示,在这里我们只能显示 Tomcat 的初始网页,怎么样才能让容器运行我们自己所写的代码呢?观察之前在浏览器中所所打开的页面,其中有一行
This is the default Tomcat home page. It can be found on the local filesystem at: /var/lib/tomcat7/webapps/ROOT/index.html
也就是说 /var/lib/tomcat7/webapps/ROOT/
就是项目的根目录,我们只需要把自己的 Java 项目放到这个文件夹下就能执行我们自己的代码了。那么要怎么做?执行命令
docker run --name tomcat -d -p 80:8080 -v /home/derobukal/Desktop/html:/var/lib/tomcat7/webapps/ROOT/ 8e17306cf050
这条启动容器的命令和上面的相比多了个 -v /home/derobukal/Desktop/html:/var/lib/tomcat7/webapps/ROOT/
,表示把当前文件夹的 /home/derobukal/Desktop/html
目录(必须是绝对路径)挂载到 /var/lib/tomcat7/webapps/ROOT/
上,此时对文件夹 html
的操作就相当于在操作容器中 tomcat 下的 ROOT 文件夹。我们在 html
文件夹下新建一个文件,命名为index.html
,在之中输入hello, world
,然后刷新浏览器页面,显示结果如下
至此我们已经可以成功的部署 Tomcat 应用了。
如果你需要重启 Tomcat,可以执行命令
docker restart <容器ID>
可以通过以下命令来删除一个 Docker 镜像
docker rmi <镜像ID>
总结:
在 Docker 中需要清晰的区分镜像和容器的概念,并且要明白他们所对应的操作有什么不同。如果能理解了他们之中的差异,那么也就能够快速的理解 Docker 的相关操作了。
本文只是对 Docker 进行了一个简单的介绍,想要了解更多关于 Docker 的内容,读者可以参阅 Docker 技术入门与实战 一书,这里介绍了关于 Docker 的大量细节,如果你想要更加深入的了解 Docker,那么你一定不能错过这本书籍。