Docker 简明教程

How to Run Java in a Docker Container?

Docker 允许你设置可在生产和开发服务器中使用的 Java 环境。它提高了执行 Java 程序的效率和可管理性。无论底层配置、环境和依赖项如何,Docker 都允许你在所有平台上可靠地、一致地运行 Java 程序。它还极大地简化了部署过程,解决了“它只在我的机器上工作”的问题。

Docker allows you to set up Java environments that you can use in production and development servers alike. It enhances the efficiency and the manageability of executing Java programs. Irrespective of the underlying configurations, environment, and dependencies, Docker allows you to run Java programs reliably, and consistently across all the platforms. It greatly simplifies the deployment procedure as well and the problem of “it works only on my machine” is resolved.

你可以使用下面讨论的两种主要方法在 Docker 容器中运行 Java −

You can run Java in Docker containers using the two main approaches discussed below −

  1. You can use the official Java Docker base images provided by Oracle or AdoptOpenJDK.

  2. You can create your own Docker images with custom dependencies tailored specifically for Java applications by using Dockerfiles.

在本章中,我们将通过逐步说明、命令和示例解释这两种方法,以便在 Docker 容器中创建和运行 Java 应用程序。

In this chapter, we will explain both of these approaches to create and run Java applications inside the Docker container with the help of step-by-step instructions, commands, and examples.

Benefits of Using Docker Containers to Run Java Applications

在 Docker 容器中运行 Java 应用程序有很多好处。它们增强了开发和部署工作流,并改进了可伸缩性和可靠性。以下是将 Docker 容器用于 Java 应用程序的一些主要优点。

There are several benefits associated with running Java applications inside Docker containers. They enhance the development and deployment workflows and improve scalability and reliability. Here are some of the key advantages of using Docker containers for Java applications.

  1. Isolation − Ensures independent operation.

  2. Consistency − Maintains uniform runtime environments.

  3. Portability − Facilitates easy migration between environments.

  4. Resource Efficiency − Maximizes resource utilization.

  5. Scalability − Allows seamless adjustment to workload demands.

How to Run Java in Docker Using Java Base Images?

在 Docker 中运行 Java 最简单的方法之一是使用可信组织(如 Oracle 或 AdoptOpenJDK)提供的现有 Java 基础镜像。为此,提供了以下步骤和命令。

One of the easiest ways to run Java in Docker is by using the existing Java base images provided by trusted organizations like Oracle or AdoptOpenJDK. To do so, here are the steps and commands.

Step 1: Pull the Java Base Image

你可以通过使用 Docker pull 命令从 Docker Hub 中拉取 Java 基础镜像来开始。例如,如果你想从 AdoptOpenJDK 中拉取 OpenJDK 11 镜像,你可以使用以下命令。

You can start by pulling the Java base image from Docker Hub using the Docker pull command. For example, if you want to pull the OpenJDK 11 image from AdoptOpenJDK, you can use the following command.

docker pull adoptopenjdk/openjdk11

Step 2: Run the Docker Container

现在你已经将基础镜像拉取到你的本地,你可以使用已拉取的镜像运行 Docker 容器。你可以指定你想在容器内运行的 Java 应用程序 JAR,并将其复制到容器中。为此,你可以使用以下命令。

Now that you have the base image pulled to your local, you can run the Docker container using the pulled image. You can specify the Java application JAR that you want to run inside the container and copy it to the container. To do so, you can use the following command.

docker run -d --name my-java-container -v
   /path/to/your/jar:/usr/src/app/my-java-app.jar adoptopenjdk/openjdk11

此命令中 −

In this command −

  1. -d − This flag helps you to detach the container and you can run it in the background.

  2. --name my-java-container − You can assign a name to the running container for your reference using this flag.

  3. -v /path/to/your/jar:/usr/src/app/my-java-app.jar − This flag helps you to mount the directory that contains your Java application JAR into the container at /usr/src/app/my-java-app.jar.

  4. adoptopenjdk/openjdk11 − This is the name of the base image that you want to pull.

Step 3: Access the Container’s Bash

如果你想检查 Java 是否安装在使用 Docker 镜像创建的容器中,你可以访问容器的 bash shell。为此,你可以使用以下命令。

If you want to check whether Java is installed in the container that you created using the Docker image, you can access the bash shell of the container. To do so, you can use the following command.

docker exec -it my-java-container /bin/bash

此命令中 −

In this command −

  1. docker exec − It lets you execute a command inside a running container.

  2. -it − It allocates a pseudo-TTY and helps keep the stdin open. This allows you to interact with the container’s bash shell.

  3. my-java-container − This is the name of the running container.

  4. /bin/bash − This specifies the command that you want to execute inside the container. This command opens a bash shell inside the container.

