1. 容器技术基础:Docker核心概念、镜像与容器、Dockerfile编写、Docker Compose入门

1.1 Docker核心概念:为什么我们需要容器?

说实话,我刚接触容器技术那会儿,也觉得很玄乎。不就是个轻量级虚拟机吗?后来在项目中踩过坑才明白——完全不是一回事。

Docker的核心,说白了就是进程隔离。它利用Linux内核的Namespace和Cgroups技术,让每个应用跑在独立的"沙箱"里。这个沙箱,我们叫它容器

我个人习惯把容器比作"快递盒":

  • 镜像 = 快递盒的设计图纸(只读模板)
  • 容器 = 实际打包好的快递(可读写运行实例)
  • 仓库 = 快递中转站(镜像存储分发中心)

关键区别:镜像是一个静态文件,容器是它的运行态。你可以在同一台机器上跑10个Nginx容器,它们共享同一个镜像层,但各自独立运行。

1.2 镜像与容器:从拉取到运行

我记得第一次用Docker时,最震撼的就是docker pull的速度。几秒钟就能把整个应用环境拉下来,这在传统运维里简直不敢想。

来看一个最基础的流程:

# 拉取镜像
docker pull nginx:1.21

# 查看本地镜像
docker images

# 运行容器
docker run -d --name my-nginx -p 8080:80 nginx:1.21

# 查看运行中的容器
docker ps

# 进入容器内部
docker exec -it my-nginx bash

这里有个坑,我曾经吃过亏——容器内的进程默认以root运行。这在生产环境是安全隐患。我建议你始终指定用户:

docker run -d --user 1000:1000 nginx:1.21

注意:容器停止后,数据默认会丢失。如果你需要持久化数据,一定要用-v挂载卷或--mount绑定目录。

1.3 Dockerfile编写:从零构建镜像

写Dockerfile就像写菜谱。你得告诉Docker:用什么基础原料、加什么调料、最后怎么装盘。

来看一个我项目中常用的Node.js应用Dockerfile:

# 1. 选择基础镜像
FROM node:18-alpine

# 2. 设置工作目录
WORKDIR /app

# 3. 先复制依赖文件(利用缓存加速)
COPY package*.json ./

# 4. 安装依赖
RUN npm install --production

# 5. 复制源码
COPY . .

# 6. 暴露端口
EXPOSE 3000

# 7. 启动命令
CMD ["node", "server.js"]

为什么先复制package.json再复制源码?因为Docker构建时会缓存每一层。如果源码改了但依赖没变,npm install这层就不会重新执行。嗯,这个小技巧能帮你省下不少构建时间。

我的经验:尽量用alpine版本的基础镜像。它只有5MB左右,比完整版小10倍以上。生产环境能省不少磁盘和网络开销。

1.4 Docker Compose入门:多容器编排

单个容器好办,但真实项目往往需要多个服务配合——比如Web应用+数据库+缓存。你想想看,如果每个都手动docker run,那得多累?

Docker Compose就是来解决这个问题的。它用YAML文件定义整个应用栈:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
    environment:
      - DB_HOST=db
      - REDIS_HOST=redis

  db:
    image: postgres:14-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

启动整个应用栈只需要一条命令:

docker-compose up -d

我曾经在一个微服务项目里,用Compose管理了12个服务。每次启动只需要docker-compose up,所有服务自动按依赖顺序启动。相比以前手动启动每个服务,效率提升了不止一个量级。

核心要点:Compose不是生产环境的编排工具(那是Kubernetes的事),但它对本地开发和CI/CD测试来说,绝对是最佳选择。

1.5 避坑指南:我踩过的那些坑

做容器化这几年,我总结了几条血泪教训:

  • 镜像不要太大——我曾经把一个1.5GB的镜像推到仓库,结果同事拉取时等了20分钟。后来改用多阶段构建,缩小到200MB。
  • 不要用latest标签——在项目里我坚持用具体版本号,比如nginx:1.21.6而不是nginx:latest。否则某天基础镜像更新了,你的应用可能莫名其妙挂掉。
  • 容器里不要存数据——容器随时可能被销毁重建。数据库这类有状态服务,一定要把数据挂载到宿主机或持久卷上。
  • 日志要输出到stdout/stderr——Docker默认收集标准输出作为日志。如果你把日志写到文件里,docker logs就看不到了。

嗯,这些坑我基本都踩过一遍。现在写Dockerfile时,脑子里会自动过一遍这些检查点。

1.6 本章小结

容器技术的核心就三件事:镜像构建、容器运行、编排管理。Docker让你能快速打包应用,Compose让你能轻松管理多服务。这些都是后续学习Kubernetes的基础。

下一章我们会深入Kubernetes的核心概念。到时候你会发现,很多Docker里的思路在K8s里都能找到对应——只是规模更大、能力更强。

公众号:蓝海资料掘金营,微信deep3321