使用Java完成对Docker的指南入门,第2部分

欢迎回来!

管理Docker应用程序

启动和停止Docker容器

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》

作者:Eugen Paraschiv

译者:February

不代表云加社区观点,更多详情请查看原文链接

原文链接:https://dzone.com/articles/a-start-to-finish-guide-to-docker-with-java-part-2

原文作者:Eugen Paraschiv

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Laoqi's Linux运维专列

Docker 空间使用分析与清理

4664
来自专栏云计算教程系列

使用Docker容器

Docker是一种流行的容器化工具,用于为软件应用程序提供包含运行所需内容的文件系统。使用Docker容器可确保软件的行为方式相同,无论其部署位置如何,因为其运...

2313
来自专栏容器云生态

如何优雅的编写Dockerfile

在生产环境中一般我们会对基本的环境进行自构建,从而利用images的分层特性去层层构建上层的业务镜像。 1.默认情况下我们会首先构建一个基本的base镜像,这...

1.1K8
来自专栏云计算教程系列

如何在Ubuntu 14.04上安装和使用Docker Compose

Docker是一个很棒的工具,但要真正充分发挥其潜力,最好是应用程序的每个组件都在自己的容器中运行。对于具有大量组件的复杂应用程序,编排所有容器以一起启动和关闭...

4121
来自专栏漫漫全栈路

Docker 初次见面

Docker没有官方中文文档(至少目前为止没有,2018/1/1),所以只能通过搜索引擎加上我自己的了解来说一下。

4318
来自专栏云计算教程系列

如何在CentOS 7上安装和使用Docker

Docker是一个应用程序,它使得在容器中运行应用程序进程变得简单易行,就像虚拟机一样,只是更便携,更加资源友好,更依赖于主机操作系统。

6300
来自专栏从零学习云计算

kubernetes学习记录(3)——集群外部访问Pod或Service

学习阅读的书籍为《kubernetes权威指南:从Docker到Kubernetes实践全接触》,书中有不少地方讲的比较模糊,故在此做下学习过程中的梳理。 Po...

3950
来自专栏云计算教程系列

如何在Debian 9上安装和使用Docker

Docker是一个简化容器中应用程序进程管理过程的应用程序。容器允许您在资源隔离的进程中运行应用程序。它们与虚拟机类似,但容器更便携,更加资源友好,并且更依赖于...

4.9K4
来自专栏搜云库

Docker 部署SpringBoot项目整合 Redis 镜像做访问计数Demo

Docker 部署SpringBoot项目整合 Redis 镜像做访问计数Demo

29011
来自专栏云计算教程系列

如何在Ubuntu 16.04上安装和使用Docker

Docker是一个应用程序,它使得在容器中运行应用程序进程变得简单易行,就像虚拟机一样,只是更便携,更加资源友好,更依赖于主机操作系统。

4353

扫码关注云+社区

领取腾讯云代金券