Step 4: Check Java Installation

现在你已经访问了容器的 bash shell,你可以通过运行以下命令检查 Java 是否已安装。

Now that you have access to the bash shell of the container, you can check if Java is installed by running the below command.

java -version

此命令用于显示已安装在容器中的 Java 和 JDK 的版本。运行此命令后,如果你看到与 Java 版本相关的信息,则表示 Java 已正确安装在容器中。

This command is used to display the version of Java and JDK that has been installed in the container. On running this command, if you see the information related to the Java version, it means Java is installed properly in the container.

现在您已验证在容器内成功安装了 Java,可以通过键入“exit”并按下 enter 键退出容器的 bash。

Now that you have verified the successful installation of Java inside the container, you can exit the bash of the container by typing “exit” and pressing the enter key.

How to Use Dockerfile to Create Custom Java Images?

您可以使用 Dockerfile 创建和构建 Docker 镜像,为 Java 应用程序定义特定环境并运行配置。按照以下步骤使用 Dockerfile 创建自定义 Docker 镜像。

You can define your specific environment and run configurations for your Java applications using a Dockerfile to create and build Docker images. Here are the steps that you can follow to create a custom Docker image using Dockerfile.

Step 1: Create a Dockerfile

首先,在 Java 应用程序目录中创建一个 Dockerfile。在 Dockerfile 中,我们将提及构建镜像层级所需的指令。下面为在其中预先安装了 Java 的 Docker 镜像准备的 Dockerfile −

First, create a Dockerfile in the directory of your Java application. In the Dockerfile, we will mention the instructions to build image layers. Here’s a Dockerfile for a Docker image that has Java pre-installed in it −

# Use a base Java image
FROM adoptopenjdk/openjdk11:latest

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy the Java application JAR file into the container
COPY target/my-java-app.jar .

# Expose the port on which your Java application runs (if applicable)
EXPOSE 8080

# Command to run the Java application
CMD ["java", "-jar", "my-java-app.jar"]

此 Dockerfile 中 −

In this Dockerfile −

  1. FROM − You can use FROM to specify the base image to be used. In this case, we have used OpenJDK 11 from AdoptOpenJDK as the base image.

  2. WORKDIR − This directive helps you to set the default working directory inside the Docker container where all the subsequent commands will be run.

  3. COPY − It helps you to copy the Java application JAR file from your local directory into the container.

  4. EXPOSE − This directive helps you to expose a particular port of the Docker container. You can adjust the port number based on your application’s configuration.

  5. CMD − You can use this directive to define the default command to be run when the container starts. In this case, we will execute the Java application JAR file.

Step 2: Build the Docker Image

现在,Dockerfile 已准备就绪,导航到 Dockerfile 所在的路径,然后运行以下 Docker 构建命令以创建 Docker 镜像。

Now that you have your Dockerfile ready, navigate to the path where your Dockerfile is located and run the Docker build command below to create the Docker image.

docker build -t my-custom-java-image .

此命令中 −

In this command −

  1. -t my-custom-java-image − The -t flag tags the Docker image with a custom name for meaningful future references.

  2. Dot − The dot here specifies the build context. In this case, it is the current directory containing the Dockerfile.

Step 3: Run the Docker Container

您还可以使用“docker images”命令检查镜像是否已成功构建。如果镜像成功构建,则您可以使用以下命令为该镜像运行容器。

You can check whether your image has been built successfully using the “docker images” command. If the image is built successfully, you can run a container for that image using the below command.

docker run -d --name my-java-container my-custom-java-image

此命令中 −

In this command −

  1. -d − This option detaches the container which helps you to run it in the background.

  2. --name my-java-container − Similar to providing a name to an image, you can use it to provide a meaningful name to your container.

  3. my-custom-java-image − This is the name of the image that you want to create and run a container for.

如果您要验证 Java 应用程序是否按预期运行,可以通过运行之前方法中提及的“docker exec”命令访问容器的 bash shell。然后您可以验证日志或检查在容器内运行的活动进程。

If you want to verify if the Java application is running as expected, you can run the “docker exec” command mentioned in the previous approach to access the bash shell of the container. You can then verify the log or check the active processes running inside the container.

Key Tips for Setting Up Java in Docker

毫无疑问,Docker 可以帮助您无缝地设置、开发和部署 Java 应用程序。以下是一些技巧,可以改善您在 Docker 中运行 Java 的体验。

