# Docker 面试总览:镜像、容器与可复现交付
⚡ 30 秒速记
- 镜像是只读分层文件系统加运行配置,容器是镜像启动后的隔离进程;容器不是轻量虚拟机的同义词
- 隔离主要来自 Linux
namespace,资源限制与统计来自cgroup,分层文件系统负责镜像复用和容器可写层 Dockerfile的核心是可复现与缓存:固定依赖、缩小 build context、先复制低频文件、使用多阶段构建- 容器可写层应视为临时数据;数据库和用户文件放
volume/ 外部存储,配置与密钥在运行时注入 - 生产质量还要回答非 root 用户、健康检查、优雅退出、资源上限、镜像扫描和日志去向
镜像是只读分层文件系统和运行配置,容器则是基于镜像启动的隔离进程,不能简单等同于轻量虚拟机。 容器通过 namespace 隔离视图,用 cgroup 管理资源,但仍与宿主机共享内核。构建时我会固定依赖、缩小上下文并采用多阶段构建,让缓存和交付结果更稳定。生产中还要把持久数据外置,并处理非 root、SIGTERM、资源上限、日志和镜像安全等问题。
镜像由一组不可变层和元数据组成,容器启动时在其上增加可写层并创建受隔离的进程。namespace 分隔进程号、网络、挂载点等视图,cgroup 控制 CPU、内存等资源;宿主与容器仍共享内核,所以镜像能比完整虚拟机更小、启动更快,也意味着内核漏洞和过高权限需要认真防护。
一份可维护的前端镜像通常使用多阶段构建:构建阶段安装完整依赖并产出静态文件或 Next.js standalone 包,运行阶段只复制产物和生产依赖。依赖清单应先于源码复制,这样日常改业务代码时还能复用安装层;.dockerignore 则避免把 .git、本地缓存和密钥送进 build context。latest 不能提供可追溯性,发布应使用不可变 tag 或 digest。
容器删除后可写层会消失,因此持久数据必须外置。服务发现应使用容器网络里的服务名,不能把某次分配的 IP 写死。进程还要正确处理 SIGTERM:先停止接收请求,等待存量请求结束,再在编排器的宽限期内退出;否则“镜像能跑”不等于“能安全发布”。
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json yarn.lock ./
RUN corepack enable && yarn install --immutable
COPY . .
RUN yarn build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
USER node
COPY --from=build --chown=node:node /app/.next/standalone ./
COPY --from=build --chown=node:node /app/.next/static ./.next/static
CMD ["node", "server.js"]