学习Docker的***办法就是迅速在工作中应用它,本文作者使用Docker部署了一个Java EE应用,非常简单和方便。需要注意的是,由于作者写作时本地网络有问题,所以Dockerfile中很多的资源都没有从网络下载,你再实践时,可以尝试修改。学习快乐 :)
本文中,我们将会把Java EE和Docker结合,具体内容如下:
- 创建、构建并运行一个Docker镜像;
- 通过镜像启动一个Wildfly服务器,并部署了一个JavaEE示例应用;
- 展示一些常用的Docker命令;
- 启动多个容器,并让同一应用运行于不同端口。
引言
在这里我不再介绍Docker,因为已经有太多的介绍性的文章。写本文之前,我阅读了如下教程:
- Docker用户指南;
- 使用Docker镜像;
- Docker***指南(译者注:已翻译);
- Arun Gupta的技术技巧:#39、#57、#61和#65。
前提条件
要完成本教程,你需要:
- 有一个运行于宿主机上的Docker后台进程
- 安装Docker后,在etc\default\docker文件中添加一行:DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock
- 此后重启机器并尝试运行这个命令:docker -H tcp://127.0.0.1:2375 –version,输出应该类似这样的:Docker version 1.4.1, build 5bc2ff8
- 一个Wildfly 8.2.0的安装程序(解压后的);
- jdk-8u25-linux-x64.tar.gz文件。(http://www.oracle.com/technetwork/java/javase/downloads/index.html)
- 下载 car-service.war。(https://github.com/rmpestano/javaee-docker-sample/blob/master/java_ee/car-service.war)
- 下载 Dockerfile。(https://github.com/rmpestano/javaee-docker-sample/blob/master/java_ee/Dockerfile)
创建Docker镜像
Docker镜像展现/描述了容器本身。由于我的网络带宽有限(手机3G),在这里我使用本机资源创建了一个镜像。因此,这个镜像只有在包含如下文件的目录下构建才能使用:
- wildfly-8.2.0.Final:应用服务器
- car-service.war:要部署的应用
- Dockerfile:描述容器的文件
- jdk-8u25-linux-x64.tar.gz:要在容器里安装的java版本
注意:不推荐在Docker容器中使用本地资源,因为只有当所有文件都存在时镜像才可以正常构建。***的办法是从头安装所有东西并下载必要的文件。
这是Dockerfile的内容:
- FROM ubuntu
- MAINTAINER Rafael Pestano <rmpestano@gmail.com>
- setup WildFly
- COPY wildfly-8.2.0.Final /opt/wildfly
- install example app on wildfy
- COPY car-service.war /opt/wildfly/standalone/deployments/
- setup Java
- RUN mkdir /opt/java
- COPY jdk-8u25-linux-x64.tar.gz /opt/java/
- change dir to Java installation dir
- WORKDIR /opt/java/
- RUN tar -zxf jdk-8u25-linux-x64.tar.gz
- setup environment variables
- RUN update-alternatives --install /usr/bin/javac javac /opt/java/jdk1.8.0_25/bin/javac 100
- RUN update-alternatives --install /usr/bin/java java /opt/java/jdk1.8.0_25/bin/java 100
- RUN update-alternatives --display java
- RUN java -version
- Expose the ports we're interested in
- EXPOSE 8080 9990
- Set the default command to run on boot
- This will boot WildFly in the standalone mode and bind to all interface
- CMD ["/opt/wildfly/bin/standalone.sh", "-c", "standalone-full.xml", "-b", "0.0.0.0"]
镜像继承自Ubuntu——一个安装了Ubuntu操作系统的镜像。Docker安装教程中就安装了Ubuntu镜像。
接着,我们将服务器复制到容器的/opt/wildfly目录。COPY是Dockerfile的一个指令。我们可以在这里找到所有命令。
我们随后将应用的war包复制到服务器中:
- COPY car-service.war /opt/wildfly/standalone/deployments/。
然后,我们将Java解压安装到容器的/opt/java目录并设置一些环境变量。***的办法是使用apt-get,不过这要求有互联网接入,而我写作时不具备这个条件。我使用RUN命令来执行java -version,(如果Java正确安装的话)它将在镜像构建时打印版本号。
之后,我使用EXPOSE 8080 9990来告诉Docker容器要暴露的端口号。容器其实是镜像的实例,运行镜像(docker run)时,我们可以指定允许宿主访问的端口。
***,我们指定了默认命令:CMD ["/opt/wildfly/bin/standalone.sh", "-c", "standalone-full.xml", "-b", "0.0.0.0"]。每次容器启动时都会运行这个命令。
构建镜像
在描述完镜像之后,我们需要构建它。在包含Dockerfile的父目录运行以下命令:
- docker -H tcp://127.0.0.1:2375 build -t javaee_sample java_ee/
- -H参数指定了Docker后台地址(使用TCP与后台通讯);
- build是命令本身;
- -t指定了用于识别镜像的标签名称(这里是javaee_sample);
- java_ee/是包含用于描述镜像的Dockerfile的目录。
上述命令的输出如下:
然后我们可以通过列出镜像命令(译者注:docker images命令)来确认刚创建的镜像:docker -H tcp://127.0.0.1:2375 images:
启动容器
使用这一命令启动容器:
- docker -H tcp://127.0.0.1:2375 run -p 8180:8080 javaee_sample
- -p指定容器端口到主机端口的映射;
- run是命令本身;
- javaee_sample是镜像名。
容器启动过程中会输出Wildfly启动日志,这是因为我们将其设置为初始命令(CMD Dockerfile命令):
运行多个容器
我们可以实例化多个容器,因为它们的端口在宿主上不会发生冲突。我将再启动两个容器并将8080端口分别暴露为8280和8380:
- docker -H tcp://127.0.0.1:2375 run -p 8280:8080 javaee_sample
- docker -H tcp://127.0.0.1:2375 run -p 8380:8080 javaee_sample
要列出启动的容器,我们可以使用命令:docker -H tcp://127.0.0.1:2375 ps,这是输出结果:
- rmpestano@rmpestano-ubuntu:~/docker /images$ docker -H tcp://127.0.0.1:2375 ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7b9079806e69 javaee_sample:latest "/opt/wildfly/bin/st 27 seconds ago Up 27 seconds 9990/tcp, 0.0.0.0:8280->8080/tcp suspicious_lovelace
- d4975e825751 javaee_sample:latest "/opt/wildfly/bin/st 28 seconds ago Up 28 seconds 9990/tcp, 0.0.0.0:8380->8080/tcp loving_hopper
- 96e58eb65126 javaee_sample:latest "/opt/wildfly/bin/st 42 seconds ago Up 42 seconds 9990/tcp, 0.0.0.0:8180->8080/tcp clever_cori
现在我们可以在浏览器中同时访问这三个应用:
你可以通过容器的ID或名字来停止容器:
- docker -H tcp://127.0.0.1:2375 stop suspicious_lovelace
记住,在容器删除时所有数据将消失。请使用Docker卷来持久化数据。