

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 容器映像的最佳实践
<a name="containers-best-practices"></a>

在为以下对象构建容器镜像时，请遵循以下最佳实践 HealthOmics 工作流程。

## 在亚马逊 ECR 容器镜像中使用 Java
<a name="ecr-java-considerations"></a>

如果工作流任务使用诸如 GATK 之类的 Java 应用程序，请考虑容器的以下内存要求：
+ Java 应用程序使用堆栈内存和堆内存。默认情况下，最大堆内存是容器中总可用内存的百分比。此默认值取决于特定的 JVM 发行版和 JVM 版本，因此请查阅 JVM 的相关文档或使用 Java 命令行选项明确设置最大堆内存（例如 `-Xmx`）。
+ 不要将最大堆内存设置为容器内存分配的 100%，因为 JVM 堆栈也需要内存。JVM 垃圾收集器和容器中运行的任何其他操作系统进程也需要内存。
+ 某些 Java 应用程序（例如 GATK）可以使用本机方法调用或其他优化，例如内存映射文件。这些技术需要 “堆外” 执行的内存分配，而 JVM 最大堆参数无法控制这些分配。

  如果您知道（或怀疑）您的 Java 应用程序分配堆外内存，请确保您的任务内存分配包括堆外内存要求。

  如果这些堆外分配导致容器耗尽内存，则通常看不到 Java `OutOfMemory` 错误，因为 JVM 无法控制此内存。

## 向 Amazon ECR 容器映像添加任务输入
<a name="ecr-tasks"></a>

将运行工作流程任务所需的所有可执行文件、库和脚本添加到用于运行任务的 Amazon ECR 映像中。

最佳做法是避免使用任务容器映像外部的脚本、二进制文件和库。这在使用时尤其重要 `nf-core` 使用 a 的工作流程 `bin` 目录作为工作流程包的一部分。尽管此目录可用于工作流任务，但它是作为只读目录安装的。应将此目录中的所需资源复制到任务映像中，并在运行时或构建用于任务的容器映像时可用。

参见 [HealthOmics 工作流程固定大小配额](fixed-quotas.md#fixed-quotas-workflows) 对于容器镜像的最大大小 HealthOmics 支持。

## 对于非 PTC 图像，使用摘要或版本代替标签
<a name="containers-best-practices-non-ptc-pin"></a>

对于来自不支持提取缓存的注册表（例如 Seqera、NVIDIA NGC 和 Google Artifact Registry）的容器镜像，请引用摘要或版本而不是标签，例如 `latest`。 HealthOmics 在任务第一次需要时复制图像，并且不会刷新副本，因此上游更改的标签会继续解析为较早的副本。有关更多信息，请参阅 [使用拉入式缓存不支持的第三方注册表](containers-non-ptc-registries.md)。

以下示例按版本和摘要引用了 Seqera 容器镜像：

```
community.wave.seqera.io/library/htslib_samtools:1.24--d697cfb9dce007cd@sha256:a55ddea590e567a91df592300a960aa534cfc1bd16e7623e3938ec21f4f3df15
```