玩转 Docker:完整教程与实战案例分享

玩转 Docker:完整教程与实战案例分享

1. Docker 简介:容器化时代的变革者

在云计算和 DevOps 文化日益盛行的今天,Docker 已经成为了一个无法绕开的话题。作为容器化技术的代表,Docker 以其轻量、高效、可移植等特性,极大地改变了软件开发、测试和部署的流程。

1.1 什么是 Docker?

Docker 是一个开源的应用容器引擎,它允许开发者将应用及其依赖打包到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

1.2 Docker 的核心概念

  • 镜像(Image): Docker 镜像是一个只读模板,包含了运行应用程序所需的所有内容,包括代码、运行时环境、库、环境变量和配置文件。
  • 容器(Container): 容器是镜像的可运行实例。每个容器都是相互隔离的,拥有自己的文件系统、网络和进程空间。
  • 仓库(Registry): 仓库是用来存储和分发 Docker 镜像的地方。Docker Hub 是官方的公共仓库,当然你也可以搭建私有仓库。
  • Dockerfile: Dockerfile 是一个文本文件,其中包含了一系列用于构建镜像的指令。

1.3 Docker 的优势

  • 轻量级: 容器共享主机内核,无需额外的操作系统,因此非常轻量。
  • 快速启动: 容器可以在几秒钟内启动,远快于传统的虚拟机。
  • 可移植性: “一次构建,到处运行”,Docker 镜像可以在任何支持 Docker 的平台上运行。
  • 隔离性: 容器之间相互隔离,互不影响,提高了应用的安全性。
  • 版本控制: 镜像可以进行版本控制,方便回滚和管理。
  • 易于扩展: 可以通过 Docker Compose 或 Kubernetes 等工具轻松扩展容器化应用。
  • 标准化交付: Docker 提供了标准化的交付方式,保证了开发、测试、生产环境的一致性。

2. Docker 安装与配置

在开始使用 Docker 之前,首先需要在你的机器上安装 Docker。

2.1 在不同操作系统上安装 Docker

  • Linux: 大多数 Linux 发行版都提供了 Docker 的软件包。你可以参考 Docker 官方文档,根据你的发行版选择相应的安装方法。
  • Windows: Docker Desktop for Windows 提供了一个集成的 Docker 环境。
  • macOS: Docker Desktop for Mac 同样提供了一个集成的 Docker 环境。

2.2 配置 Docker 镜像加速器

由于国内访问 Docker Hub 速度较慢,建议配置镜像加速器。常见的镜像加速器有:

  • 阿里云容器镜像服务
  • DaoCloud 镜像市场
  • 网易云镜像服务

你可以在 Docker 的配置文件中(Linux 上通常是 /etc/docker/daemon.json)添加如下内容:

json
{
"registry-mirrors": ["https://your-mirror-address"]
}

https://your-mirror-address 替换为你选择的镜像加速器地址。然后重启 Docker 服务。

2.3 验证 Docker 安装

安装完成后,可以通过运行以下命令来验证 Docker 是否安装成功:

bash
docker --version
docker run hello-world

如果能够看到 Docker 版本信息,并且 hello-world 镜像能够成功运行,则说明 Docker 安装成功。

3. Docker 常用命令

掌握 Docker 的常用命令是使用 Docker 的基础。

3.1 镜像相关命令

  • docker pull <image_name>:<tag>:从仓库拉取镜像。
  • docker images:列出本地镜像。
  • docker rmi <image_id>:删除本地镜像。
  • docker build -t <image_name>:<tag> .:根据 Dockerfile 构建镜像。
  • docker tag <source_image>:<tag> <target_image>:<tag>:为镜像打标签。
  • docker push <image_name>:<tag>:将镜像推送到仓库。
  • docker search <image_name>: 搜索 Docker Hub 上的镜像。

3.2 容器相关命令

  • docker run <image_name>:<tag>:创建并启动一个容器。
  • docker ps:列出正在运行的容器。
  • docker ps -a:列出所有容器(包括已停止的)。
  • docker start <container_id>:启动一个已停止的容器。
  • docker stop <container_id>:停止一个正在运行的容器。
  • docker restart <container_id>:重启一个容器。
  • docker rm <container_id>:删除一个容器。
  • docker exec -it <container_id> bash:进入一个正在运行的容器的 shell。
  • docker logs <container_id>: 查看容器的日志。
  • docker inspect <container_id/image_id>:查看容器或镜像的详细信息。

3.3 其他常用命令

  • docker info:显示 Docker 系统信息。
  • docker version:显示 Docker 版本信息。
  • docker-compose up:(使用 Docker Compose)启动多个容器。
  • docker-compose down:(使用 Docker Compose)停止多个容器。

4. Dockerfile 编写

Dockerfile 是构建 Docker 镜像的关键。它是一个文本文件,包含了一系列用于构建镜像的指令。

4.1 Dockerfile 常用指令

  • FROM:指定基础镜像。
  • RUN:执行命令。
  • COPY:复制文件或目录到镜像中。
  • ADD:类似于 COPY,但可以自动解压压缩文件。
  • WORKDIR:设置工作目录。
  • ENV:设置环境变量。
  • EXPOSE:声明容器运行时监听的端口。
  • CMD:指定容器启动时执行的命令(只能有一个 CMD 指令,如果有多个,只有最后一个生效)。
  • ENTRYPOINT:类似于 CMD,但不会被 docker run 的命令行参数覆盖。
  • VOLUME: 声明数据卷,用于持久化数据。
  • USER: 指定运行容器的用户。

