使用官方的基础镜像来构建应用
不要使用从整个操作系统从头安装的模式来构建应用,比如我们使用node环境的时候,我们应该直接使用node镜像,而不是使用centos或者ubuntu镜像,然后自己安装node环境。
指定镜像的版本
如果我们不指定进行的版本的话,它默认采用的就是最新版本,这样的每次构建的时候,可能会导致和之前的版本不一致,所以对此才去的方法就是采用指定版本,这样每次构建的版本都是统一的。
使用最小化的操作系统
linux的操作系统有很多版本,比如centos或者ubuntu等等,但是它们对于我们的应用来说都显得太大,太臃肿,因此我们推荐采用更小的系统,比如alpine等。
优化镜像层的缓存
在Dockerfile中找到的每个命令都会在创建一个新层。每一层都包含对执行命令之前的状态和执行命令之后的状态的映像的文件系统更改。
RUN命令允许您在 Docker 映像中执行命令。如果该RUN命令生成的图层已经存在于缓存中,则该RUN 命令只能执行一次。
Dockerfile中的COPY命令允许您将一个或多个外部文件导入 Docker 映像。执行时,这些COPY命令可确保您拥有所有相关外部文件的最新版本。
如果第一个COPY命令上的所有外部文件的内容都相同,将使用层缓存,并且所有后续命令直到下一个ADD或COPY命令将使用层缓存。
但是,如果一个或多个外部文件的内容不同,那么 所有后续命令都将在不使用层缓存的情况下执行。
为了利用 Docker 的层缓存,您应该 Dockerfile以一种经常更改的步骤(例如COPY位于Dockerfile文件末尾附近)的方式来构建您的结构。这将确保不会不必要地重建与执行相同操作有关的步骤。
学会使用.dockerignore 文件
使用 .dockerignore 有很多优势。它可以帮助减少 Docker 镜像大小、加速docker build并避免意外密码的泄露.
Docker 是一个客户端-服务器应用程序,它由 Docker 客户端和 Docker 服务器(也称为 Docker 守护进程)组成。Docker 客户端命令行工具与 Docker 服务器对话并要求它做事。其中之一是 Docker build:构建一个新的 Docker 映像。Docker 服务器可以与客户端运行在同一台机器上,也可以在虚拟机中运行,也可以是本地、远程或云中的。
为了创建一个新的 Docker 镜像,Docker 服务器需要访问文件,你想从中创建 Docker 镜像。因此,您需要以某种方式将这些文件发送到 Docker 服务器(因为记住 Docker 服务器可以是另一台远程机器)。这些文件是 Docker构建上下文。Docker 客户端将所有构建上下文文件打包到一个tar存档中,并将此存档上传到 Docker 服务器。默认情况下,客户端将获取当前工作目录中的所有文件(和文件夹)并将它们用作构建上下文。
.dockerignore文件是工具,它可以帮助您定义您真正需要的 Docker构建上下文。使用此文件,您可以为文件和文件夹指定这些规则的忽略规则和例外,它们不会包含在构建上下文中,因此不会打包到存档中并上传到 Docker 服务器。
使用多步构建工具,构建和运行所需要的环境不同
通过多阶段构建,您可以在 Dockerfile 中使用多个FROM语句。每条FROM指令都可以使用不同的基础镜像,它们中的每一条都开始了构建的新阶段。您可以选择性地将文件从一个阶段复制到另一个阶段,从而在其中留下您不想要的一切。
使用最小权限用户
如果 Dockerfile 中没有指定 USER ,Docker 默认将会以超级用户 root 的身份运行容器,容器所属的命名空间(namespace)因此镜像为 root 用户所拥有,这意味着容器有可能获取 Docker 宿主系统的超级管理权限。不仅如此,以 root 用户身份运行容器,还扩大了攻击面,如果容器应用中存在安全漏洞,很容易造成权限提升。
在实践中,一般不需要容器拥有 root 权限。为了尽量降低安全威胁,创建专门的用户和用户组,在 Dockerfile 中使用 USER 指定用户,确保以最小权限的用户身份运行容器应用。
如果基础镜像中不包含专门的用户,那么就在 Dockerfile 中直接创建一个普通用户。
扫描镜像是否有安全问题
docker 本地镜像的漏洞扫描允许开发人员和开发团队查看容器镜像的安全状态,并采取措施修复扫描期间发现的问题,从而实现更安全的部署。Docker Scan 在 Snyk 引擎上运行,为用户提供对其本地 Dockerfile 和本地映像的安全状况的可见性。
用户通过 CLI 触发漏洞扫描,并使用 CLI 查看扫描结果。扫描结果包含常见漏洞和暴露 (CVE) 列表、源(例如操作系统包和库)、引入它们的版本以及用于修复发现的 CVE 的推荐修复版本(如果可用).
通常,镜像扫描通过解析容器镜像文件中定义的包或其他依赖项来工作,然后检查这些包或依赖项中是否存在任何已知漏洞。