一个简单的Java EE&Docker示例

【编者的话】学习Docker的最好办法就是迅速在工作中应用它,本文作者使用Docker部署了一个Java EE应用,非常简单和方便。需要注意的是,由于作者写作时本地网络有问题,所以Dockerfile中很多的资源都没有从网络下载,你再实践时,可以尝试修改。学习快乐 :) 本文中,我们将会把Java EE和Docker结合,具体内容如下:
    []创建、构建并运行一个Docker镜像;[/][]通过镜像启动一个Wildfly服务器,并部署了一个JavaEE示例应用;[/][]展示一些常用的Docker命令;[/][]启动多个容器,并让同一应用运行于不同端口。[/]
# 引言 在这里我不再介绍Docker,因为已经有太多的介绍性的文章。写本文之前,我阅读了如下教程:# 前提条件 要完成本教程,你需要:
    []有一个运行于宿主机上的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# 创建Docker镜像 Docker镜像展现/描述了容器本身。由于我的网络带宽有限(手机3G),在这里我使用本机资源创建了一个镜像。因此,这个镜像只有在包含如下文件的目录下构建才能使用:
1.png
    []wildfly-8.2.0.Final:应用服务器[/][]car-service.war:要部署的应用[/][]Dockerfile:描述容器的文件[/][]jdk-8u25-linux-x64.tar.gz:要在容器里安装的java版本[/]

注意:不推荐在Docker容器中使用本地资源,因为只有当所有文件都存在时镜像才可以正常构建。最好的办法是从头安装所有东西并下载必要的文件。

这是Dockerfile的内容:
FROM ubuntuMAINTAINER Rafael Pestano  # setup WildFlyCOPY wildfly-8.2.0.Final /opt/wildfly # install example app on wildfyCOPY 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 inEXPOSE 8080 9990 # Set the default command to run on boot# This will boot WildFly in the standalone mode and bind to all interfaceCMD ["/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命令。上述命令的输出如下:
2.png
然后我们可以通过列出镜像命令(译者注:docker images命令)来确认刚创建的镜像:`docker -H tcp://127.0.0.1:2375 images`:
3.png
# 启动容器 使用这一命令启动容器:
docker -H tcp://127.0.0.1:2375 run -p 8180:8080 javaee_sample
    []-p指定容器端口到主机端口的映射;[/][]run是命令本身;[/][]javaee_sample是镜像名。[/]
容器启动过程中会输出Wildfly启动日志,这是因为我们将其设置为初始命令(CMD Dockerfile命令):
4.png
# 运行多个容器 我们可以实例化多个容器,因为它们的端口在宿主上不会发生冲突。我将再启动两个容器并将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
现在我们可以在浏览器中同时访问这三个应用:
5.png
你可以通过容器的ID或名字来停止容器:
docker -H tcp://127.0.0.1:2375 stop suspicious_lovelace
记住,在容器删除时所有数据将消失。请使用Docker卷来持久化数据。 原文:A SIMPLE JAVA EE DOCKER EXAMPLE (翻译:梁晓勇 校对:李颖杰)

4 个评论

问一个问题,为什么tomcat不可以啊?
CMD ["/usr/tomcat/apache-tomcat-7.0.57/bin/startup.sh","-c"]
admln

admln 回复 admln

我明白了
OneAPM 可以智能探知 Java 应用之间的相互调用关系,通过串联复杂的后台组件,动态生成 J2EE 应用整体架构视图。在图中通过简单的点击钻取您可以逐级深入,查看对代码级别的诊断数据。快来官网注册试用吧~
您好,我是个新手,我按照您的例子走一边,老是出错:12:06:21,237 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-5) MSC000001: Failed to start service jboss.deployment.unit."car-service.war".STRUCTURE: org.jboss.msc.service.StartException in service jboss.deployment.unit."car-service.war".STRUCTURE: JBAS018733: Failed to process phase STRUCTURE of deployment "car-service.war"
能看到wildfly成启动,但是无法加载部署的应用

要回复文章请先登录注册