
随着 Heroku 等平台免费层的取消,开发者们正积极寻找替代方案来部署 Java 应用。Render.com 作为一种流行的云服务,虽然不直接支持 Java 原生构建,但其对 Docker 的良好支持使其成为一个有吸引力的选择。然而,对于初次尝试将 Quarkus 应用通过 Docker 部署到 Render 的开发者来说,可能会遇到构建失败的问题,尤其是在处理 Quarkus 默认提供的 Dockerfile 时。
典型的 Quarkus 应用在本地开发时,通常会在运行 mvnw package 后生成编译好的产物。而默认的 Quarkus Dockerfile 往往假定这些产物(位于 target/quarkus-app 目录)已经存在于构建上下文中。当直接将包含源代码的 Git 仓库连接到 Render 并尝试构建时,由于 target 目录尚未生成,Docker 构建过程将因找不到文件而失败,报错信息通常为 no such file or directory。
Quarkus 提供的默认 Dockerfile.jvm 示例通常如下所示:
FROM registry.access.redhat.com/ubi8/openjdk-17:1.14 ENV LANGUAGE='en_US:en' COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ COPY --chown=185 target/quarkus-app/*.jar /deployments/ COPY --chown=185 target/quarkus-app/app/ /deployments/app/ COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ EXPOSE 8080 USER 185 ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
这个 Dockerfile 的核心问题在于,它直接尝试从本地文件系统的 target/quarkus-app 目录复制文件。在 Docker 构建环境中,如果这个目录在构建开始前不存在(即没有在本地运行 mvnw package),或者在 Dockerfile 中没有明确的编译步骤,那么 COPY 指令就会失败。即使尝试在 COPY 之前添加 RUN ./mvnw package,如果构建上下文没有包含完整的项目源代码,同样会导致问题。
解决此问题的最佳实践是采用多阶段 Dockerfile 构建。多阶段构建允许在一个 Dockerfile 中定义多个阶段,每个阶段可以基于不同的基础镜像,并且可以将前一个阶段的产物传递给下一个阶段。这使得我们可以在一个阶段中完成应用的编译,然后在另一个更轻量级的阶段中只包含运行时所需的产物,从而生成更小、更安全的最终镜像。
以下是一个适用于 Quarkus 应用的多阶段 Dockerfile 示例:
# --- 构建阶段 --- # 使用包含 JDK 和 Maven 的基础镜像进行编译 FROM registry.access.redhat.com/ubi8/openjdk-17:1.14 as builder # 设置工作目录 WORKDIR /project # 复制 Maven 依赖文件,利用 Docker 缓存加速构建 COPY pom.xml . COPY .mvn .mvn COPY mvnw . RUN ./mvnw dependency:go-offline -B # 复制项目源代码 COPY src src # 编译 Quarkus 应用 RUN ./mvnw package -Dquarkus.package.type=mutable-jar -DskipTests # --- 运行时阶段 --- # 使用更轻量级的 JDK 运行时镜像 FROM registry.access.redhat.com/ubi8/openjdk-17:1.14 as runner # 设置语言环境 ENV LANGUAGE='en_US:en' # 从构建阶段复制编译好的应用产物 COPY --from=builder /project/target/quarkus-app/lib/ /deployments/lib/ COPY --from=builder /project/target/quarkus-app/*.jar /deployments/ COPY --from=builder /project/target/quarkus-app/app/ /deployments/app/ COPY --from=builder /project/target/quarkus-app/quarkus/ /deployments/quarkus/ # 暴露应用端口 EXPOSE 8080 # 以非 root 用户运行 USER 185 # 设置 Java 运行时参数 ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" # 定义容器启动命令 ENTRYPOINT [ "java", "-jar", "/deployments/quarkus-run.jar" ]
多阶段 Dockerfile 详解:
构建阶段 (builder):
运行时阶段 (runner):
在使用多阶段 Dockerfile 时,.dockerignore 文件的配置至关重要。它决定了哪些文件和目录不会被复制到 Docker 构建上下文中。如果 .dockerignore 文件中包含 * 或 src/ 等规则,可能会阻止源代码被复制到构建阶段,从而导致编译失败。
重要提示: 确保 .dockerignore 文件中不包含会阻止源代码(如 src 目录)被复制到构建上下文的规则。如果存在 * 这样的通配符,请务必移除或修改,以允许必要的源代码被复制。
一个合理的 .dockerignore 文件示例:
target/ .mvn/wrapper/maven-wrapper.jar .git/ .gitignore .idea/ *.iml *.log tmp/
这个配置会忽略 target 目录(因为我们会在容器内生成它)、Git 相关文件、IDE 文件等,但会确保 src 目录和 pom.xml 等关键文件被包含在构建上下文中。
完成上述 Dockerfile 和 .dockerignore 的配置后,在 Render.com 上部署 Quarkus 应用的步骤如下:
通过遵循这些步骤和最佳实践,开发者可以成功地将 Quarkus Java 应用部署到 Render.com,享受云原生部署的便利性。
以上就是Quarkus 应用在 Render.com 上的 Docker 部署指南的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号