4、容器化开发环境:Docker基础概念、Docker安装与配置、编写Dockerfile、使用Docker Compose编排多容器环境

说实话,搞开发最头疼的事之一,就是环境问题。

「在我机器上能跑啊!」——这句话我听了太多次了。我自己也说过不少次。后来我彻底服了,开始用 Docker。嗯,真香。

4.1 Docker 基础概念:镜像、容器、仓库

Docker 说白了,就是一个「轻量级虚拟机」。但它比虚拟机快得多,也小得多。

三个核心概念,我帮你捋清楚:

  • 镜像(Image):一个只读的模板。里面装好了操作系统、运行环境、代码。你可以把它理解成一个「安装包」。
  • 容器(Container):镜像跑起来之后,就是容器。它是可读写的,你可以进去操作、改文件。容器之间互相隔离。
  • 仓库(Registry):存放镜像的地方。最常用的是 Docker Hub,类似 GitHub 但存的是镜像。

我个人的理解方式:

镜像 = 类(Class),容器 = 实例(Instance)。

一个镜像可以启动 N 个容器,每个容器互不干扰。

我在项目中遇到过一个问题:同事用 Windows,我用 Mac,测试环境是 CentOS。三个环境,三个坑。后来统一用 Docker 镜像,再也没吵过架。

4.2 Docker 安装与配置

安装 Docker 其实不难。我分别说说主流系统怎么搞。

Linux(Ubuntu 为例)

我个人习惯用官方脚本,一行搞定:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

装完记得把当前用户加入 docker 组,不然每次都要 sudo:

sudo usermod -aG docker $USER
# 然后退出重新登录

macOS / Windows

直接去 Docker Desktop 官网下载安装包。双击安装,下一步下一步就行。

注意:Windows 用户记得开启 WSL2。我曾经因为没开 WSL2,Docker 跑起来慢得像蜗牛。开了之后,速度直接起飞。

验证安装

docker --version
docker run hello-world

看到 Hello from Docker! 就说明成了。

4.3 编写 Dockerfile

Dockerfile 就是一份「菜谱」。告诉 Docker 怎么一步步构建你的镜像。

我拿一个 Python 项目举例。你想想看,平时部署 Python 项目要装 Python、装 pip、装依赖、配环境变量……用 Dockerfile 全自动化:

# 1. 指定基础镜像
FROM python:3.11-slim

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

# 3. 复制依赖文件
COPY requirements.txt .

# 4. 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 5. 复制项目代码
COPY . .

# 6. 暴露端口
EXPOSE 8000

# 7. 启动命令
CMD ["python", "app.py"]

避坑指南:我曾经把 COPY . . 写在 RUN pip install 前面。结果每次改代码都要重新装一遍依赖,气得我直拍桌子。记住:把不常变的东西放前面,常变的放后面。这样能充分利用 Docker 的缓存机制。

构建镜像:

docker build -t my-python-app:1.0 .

跑起来:

docker run -p 8000:8000 my-python-app:1.0

4.4 使用 Docker Compose 编排多容器环境

一个项目往往不止一个服务。比如 Web 应用 + 数据库 + Redis。难道要一个个手动启动?

Docker Compose 就是干这个的。它用一个 YAML 文件,定义所有服务。然后一条命令全部启动。

一个典型的 docker-compose.yml

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
      - redis
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

启动所有服务:

docker-compose up -d

停止并清理:

docker-compose down

我个人的经验:

刚开始用 Compose 时,我总把 depends_on 当成「等数据库完全启动好」。其实它只保证启动顺序,不保证服务就绪。数据库启动需要几秒钟,这时候 Web 服务连上去会报错。

解决方案?加个 wait-for-it.sh 脚本,或者用 healthcheck。嗯,这个坑我踩过。

常用 Compose 命令

命令 作用
docker-compose up -d 后台启动所有服务
docker-compose down 停止并删除容器、网络
docker-compose logs -f 实时查看日志
docker-compose exec web bash 进入 web 容器内部
docker-compose build 重新构建镜像

小技巧:开发时可以用 docker-compose up --build,每次启动前自动重新构建镜像。省得忘了 build 导致代码没更新。

4.5 总结一下

Docker 这东西,上手不难,但用好需要积累。我建议你从一个小项目开始,把开发环境容器化。慢慢你就会发现——

「在我机器上能跑」这句话,终于不再是问题了。

最后提醒一句:别把 Docker 当万能药。它解决的是环境一致性问题,不是架构设计问题。该拆的服务还是要拆,该做的优化还是要做。


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