4.2 Dockerfile 最佳实践

  • 使用官方镜像作为基础镜像: 尽量使用官方维护的镜像,例如 nodepythonjava 等。
  • 精简镜像大小: 删除不必要的文件和依赖,使用多阶段构建等技术来减小镜像体积。
  • 使用 .dockerignore 文件: 忽略不需要复制到镜像中的文件和目录。
  • 合理使用缓存: Dockerfile 中的每一条指令都会创建一个新的镜像层,合理利用缓存可以加快构建速度。
  • 明确指定版本:FROM 指令中明确指定基础镜像的版本,避免因基础镜像更新导致构建失败。
  • 使用多阶段构建: 在单个 Dockerfile 中使用多个 FROM 指令。这允许你将构建环境和运行环境分离,从而显著减小最终镜像的大小。

4.3 示例 Dockerfile

```dockerfile

使用 Node.js 14 作为基础镜像

FROM node:14

设置工作目录

WORKDIR /app

复制 package.json 和 package-lock.json

COPY package*.json ./

安装依赖

RUN npm install

复制应用代码

COPY . .

暴露端口

EXPOSE 3000

启动应用

CMD ["npm", "start"]
```

5. Docker Compose:多容器应用编排

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一个 YAML 文件,你可以配置应用的服务、网络和卷,然后使用 docker-compose 命令来启动、停止和管理整个应用。

5.1 安装 Docker Compose

Docker Desktop for Windows 和 Docker Desktop for Mac 已经包含了 Docker Compose。在 Linux 上,你可以通过以下命令安装:

bash
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

5.2 编写 docker-compose.yml 文件

docker-compose.yml 文件是 Docker Compose 的核心。它使用 YAML 格式来定义应用的服务、网络和卷。

5.2.1 常用配置项

  • version:指定 docker-compose.yml 文件的版本。
  • services:定义应用的服务。
    • image:指定服务的镜像。
    • build:指定服务的构建上下文(Dockerfile 所在的目录)。
    • ports:映射端口。
    • volumes:挂载卷。
    • environment:设置环境变量。
    • depends_on:指定服务的依赖关系。
  • networks:定义网络。
  • volumes:定义卷。

5.2.2 示例 docker-compose.yml 文件

yaml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"

这个示例定义了两个服务:webredisweb 服务使用当前目录下的 Dockerfile 构建,并将容器的 5000 端口映射到主机的 5000 端口。redis 服务使用 redis:alpine 镜像。

5.3 使用 Docker Compose 管理应用

  • docker-compose up:启动应用。
  • docker-compose down:停止应用。
  • docker-compose ps:列出应用的服务。
  • docker-compose logs:查看应用服务的日志。
  • docker-compose build:构建应用的服务。
  • docker-compose exec <service_name> bash: 进入指定服务的容器。

6. Docker 实战案例

6.1 案例一:部署一个简单的 Web 应用

  1. 编写应用代码: 创建一个简单的 Python Flask 应用(app.py):

    ```python
    from flask import Flask
    app = Flask(name)

    @app.route('/')
    def hello_world():
    return 'Hello, Docker!'

    if name == 'main':
    app.run(debug=True, host='0.0.0.0')
    ```

  2. 编写 Dockerfile:

    ```dockerfile
    FROM python:3.9-slim-buster

    WORKDIR /app

    COPY requirements.txt ./
    RUN pip install --no-cache-dir -r requirements.txt

    COPY . .

    CMD ["python", "app.py"]
    ```

    requirements.txt:

    Flask==2.0.3

  3. 构建镜像:

    bash
    docker build -t my-web-app .

  4. 运行容器:

    bash
    docker run -d -p 5000:5000 my-web-app

    现在,你可以在浏览器中访问 http://localhost:5000 来查看你的应用。

6.2 案例二:使用 Docker Compose 部署一个包含 Web 应用和数据库的应用

  1. 编写应用代码: 创建一个简单的 Node.js Express 应用,连接到 MongoDB 数据库。

    ```javascript
    // app.js
    const express = require('express');
    const mongoose = require('mongoose');
    const app = express();

    mongoose.connect('mongodb://mongo:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => console.log('Connected to MongoDB'))
    .catch(err => console.error('Could not connect to MongoDB', err));

    app.get('/', (req, res) => {
    res.send('Hello from Docker Compose!');
    });

    app.listen(3000, () => {
    console.log('Server is running on port 3000');
    });

    ```

    package.json:

    json
    {
    "name": "my-app",
    "version": "1.0.0",
    "dependencies": {
    "express": "^4.17.1",
    "mongoose": "^6.0.0"
    }
    }

  2. 编写 Dockerfile:

    ```dockerfile
    FROM node:14

    WORKDIR /app

    COPY package*.json ./

    RUN npm install

    COPY . .

    CMD ["node", "app.js"]
    ```

  3. 编写 docker-compose.yml 文件:

    yaml
    version: "3.9"
    services:
    web:
    build: .
    ports:
    - "3000:3000"
    depends_on:
    - mongo
    mongo:
    image: "mongo"
    volumes:
    - mongodb_data:/data/db
    volumes:
    mongodb_data:

  4. 启动应用:

    bash
    docker-compose up

    现在,你可以在浏览器中访问 http://localhost:3000 来查看你的应用。

7. 总结与展望

Docker 作为容器化技术的领导者,已经深刻地改变了软件开发和部署的方式。通过本文的学习,你应该已经掌握了 Docker 的基本概念、常用命令、Dockerfile 编写、Docker Compose 使用以及一些实战案例。

当然,Docker 的学习之路还很长,还有很多高级特性和工具等待你去探索,例如 Docker Swarm、Kubernetes、服务网格等。希望本文能够为你打开 Docker 的大门,让你在容器化时代乘风破浪! 持续学习和实践,你会发现 Docker 的强大之处,并将其应用到你的实际工作中,提高开发效率和应用可靠性。

THE END