No doubt, Docker helps you with the seamless setup, development, and deployment of Java applications. Here are a few tips that can enhance your experience of running Java in Docker.

  1. Consider your application’s requirements and security before choosing the appropriate Java base image and other dependencies.

  2. Optimize your Java runtime by managing the environment variables effectively. This includes memory settings, time zones, etc.

  3. You can minimize redundant image pulls and installations of dependencies by leveraging the caching layer mechanisms of Docker image building.

  4. Ensure that you regularly update the Docker images including Java versions, fix vulnerabilities, bug fixes, etc.

  5. Try to minimize the image size to reduce the attack surface which further enhances security and lowers maintenance.

Frequently Asked Questions

Q1. How do I debug Java applications running in Docker containers?

你可以通过设置 Java 虚拟机 (JVM) 接受用于远程调试的连接,调试运行在 Docker 容器中的 Java 应用程序。若要允许远程调试,可以在 Docker 容器内设置 JAVA_OPTS 环境变量并提供 JVM 调试选项(例如 -agentlib:jdwp )。此外,必须在启动 Docker 容器的同时使用 -p-P 标志(即 5005)公开调试端口。

You may debug Java applications that are running in Docker containers by setting up the Java Virtual Machine (JVM) to accept connections for remote debugging. To allow remote debugging, you can set the JAVA_OPTS environment variable within the Docker container and provide the JVM debug options (e.g., -agentlib:jdwp). Additionally, you must expose the debug port while launching the Docker container with the -p or -P flag (which is 5005).

配置完成后,你可以从命令行调试器或集成开发环境 (IDE) 连接到远程调试器,从而逐步执行代码、设置断点和检查变量。这就更便于识别和修复 Docker 容器中运行的 Java 应用程序的问题。

Once configured, you can step through the code, set breakpoints, and inspect variables while connecting to the remote debugger from your command-line debugger or Integrated Development Environment (IDE). This makes it easier to identify and fix problems with Java applications running inside Docker containers.

Q2. How can I optimize the performance of Java applications running in Docker containers?

为了保证有效使用资源并降低开销,会使用几种技术来优化 Docker 容器中运行的 Java 应用程序的性能。一种方法是根据可用的内存和 CPU 资源,仔细调整 Java 虚拟机 (JVM) 的垃圾回收和堆大小。若要分别调整最大堆大小和初始堆大小,你可以使用 -Xmx-Xms 等 JVM 选项。

Several techniques are used to optimize the performance of Java applications operating in Docker containers in order to guarantee effective resource use and reduce overhead. One method is to carefully adjust the garbage collection and heap size of the Java Virtual Machine (JVM) according to the memory and CPU resources that are available. To adjust the maximum and initial heap sizes, respectively, you can use JVM options like -Xmx and -Xms.

你还可以根据应用程序的内存使用模式选择垃圾回收器(例如 G1GC)。此外,可以通过利用 Docker 的资源约束(例如内存和 CPU 限制)并使用 Kubernetes 等容器编排系统隔离容器工作负载,避免资源争用并保证 Docker 容器中 Java 应用程序的性能一致。

You can also select the garbage collector (such as G1GC) based on the memory usage patterns of the application. Additionally, resource contention can be avoided and consistent Java application performance in Docker containers can be guaranteed by making use of Docker’s resource constraints (such as memory and CPU limits) and isolating container workloads using container orchestration systems like Kubernetes.

Q3. How do I manage logging and monitoring for Java applications running in Docker containers?

管理在 Docker 容器中运行的 Java 应用程序的日志记录和监控的一部分就是使用日志记录框架(例如 Log4j、Logback)和监控工具(例如 Prometheus 和 Grafana)收集并检查应用程序指标和日志。

Using logging frameworks (like Log4j, Logback) and monitoring tools (like Prometheus, and Grafana) to gather and examine application metrics and logs is part of managing logging and monitoring for Java applications running in Docker containers.

可以将 Java 应用程序设置为将日志写入标准错误或输出流,然后由 Docker 捕获这些日志并发送到日志驱动程序(例如 syslog 或 JSON 文件),以进行集中日志记录。此外,可以使用 Dropwizard Metrics 或 Micrometer 等库为 Java 应用程序构建指标,然后通过 JMX 或 HTTP 端点公开这些指标以进行监控。

The Java application can be set up to write logs to standard error or output streams, which Docker then catches and sends to logging drivers (such syslog or JSON files) for centralized logging. Furthermore, you can use libraries such as Dropwizard Metrics or Micrometer to instrument your Java application with metrics, and then expose those metrics through JMX or HTTP endpoints for monitoring.