欢迎回来!
Docker ps
告诉我们正在运行的是什么:
$ docker ps
IMAGE STATUS PORTS NAMES
spring-boot-app:latest Up 2 minutes 0.0.0.0:8080->8080/tcp eloquent_varaham
该应用程序仍在运行。它在一个名为eloquent_varaham的容器中运行 。
我们使用容器名称来控制它。我们停下来是:
$ docker stop eloquent_varaham
eloquent_varaham
当你检查docker ps
时,它已经消失了:
$ docker ps
CONTAINER ID IMAGE COMMAND
如果您再次尝试打开索引页面,则会失败。
但容器仍在那里。让我们再来看看:
$ docker ps -a
IMAGE STATUS PORTS NAMES
spring-boot-app:latest Exited (143) 2 minutes ago eloquent_varaham
添加 -a
显示停止的容器。
我们可以重新启动现有容器而不是创建一个新容器:
$ docker restart eloquent_varaham
eloquent_varaham
$ docker ps -a
IMAGE STATUS PORTS NAMES
spring-boot-app:latest Up 22 seconds 0.0.0.0:8080->8080/tcp eloquent_varaham
容器再次运行,您可以打开访问Web应用程序。
但是你也可以停下来移除容器:
$ docker stop eloquent_varaham
eloquent_varaham
$ docker rm eloquent_varaham
eloquent_varaham
$ docker ps -a
CONTAINER ID IMAGE PORTS NAMES
Docker rm 删除容器,但必须先将其停止。
开始一个新容器。不是不同的端口映射参数:
$ docker run -d -p 8081:8080 spring-boot-app:latest
69e430267b4347a6d9cbfc5b7fcce368187622c219105e8f3634b9c8116bb20b
$ docker ps
IMAGE COMMAND PORTS NAMES
spring-boot-app:latest "/usr/bin/java -jar ..." 0.0.0.0:8080->8080/tcp sad_swartz
它在名为sad_swartz的容器中再次运行 。 将浏览器指向端口8081以加载页面。 您可以在命令行上将容器端口重新映射到不同的主机端口。
现在看一下容器日志:
$ docker logs sad_swartz
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.1.RELEASE)
2018-06-10 02:36:53.032 INFO 1 --- [ main] c.s.Application
: Starting Application
...
Docker logs 显示容器的输出。
您还可以将shell附加到我们的容器:
$ docker exec -it sad_swartz sh
/ # ps
PID USER TIME COMMAND
1 root 0:52 /usr/bin/java -jar -Dspring.profiles.active=default /app.war
46 root 0:00 sh
50 root 0:00 ps
/ # ls
app.war dev home media proc run srv tmp var
bin etc lib mnt root sbin sys usr
/ #
Docker的 exec 选项在容器内执行程序。 由于阿尔卑斯山图像极简主义,您需要使用 sh
。您只能执行图像中已有的命令。
该 -it
标记允许我们与外壳进行交互。
所有状态(包括文件系统)仅在容器的生命周期内存在。 当你 rm 的容器,你也破坏了状态。
如果要保留数据,则需要将其存储在容器外部。让我们通过将应用程序日志映射到主机系统上的目录来演示这一点。
首先,向应用程序添加一个logback配置:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>/var/log/Application/application.log</file>
<append>true</append>
<encoder>
<pattern>%-7d{yyyy-MM-dd HH:mm:ss:SSS} %m%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
然后修改您的Dockerfile以使用它:
FROM openjdk:8-jre-alpine
COPY spring-boot-app-0.0.1-SNAPSHOT.war /app.war
COPY logback.xml /logback.xml
CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default",
"-Dlogging.config=/logback.xml", "/app.war"]
您正在将logback.xml复制到映像中,并将日志记录配置添加到命令行。
日志记录配置将应用程序日志放在 / var / log / Application /中。
重建图像:
$ docker build -t spring-boot-app:latest .
Sending build context to Docker daemon 131.1MB
Step 1/4 : FROM openjdk:8-jre-alpine
---> c529fb7782f9
Step 2/4 : COPY target/spring-boot-app-0.0.1-SNAPSHOT.war /app.war
---> Using cache
---> d19bfa9fdfa7
Step 3/4 : COPY src/main/resources/logback.xml /logback.xml
---> Using cache
---> d62f97d9900d
Step 4/4 : CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default",
"-Dlogging.config=/logback.xml", "/app.war"]
---> Using cache
---> fb9139a8c8b8
Successfully built fb9139a8c8b8
Successfully tagged spring-boot-app:latest
Docker没有下载 openjdk:8-jre-alpine 图像,因为 docker
在本地缓存了它。
查看build命令。您可以使用-t
指定图像标记 。这是您传递给docker run
的标记 。最后提供工作目录。
现在,您需要在运行容器时将目录映射到主机上的目录:
$ docker run -d -v /var/log/app:/var/log/Application/
-p 8080:8080 spring-boot-app:latest
该 -v 选项将 我们的主机系统上的/ var / log / app映射到容器中的/ var / log / Application /。
运行此命令时,您可以看到在映射目录中创建的日志文件。
您一直在让docker为容器指定名称。你可以用-name以下方式覆盖 :
$ docker run -d --name bootapp -v /var/log/app:/var/log/Application/
-p 8080:8080 spring-boot-app:latest
57eb3f1998f503dc146d1f3b7ab9a6b221a939537be17ffc40fd410e2b72eda3
$ docker ps
IMAGE STATUS PORTS NAMES
spring-boot-app:latest Up 2 seconds 0.0.0.0:8080->8080/tcp bootapp
当您查看图像的历史记录时,您看到了将jre添加到Alpine的命令。 您也可以在你的Dockerfile中添加程序包到Alpine,让我们添加bash
到容器中。
首先,将APK
命令添加到我们的Dockerfile:
# Alpine Linux with OpenJDK JRE
FROM openjdk:8-jre-alpine
RUN apk add --no-cache bash
# Copy WAR
COPY spring-boot-app-0.0.1-SNAPSHOT.war /app.war
# copy fat WAR
COPY logback.xml /logback.xml
# runs application
CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default",
"-Dlogging.config=/logback.xml", "/app.war"]
然后使用与以前相同的指令构建映像:
$ docker build -t spring-boot-app:latest .
Sending build context to Docker daemon 40MB
Step 1/5 : FROM openjdk:8-jre-alpine
---> c529fb7782f9
Step 2/5 : RUN apk add --no-cache bash
---> Using cache
---> 3b0c475c9bd0
Step 3/5 : COPY spring-boot-ops.war /app.war
---> c03bd6c6ace5
Step 4/5 : COPY logback.xml /logback.xml
---> b2f899ebec17
Step 5/5 : CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default",
"-Dlogging.config=/logback.xml", "/app.war"]
---> Running in 3df30746d7a8
Removing intermediate container 3df30746d7a8
---> cbbfb596a092
Successfully built cbbfb596a092
Successfully tagged spring-boot-app:latest
这次输出略有不同。您可以 在第二步中看到bash
的安装位置。
最后,在运行容器之后,您可以使用bash
命令进行shell:
$ docker exec -it bootapp bash
bash-4.4# ls
app.war etc logback.xml proc sbin tmp
bin home media root srv usr
dev lib mnt run sys var
bash-4.4#
到目前为止,您一直在运行Spring Boot应用程序,并将活动配置文件设置为默认值。您可能希望构建具有不同配置文件的单个jar,然后在运行时选择正确的jar。让我们修改我们的图像以接受活动配置文件作为命令行参数。
首先,在 运行Web应用程序的docker
目录中创建一个shell脚本 :
#!/bin/sh
java -Dspring.profiles.active=$1 -Dlogging.config=/logback.xml -jar /app.war
此脚本接受单个参数,并将其用作活动概要文件的名称。
然后,修改您的 Dockerfile 以使用此脚本来运行该应用程序:
# Alpine Linux with OpenJDK JRE
FROM openjdk:8-jre-alpine
RUN apk add --no-cache bash
# copy fat WAR
COPY spring-boot-app-1.0.0-SNAPSHOT.war /app.war
# copy fat WAR
COPY logback.xml /logback.xml
COPY run.sh /run.sh
ENTRYPOINT ["/run.sh"]
Dockerfile提供了两种启动容器的机制:ENTRYPOINT 和CMD。 简单地说, ENTRYPOINT
就是为启动容器而执行的程序,是 CMD
传递给该程序的参数。
默认ENTRYPOINT
是/bin/sh -c
。 到目前为止,您将Java命令数组传递给shell。
现在,dockerfile正在将脚本复制到图像,然后定义为图像的ENTRYPOINT
。 这里没有CMD
。
构建此映像,然后在命令行上使用dev
将其作为最终参数运行 :
$ docker run -d --name bootapp -v /var/log/app:/var/log/Application/
-p 8080:8080 spring-boot-app:latest dev
然后查看活动配置文件的日志:
$ grep profiles /var/log/webapp/application.log
2018-06-11 00:33:50:016 The following profiles are active: dev
您可以看到配置文件设置已传递到JVM。
我们只在您的开发系统上使用过该图像。最终,您需要将其分发到客户端或生产系统。这是通过注册表完成的,其中图像使用名称和标记进行推送,然后,在作为容器运行时被拉出 。在docker
为您提取 hello-world图像时,您在本教程开始时看到了这一点 。
第一步是在Docker Cloud上创建一个帐户 。如果您还没有帐户,请在那里创建帐户。
接下来,登录我们开发系统上的Docker注册表:
$ docker login
Username: baeldung
Password:
Login Succeeded
接下来,标记图像。标签的格式是 username/repository:tag
。标签和存储库名称实际上是自由形式的。
标记图像,然后在系统上列出图像以查看标记:
$ docker tag spring-boot-app baeldung/spring-boot-app:.0.0.1
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot-app latest f20d5002c78e 24 minutes ago 132MB
baeldung/spring-boot-app 1.00 f20d5002c78e 24 minutes ago 132MB
openjdk 8-jre-alpine c529fb7782f9 4 days ago 82MB
请注意,新图像标记和原始图像具有相同的图像ID和大小。 标签不会创建新的图像副本。他们是指针。
现在您可以将图像推送到Docker Hub:
$ docker push baeldung/spring-boot-app:.0.0.1
The push refers to repository [docker.io/baeldung/spring-boot-app]
8bfb0f145ab3: Pushed
2e0170d39ba4: Pushed
789b0cedce1e: Pushed
f58f29c8ecaa: Pushed
cabb207275ad: Mounted from library/openjdk
a8cc3712c14a: Mounted from library/openjdk
cd7100a72410: Mounted from library/openjdk
1.00: digest: sha256:4c00fe46080f1e94d6de90717f1086f03cea06f7984cb8d6ea5dbc525e3ecf27 size: 1784
docker push
接受标记名称并将其推送到默认存储库,即Docker Hub。
现在,如果您访问hub.docker.com上的帐户区域,则可以看到新的存储库,图像和标记。
现在,您可以将图像拉下来并在任何系统上运行它:
$ docker run -d --name bootapp -v /var/log/app:/var/log/Application/
-p 8080:8080 ericgoebelbecker/spring-boot-app:.0.0.1 dev
Unable to find image 'baeldung/spring-boot-ops:1.00' locally
1.00: Pulling from baeldung/spring-boot-ops
b0568b191983: Pull complete
55a7da9473ae: Pull complete
422d2e7f1272: Pull complete
3292695f8261: Pull complete
Digest: sha256:4c00fe46080f1e94d6de90717f1086f03cea06f7984cb8d6ea5dbc525e3ecf27
Status: Downloaded newer image for baeldung/spring-boot-app:.0.0.1
这是与我构建的系统不同的系统的run
的输出 。与您运行hello-world的方式类似,您将图像标记传递给 docker run
。由于图像在本地不可用,Docker将它从Docker Hub中取出,组装并运行它。
Docker是一个用于构建,管理和运行容器化应用程序的强大平台。在本教程中,我们安装了工具,打包了一个Spring Boot应用程序,查看了我们如何管理容器和映像,然后对我们的应用程序添加了一些改进。
最后,我们将我们的图像发布到Docker Hub,可以在任何支持Docker的主机上下载并运行它。
现在您已了解基础知识,继续进行实验,并了解如何使用Docker打包和分发Java应用程序。
与往常一样,本教程的源代码可在GitHub上获得。
原文标题《A Start to Finish Guide to Docker With Java, Part 2》
译者:February
不代表云加社区观点,更多详情请查看原文链接
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。