容器的方法"/>
将你的Java应用程序放入Docker容器的方法
原始地址:
Cover image by Benjamin Voros on Unsplash
如今Docker的普及率之高主要得益于它的易用性以及它能够让开发人员创建一个可在任何机器上运行的便携式应用程序。在本篇博文中,我将展示如何使用自己的Java应用程序创建自己的Docker镜像。
你还没有听说过Docker吗?或者你对它不太了解?别担心,你可以查看我之前的一篇文章,我在里面详细介绍了它。
为了演示本博文,我创建了一个简单的Java项目。这是一个Spring Boot应用程序,它连接到NASA每日天文图片API,获取当天的图片及描述,然后在一个主页上打印出来(HTML格式)。
应用程序的源代码可以在我的GitHub账户上找到。如果你对Spring Boot不熟悉,也不用担心。我不会关注它的实现,只专注于Docker🐋。
创建和运行容器
要开始,请转到你的项目的根文件夹(在我这里是~/nasa-picture),并创建一个名为Dockerfile的文本文件。它将包含创建镜像所需的所有步骤(就像食谱中的步骤一样)。对于我的应用程序,它如下所示:
FROM java:8-jdk-alpineCOPY ./build/libs/nasapicture-0.0.1-SNAPSHOT.war /usr/app/WORKDIR /usr/appEXPOSE 8080ENTRYPOINT ["java", "-jar", "nasapicture-0.0.1-SNAPSHOT.war"]
哇,这是什么意思?有些步骤可能是不言自明的,但让我们将它们分解成更小的部分。
FROM java:8-jdk-alpine——通过这一行,我们告诉Docker我们的镜像将基于公共仓库(Docker Hub)上的另一个镜像。这个镜像是由其他人准备的,包含了运行任何Java应用程序所需的所有依赖项。
COPY ./build/libs/nasapicture-0.0.1-SNAPSHOT.war /usr/app/——正如你可能已经猜到的那样,这一步是将某些东西从一个目录复制到另一个目录。但是是什么以及在哪里?
COPY之后的第一个参数是我们想要放入容器的应用程序的路径。我使用*.war文件,因为我的项目是一个Web应用程序,但如果你的项目是一个标准的.jar*应用程序,就使用它。第二个参数/usr/app/是容器中的一个目录,我们在其中放置该应用程序。
WORKDIR /usr/app——在这里,我们指示Docker使用/usr/app文件夹作为根目录,否则,在每个后续的命令中,我们都需要提供资源的完整路径。
EXPOSE 8080——这个命令告诉Docker容器将监听特定的端口,与我们的应用程序使用的端口相同。
ENTRYPOINT [“java”, “-jar”, “nasapicture-0.0.1-SNAPSHOT.war”]——在最后一条命令中,我们告诉Docker运行该应用程序,其中第一个值是一个命令,后面两个是参数。
完成后,我们可以进入终端,转到包含Dockerfile的文件夹,并使用以下命令构建镜像(-t选项后的参数是镜像的名称,你可以随意选择;还要注意命令的末尾有一个点.):
> docker build -t nasa-picture .
发送构建上下文到Docker守护程序 35.54MB
步骤 1/5 : FROM java:8-jdk-alpine
—> 3fd9dd82815c
步骤 2/5 : COPY ./build/libs/nasapicture-0.0.1-SNAPSHOT.war /usr/app/
—> 6c90658d9558
步骤 3/5 : WORKDIR /usr/app
—> Running in 3d453fe48248
Removing intermediate container 3d453fe48248
—> 27f352fbbb15
步骤 4/5 : EXPOSE 8080
—> Running in 0c656ae718e7
Removing intermediate container 0c656ae718e7
—> b3bd82c446b6
步骤 5/5 : ENTRYPOINT [“java”, “-jar”, “nasapicture-0.0.1-SNAPSHOT.war”]
—> Running in b09c6788d305
Removing intermediate container b09c6788d305
—> 08ee9123cd58
成功构建 08ee9123cd58
成功标记为nasa-picture:latest
如上所示,Docker正在按照Dockerfile中定义的命令一步一步地构建镜像。
现在我们可以检查它是否已经构建完毕,使用以下命令:
> docker images
仓库 标签 镜像ID 创建时间 大小
nasa-picture latest 08ee9123cd58 8分钟前 167MB
java 8-jdk-alpine 3fd9dd82815c 2年前 145MB
正如你从上面的输出中可以看到的,Docker正在执行按照Dockerfile中定义的命令逐步构建镜像。
现在我们可以检查它是否真的已经构建好了,使用以下命令:
> docker images
仓库 标签 镜像ID 创建时间 大小
nasa-picture latest 08ee9123cd58 8分钟前 167MB
java 8-jdk-alpine 3fd9dd82815c 2年前 145MB
很好,镜像可用,那么让我们运行它吧。
> docker run -p 3333:8080 nasa-picture
. ____ _ __ _ _
/\ / _’ __ _ () __ __ _ \ \ \ \
( ( )___ | '_ | '| | ’ / _` | \ \ \ \
\/ _)| |)| | | | | || (| | ) ) ) )
’ || .__|| ||| |__, | / / / /
=|_|======|/=////
:: Spring Boot :: (v2.1.3.RELEASE)
2019-04-08 05:01:33.617 INFO 1 — [ main] c.w.m.n.NasapictureApplication : Starting NasapictureApplication on 523080401cdd with PID 1 (/usr/app/nasapicture-0.0.1-SNAPSHOT.war started by root in /usr/app)
2019-04-08 05:01:33.621 INFO 1 — [ main] c.w.m.n.NasapictureApplication : No active profile set, falling back to default profiles: default
2019-04-08 05:01:36.054 INFO 1 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-04-08 05:01:36.112 INFO 1 — [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-04-08 05:01:36.113 INFO 1 — [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.16]
2019-04-08 05:01:36.132 INFO 1 — [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/…/lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2019-04-08 05:01:37.451 INFO 1 — [ main] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2019-04-08 05:01:37.853 INFO 1 — [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-04-08 05:01:37.853 INFO 1 — [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 4143 ms
2019-04-08 05:01:38.685 INFO 1 — [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService ‘applicationTaskExecutor’
2019-04-08 05:01:39.031 INFO 1 — [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path ‘/actuator’
2019-04-08 05:01:39.221 INFO 1 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ‘’
2019-04-08 05:01:39.226 INFO 1 — [ main] c.w.m.n.NasapictureApplication : Started NasapictureApplication in 6.2 seconds (JVM running for 7.479)
太好了!容器已创建并正在运行。要测试它,请在浏览器中输入以下URL:http://localhost:3333/
现在如果你想停止应用程序,只需在键盘上使用Ctrl + C组合键。要检查它是否真的没有运行,请输入以下命令:
> docker container ls -a
… 镜像 命令 状态
… nasa-picture “java -jar nasapictu…” 已退出 (130) 7秒前
将Docker镜像导出为文件
到目前为止,所有操作都在一台计算机上进行,但通常我们希望与他人共享我们的工作,这将需要生成一个可以通过电子邮件发送、复制到Dopbox、或者通过fttp等方式发送的文件。Docker允许将一个镜像保存为.tar文件,只需键入以下命令即可:
> docker save --output nasa-picture-export.tar nasa-picture
第一个参数,带有–output标志,是导出文件的名称,后面是镜像的名称,我们将它放在文件中。
现在我们有了一个导出的镜像,你可以共享它,然后使用以下指令打开它:
> docker load --input nasa-picture-export.tar
然后将提取出新的镜像,并可以使用它(与之前的操作方式相同)。
在Docker Hub上发布镜像
上述方法运行良好,但坦率地说,这不是21世纪的方法。我们习惯了能够在几秒钟内从互联网上下载任何东西。因此,用Docker镜像交换文件可能不是那么方便。
相反,我们可以将镜像推送到中央仓库Docker Hub,然后以控制台中的名称输入它,以在任何地方提取它。
首先,你需要在Docker Hub上拥有一个账户。如果还没有,请创建一个,它是免费的。
然后,在登录到你的账户之后,在主页上会有一个图标,用于创建一个仓库(参见左侧的图片)。请点击这个图标。
接下来,会出现一个新页面,在这个页面上,你可以提供仓库的名称、描述,并决定它是一个公开(向全世界开放)还是私有(只有你能看到)的仓库。
设置好一切后,只需点击页面底部的创建按钮即可。
现在让我们回到PC上的控制台,并键入以下命令以登录到Docker Hub(在登录过程中,将提示输入密码):
> docker login --username=wkrzywiec
密码:
警告!你的密码将以未加密的方式存储在/home/…中。
配置凭据助手以删除此警告。请参阅
登录成功
好的,我们已经连接上了。现在让我们准备一个将要被推送的镜像。假设你仍然拥有你的镜像,并通过以下命令检查它:
> docker images
仓库 标签 镜像ID
nasa-picture latest 430e1de8c0d4
我们需要为镜像添加标签。标签通常包含有关镜像版本的有用信息,并在镜像名称之后用分号表示,例如:latest。
> docker tag 430e1de8c0d4 wkrzywiec/nasa-picture:firsttry
430e1de8c0d4——这是我们要标记的镜像的ID,
wkrzywiec/nasa-picture:firsttry——在这里,我们提供将被发送到Docker Hub的镜像的完整名称。它与某个模式匹配——
docker-hub-用户名/镜像-名称:镜像-标签。重要的是它与Docker Hub仓库的名称相同。标签可以是任何我们想要的。
一切都设置好了,所以现在让我们将其推送到仓库:
> docker push wkrzywiec/nasa-picture
推送到repository [docker.io/wkrzywiec/nasa-picture]
e2fd04bd79f3: 已推送
a1e7033f082e: 已从library/java挂载
78075328e0da: 已从library/java挂载
9f8566ee5135: 已从library/java挂载
firsttry: 摘要: sha256:a2c24d7e0abea09be2520e6bbf41b61f4be1da3f372a98fecc16ebb4db20fd07 大小: 1159
现在它在Docker Hub上了!要检查它,请访问网站,或者您可以通过命令行拉取镜像。如果你选择第二个选项,首先确保你本地没有这个镜像,使用
docker image prune -a。然后你就可以执行以下操作:
> docker pull wkrzywiec/nasa-picture:firsttry
拉取来自 wkrzywiec/nasa-picture 的 firsttry
709515475419: 已完成
38a1c0aaa6fd: 已完成
5b58c996e33e: 已完成
4eb443a91b8c: 已完成
摘要: sha256:a2c24d7e0abea09be2520e6bbf41b61f4be1da3f372a98fecc16ebb4db20fd07
状态: 下载了较新的镜像 wkrzywiec/nasa-picture:firsttry
太好了,它正常工作!但是如果你不想每次拉取镜像时都提供:firsttry标签怎么办?没有更简单的方法,当你像之前的步骤那样给镜像打标签时,你需要用
:latest标签来标记它,然后将其推送到Docker Hub。从现在开始,要拉取一个镜像,你可以使用
docker pull wkrzywiec/nasa-picture。
如果想要查看应用程序代码的源代码,去查看我的GitHub项目:
wkrzywiec
/
Nasa-Picture
Single-page application which display NASA’s Astronomy Picture of the Day
或者你可以拉取它的Docker镜像:
Docker Hub 位于 hub.docker
参考资料
Spring Boot with Docker 在 spring.io Dockerizing a Spring Boot Application 在 stackabuse A Start to Finish Guide to Docker with Java 在 stackify How to copy Docker images from one host to another without using a repository 在 stackoverflow docker build 在 docs.docker Pushing and Pulling to and from Docker Hub 在 ropenscilabs.github.io A quick introduction to Docker tags 在 medium.freecodecamp
更多推荐
将你的Java应用程序放入Docker容器的方法
发布评论