在 docker 镜像中部署 WAR 文件的正确方法

2022-01-14 00:00:00 docker dockerfile java maven jetty

在docker容器中部署java项目的docker方式是什么?

What is the docker way to deploy java projects in a docker container?

我是否将战争复制到 webapps 中:

Do I copy the war into webapps:

FROM jetty:9.2.10
MAINTAINER Me "me@me.com"
ADD ./target/*.war /var/lib/jetty/webapps/ROOT.war

还是我拿爆炸的战争文件:

or do I take the exploded war file:

FROM jetty:9.2.10
MAINTAINER Me "me@me.com"
ADD ./target/app-0.1.0.BUILD-SNAPSHOT /var/lib/jetty/webapps/ROOT

如果它是一个普通容器,通常会部署密封的战争文件,但对于 docker,这意味着每次你做一个小的改变时都会推送一个 10-20MB 的文件,而添加爆炸的战争只会推动差异 - .已更改的类文件.

Normally one would deploy the sealed war file if it was a normal container, but with docker, that means pushing a 10-20MB file every time you make a small change whereas adding the exploded war would only push the difference - the .class file that has changed.

部署爆炸战争而不是战争文件有什么缺点吗?

Are there any downsides to deploying the exploded war instead of the war file?

推荐答案

我想知道您是如何使用图像的.在构建图像时添加 20MB 文件几乎应该是即时的.也许你在部署过程中以某种方式构建图像,就像 AWS 在你给它一个 Dockerfile 时所做的那样.

I wonder how you're using your images. Adding a 20MB file while building an image should almost be instant. Mayb you somehow building images during deployment, like AWS does when you give it a Dockerfile.

无论如何,我认为这取决于您的部署方式.如果您在自己周围移动图像,我认为添加 .war 文件和分解的 WAR 目录之间没有太大区别.我会说做你方便的事.但是,如果您有时从 Docker 运行应用程序,有时从 .war 运行应用程序(这可能会忽略 Docker 的某些要点),那么您不妨一直使用 .war.

In any case, I think it depends on how you're deploying. If you're moving the images around yourself, I don't see a lot of difference between ADDing a .war file and an exploded WAR directory. I would say do what's convenient for you. However, if you sometimes run the app from Docker and sometimes from a .war (which might miss some of the point of Docker), you might as well use the .war all the time.

如果您要部署到诸如 AWS Elastic Beanstalk(从存储库中提取图像的东西)之类的东西,它需要 Dockerfile 或 Dockerrun.aws.json 文件,那么将图像与您实际部署的内容分开会产生一些影响有意义(或者到目前为止对我来说是有意义的).这允许容器保持不变,而更新您的应用程序只需将 .jar/.war 文件复制到正确的位置(这也可能会错过 Docker 的部分要点;).

If you're deploying to something like AWS Elastic Beanstalk (something that pulls the image from a repository), which wants either a Dockerfile or a Dockerrun.aws.json file, then separating the image from what you actually deploy makes some sense (or it has made sense to me so far). This allows the container to stay the same, while updating your app can be just copying a .jar/.war file to the right location (which also might miss part of the point of Docker ;).

我一直在做的是在 Docker Hub 上创建一个基础映像,然后使用 Dockerrun.aws.json 文件在我的应用程序中进行映射.这样,AWS 不需要构建我的镜像,只需拉取它.这更快,成本更低($).但它确实将我的应用程序与图像分开,这在某些情况下可能会使部署复杂化.但是,因为我的镜像非常稳定,所以我通常只是将一个 .jar 文件、一个 Dockerrun.aws.json 文件和一个 shell 脚本打包成一个 .zip 并上传到 AWS.我觉得很简单.

What I've been doing is creating a base image on Docker Hub and then using the Dockerrun.aws.json file to map in my app. That way, AWS does not need to build my image, just pull it. That's much faster and less costly ($). But it does separate my app from the image, which might complicate deployment in some circumstances. However, because my image is so stable, I generally just bundle a .jar file, a Dockerrun.aws.json file and a shell script into a .zip and upload it to AWS. Pretty easy I think.

我的 Dockerfile 非常简单,是我的 Spring Boot 应用程序所需要的全部内容:

My Dockerfile is pretty simple and really all I need for my Spring Boot app:

FROM java:8
VOLUME /tmp
VOLUME /app
EXPOSE 8080
ENTRYPOINT ["sh","/app/app.sh"]

您可以执行类似的操作并使用 -v 选项等将卷映射到您的应用程序、环境设置等.顺便说一句,这个镜像 在 Docker Hub 上可用.

You could do something similar and use the -v option, etc., to map volumes to your app, it's environment settings, etc. BTW, this image is available on Docker Hub.

相关文章