Skip to content

工程实践与常见问题

这篇笔记聚焦 Docker 在真实项目里最常见的工程问题。

很多人第一次接触 Docker,会停留在:

  1. 会拉镜像
  2. 会启动容器
  3. 会写最简单的 Dockerfile

但项目里真正拉开差距的,通常不是“能不能跑起来”,而是:

  1. 镜像是否可维护
  2. 配置如何管理
  3. 日志怎么处理
  4. 容器异常后怎么排查
  5. 哪些东西该放进镜像,哪些不该放

1. 项目里为什么要关心镜像大小

镜像过大,带来的问题通常不只是“看起来不优雅”。

它会直接影响:

  1. 构建耗时
  2. 推送耗时
  3. 拉取耗时
  4. 存储成本
  5. 安全面

所以工程里常见的优化方向包括:

  1. 选更小的基础镜像
  2. 使用多阶段构建
  3. 避免把无关文件打进镜像
  4. 清理构建过程中的临时产物

2. .dockerignore 是什么,为什么很重要

.dockerignore 可以理解成 告诉 Docker 在构建镜像时,哪些文件不要带进构建上下文

它解决的是:

  1. 无关文件进入镜像构建过程
  2. 构建上下文过大
  3. 本地缓存和敏感文件被意外打包

例如常见会忽略:

text
node_modules
dist
.git
.env
logs

这里要特别注意:

.env 这类文件如果被直接打进镜像,后续镜像一旦被推送或共享,就可能造成敏感信息泄露。


3. 配置应该怎么注入

项目里很容易犯的错误是:把所有环境配置都直接写死在镜像里。

这会让镜像和环境强耦合。

更常见的工程思路是:

  1. 镜像尽量保持通用
  2. 环境差异通过环境变量或挂载配置注入
  3. 不同环境尽量复用同一份镜像

这里的 环境变量注入 可以理解成 容器启动时,由外部传入运行参数,而不是把这些参数提前写死在镜像中


4. 日志为什么通常建议输出到标准输出

很多容器化应用会强调:应用日志优先输出到 stdout 和 stderr。

这是因为容器环境里更常见的思路是:

  1. 应用负责输出日志
  2. 容器平台负责采集日志
  3. 日志系统再统一存储、检索和分析

如果应用在容器里自己写本地文件日志,就会马上遇到:

  1. 日志文件位置不好统一管理
  2. 容器销毁后日志难保留
  3. 多容器环境下日志采集复杂

5. 为什么有些文件不应该放进镜像

以下内容通常不应该轻易打进镜像:

  1. 本地开发缓存
  2. 调试用日志
  3. 私钥和证书原件
  4. .env 敏感配置
  5. 不必要的源码和历史产物

这不仅会让镜像变大,还可能带来安全问题。


6. 容器异常了,最常见的排查思路是什么

可以优先按这个顺序看:

  1. 容器是否启动成功
  2. 主进程是否退出
  3. 日志里有没有报错
  4. 端口映射是否正确
  5. 环境变量是否注入成功
  6. 外部依赖是否可连通
  7. 挂载目录权限是否正常

这里的 主进程 可以理解成 容器启动后最核心、最前台的那个进程

Docker 容器的生命周期,通常就是跟着这个主进程走的。
如果主进程退出,容器往往也会结束。


7. 为什么“容器秒退”是高频问题

因为很多初学者会误以为:容器只要启动过一次,就应该一直在后台存在。

其实不对。

容器是否持续运行,取决于它的主进程是否仍在前台运行。
如果你启动的只是一个很快执行完的命令,容器就会立刻退出。


8. Docker Compose 在这里扮演什么角色

Docker Compose 可以理解成 用一份声明式配置,同时定义和启动多个相关容器

它适合:

  1. 本地开发环境
  2. 多服务联调
  3. 应用、数据库、缓存一起拉起

它解决的是 多个容器之间如何一起启动、共享网络、共享卷和注入配置


9. 一个典型的 Compose 示例

yaml
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: dev
    depends_on:
      - redis

  redis:
    image: redis:7
    ports:
      - "6379:6379"

这份配置表达的是:

  1. 启动一个应用服务
  2. 启动一个 Redis 服务
  3. 应用依赖 Redis
  4. 通过声明式方式把本地联调环境一起描述出来

10. 项目里最常见的几类误区

10.1 误区一:镜像里写死所有环境配置

这样会让镜像难以复用,也会让环境切换变得笨重。

10.2 误区二:只要容器能跑起来,就算容器化完成

真正完整的容器化还要关注:

  1. 构建效率
  2. 配置管理
  3. 日志治理
  4. 数据持久化
  5. 安全边界

10.3 误区三:把 Docker 当成 Kubernetes 的替代品

两者不是同一个层次的问题。

Docker 更偏单机容器运行和镜像交付,
Kubernetes 更偏集群编排和容器调度治理。


11. 一句话总结

Docker 的工程实践,真正要解决的不是“把程序塞进容器里”,而是:

如何把镜像构建、配置注入、日志输出、问题排查和多容器协作都变成一套可维护、可交付、可演进的工程流程。

基于 VitePress 构建的个人技术笔记。