# 🐳 Linux Docker 完全入门指南 > 从零开始掌握容器化技术,从原理到实战一网打尽 --- ## 📚 目录 1. [Docker 是什么?](#一docker-是什么) 2. [核心概念](#二核心概念) 3. [安装 Docker](#三安装-docker) 4. [Docker 基础命令](#四docker-基础命令) 5. [镜像操作](#五镜像操作) 6. [容器操作](#六容器操作) 7. [数据持久化](#七数据持久化) 8. [网络配置](#八网络配置) 9. [Dockerfile 编写](#九dockerfile-编写) 10. [镜像打包与发布](#十镜像打包与发布) 11. [Docker Compose](#十一docker-compose) 12. [实战案例](#十二实战案例) 13. [常见问题](#十三常见问题) --- ## 一、Docker 是什么? ### 1.1 容器 vs 虚拟机 ``` ┌─────────────────────────────────────────────────────────┐ │ 传统虚拟机架构 │ ├─────────────────────────────────────────────────────────┤ │ App A │ App B │ App C │ App D │ │ Bins/ │ Bins/ │ Bins/ │ Bins/ │ │ Libs │ Libs │ Libs │ Libs │ ├─────────┴─────────┴─────────┴───────────────────────────┤ │ Guest OS │ Guest OS │ Guest OS │ Guest OS │ ├─────────────────────────────────────────────────────────┤ │ Hypervisor │ ├─────────────────────────────────────────────────────────┤ │ Host OS │ ├─────────────────────────────────────────────────────────┤ │ Hardware │ └─────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────┐ │ Docker 容器架构 │ ├─────────────────────────────────────────────────────────┤ │ App A │ App B │ App C │ App D │ │ Bins/ │ Bins/ │ Bins/ │ Bins/ │ │ Libs │ Libs │ Libs │ Libs │ ├─────────┴─────────┴─────────┴───────────────────────────┤ │ Docker Engine │ ├─────────────────────────────────────────────────────────┤ │ Host OS │ ├─────────────────────────────────────────────────────────┤ │ Hardware │ └─────────────────────────────────────────────────────────┘ ``` ### 1.2 Docker 的优势 | 特性 | 说明 | |------|------| | 🚀 **轻量级** | 容器共享宿主机内核,启动秒级 | | 📦 **一致性** | 开发、测试、生产环境完全一致 | | 🔄 **可移植** | 一次构建,到处运行 | | 📈 **易扩展** | 快速部署和水平扩展 | | 🔒 **隔离性** | 进程、网络、文件系统隔离 | ### 1.3 核心原理 Docker 利用 Linux 内核的以下特性实现容器化: - **Namespace(命名空间)**:实现进程隔离 - **Cgroups(控制组)**:实现资源限制 - **UnionFS(联合文件系统)**:实现镜像分层 --- ## 二、核心概念 ### 2.1 镜像(Image) > 只读模板,包含运行应用所需的所有内容 ``` 镜像分层结构: ┌─────────────────┐ │ 可写容器层 │ ← 容器运行时修改 ├─────────────────┤ │ 应用层 │ ← 你的应用代码 ├─────────────────┤ │ 依赖层 │ ← Python/Node/Java 等 ├─────────────────┤ │ 基础系统层 │ ← Ubuntu/Alpine 等 ├─────────────────┤ │ 引导层 │ ← bootfs └─────────────────┘ ``` ### 2.2 容器(Container) > 镜像的运行实例,可以被创建、启动、停止、删除 ``` 镜像 → 运行 → 容器 Ubuntu镜像 → docker run → 正在运行的Ubuntu容器 ``` ### 2.3 仓库(Registry) > 存储和分发镜像的地方 - **Docker Hub**:官方公共仓库 https://hub.docker.com - **阿里云镜像**:国内加速 https://cr.console.aliyun.com - **私有仓库**:Harbor、Nexus 等 --- ## 三、安装 Docker ### 3.1 一键安装脚本(推荐) ```bash # 官方安装脚本 curl -fsSL https://get.docker.com | sh # 或者使用国内镜像加速 curl -fsSL https://get.docker.com | sh -s docker --mirror Aliyun ``` ### 3.2 手动安装(Ubuntu/Debian) ```bash # 1. 更新包索引 sudo apt update # 2. 安装依赖 sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release # 3. 添加 Docker 官方 GPG 密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 4. 添加 Docker 软件源 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 5. 安装 Docker sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io # 6. 启动并设置开机自启 sudo systemctl start docker sudo systemctl enable docker # 7. 验证安装 docker --version ``` ### 3.3 配置国内镜像加速 ```bash # 创建/编辑配置文件 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] } EOF # 重启 Docker sudo systemctl daemon-reload sudo systemctl restart docker ``` ### 3.4 非 root 用户使用 Docker ```bash # 将当前用户添加到 docker 组 sudo usermod -aG docker $USER # 重新登录或执行 newgrp docker # 验证 docker ps ``` --- ## 四、Docker 基础命令 ### 4.1 帮助命令 ```bash docker --help # 查看所有命令 docker command --help # 查看具体命令帮助 docker version # 查看版本信息 docker info # 查看系统信息 ``` ### 4.2 镜像相关 ```bash # 搜索镜像 docker search nginx # 拉取镜像 docker pull nginx:latest docker pull nginx:alpine # 指定标签 # 查看本地镜像 docker images docker image ls # 删除镜像 docker rmi nginx:latest docker image rm nginx:latest # 查看镜像历史 docker history nginx # 查看镜像详情 docker inspect nginx ``` ### 4.3 容器相关 ```bash # 运行容器 docker run -d -p 80:80 --name my-nginx nginx # 查看运行中的容器 docker ps # 查看所有容器(包括停止的) docker ps -a # 停止容器 docker stop my-nginx # 启动容器 docker start my-nginx # 重启容器 docker restart my-nginx # 删除容器 docker rm my-nginx # 强制删除运行中的容器 docker rm -f my-nginx # 进入容器内部 docker exec -it my-nginx /bin/bash # 查看容器日志 docker logs my-nginx docker logs -f my-nginx # 实时跟踪 # 查看容器资源使用 docker stats my-nginx ``` --- ## 五、镜像操作 ### 5.1 从 Dockerfile 构建镜像 ```bash # 基本语法 docker build -t myapp:1.0 . # 指定 Dockerfile 路径 docker build -f /path/to/Dockerfile -t myapp:1.0 . # 不使用缓存 docker build --no-cache -t myapp:1.0 . ``` ### 5.2 镜像标签管理 ```bash # 给镜像打标签 docker tag nginx:latest myregistry/nginx:v1.0 # 推送镜像到仓库 docker push myregistry/nginx:v1.0 # 导出镜像为 tar 文件 docker save -o nginx.tar nginx:latest # 从 tar 文件导入镜像 docker load -i nginx.tar ``` ### 5.3 清理镜像 ```bash # 删除 dangling 镜像(悬空镜像) docker image prune # 删除所有未使用的镜像 docker image prune -a # 清理构建缓存 docker builder prune ``` --- ## 六、容器操作 ### 6.1 运行容器的完整参数 ```bash docker run \ -d \ # 后台运行 --name my-container \ # 指定容器名 -p 8080:80 \ # 端口映射(主机:容器) -p 127.0.0.1:8080:80 \ # 绑定特定 IP -v /host/data:/app/data \ # 挂载数据卷 -e MYSQL_ROOT_PASSWORD=123 \ # 设置环境变量 --memory=512m \ # 内存限制 --cpus=1.0 \ # CPU 限制 --restart=always \ # 自动重启策略 nginx:latest ``` ### 6.2 容器生命周期管理 ```bash # 创建但不启动 docker create --name my-nginx nginx # 启动 docker start my-nginx # 暂停 docker pause my-nginx # 恢复 docker unpause my-nginx # 停止(优雅关闭) docker stop my-nginx # 强制停止 docker kill my-nginx # 删除 docker rm my-nginx # 一键停止并删除 docker rm -f my-nginx ``` ### 6.3 容器与主机交互 ```bash # 复制文件到容器 docker cp localfile.txt my-nginx:/app/ # 从容器复制文件到主机 docker cp my-nginx:/app/file.txt ./ # 查看容器进程 docker top my-nginx # 查看容器资源使用 docker stats my-nginx # 查看容器详细信息 docker inspect my-nginx ``` --- ## 七、数据持久化 ### 7.1 数据卷(Volume) ```bash # 创建数据卷 docker volume create my-data # 查看数据卷 docker volume ls # 使用数据卷运行容器 docker run -d -v my-data:/app/data nginx # 查看数据卷详情 docker volume inspect my-data # 删除数据卷 docker volume rm my-data # 清理未使用的数据卷 docker volume prune ``` ### 7.2 绑定挂载(Bind Mount) ```bash # 挂载主机目录到容器 docker run -d \ -v /home/user/data:/app/data \ -v $(pwd)/config:/app/config \ nginx # 只读挂载 docker run -d -v /host/data:/app/data:ro nginx ``` ### 7.3 对比 | 特性 | Volume | Bind Mount | |------|--------|------------| | 位置 | Docker 管理 | 主机任意位置 | | 备份 | 容易 | 需手动处理 | | 性能 | 好 | 依赖主机文件系统 | | 移植性 | 好 | 依赖主机路径 | | 推荐场景 | 数据库、应用数据 | 配置文件、开发环境 | --- ## 八、网络配置 ### 8.1 网络模式 | 模式 | 说明 | 使用场景 | |------|------|----------| | bridge | 默认模式,容器通过网桥通信 | 大多数场景 | | host | 容器直接使用主机网络 | 性能要求高 | | none | 无网络 | 完全隔离 | | container | 共享其他容器网络 | 特殊场景 | ### 8.2 网络命令 ```bash # 查看网络列表 docker network ls # 创建网络 docker network create my-network # 查看网络详情 docker network inspect my-network # 连接容器到网络 docker network connect my-network my-container # 断开容器网络 docker network disconnect my-network my-container # 删除网络 docker network rm my-network ``` ### 8.3 容器间通信 ```bash # 创建自定义网络 docker network create my-app # 运行容器并加入网络 docker run -d --name db --network my-app mysql:8.0 docker run -d --name web --network my-app -p 8080:80 nginx # 容器间可以通过容器名互相访问 # web 容器可以直接访问 db:3306 ``` --- ## 九、Dockerfile 编写 ### 9.1 基本结构 ```dockerfile # 基础镜像 FROM ubuntu:22.04 # 设置工作目录 WORKDIR /app # 复制文件 COPY . /app # 安装依赖 RUN apt-get update && apt-get install -y \ python3 \ python3-pip \ && rm -rf /var/lib/apt/lists/* # 安装 Python 依赖 RUN pip3 install -r requirements.txt # 暴露端口 EXPOSE 8000 # 设置环境变量 ENV PYTHONUNBUFFERED=1 # 健康检查 HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:8000/health || exit 1 # 启动命令 CMD ["python3", "app.py"] ``` ### 9.2 常用指令 | 指令 | 说明 | 示例 | |------|------|------| | FROM | 指定基础镜像 | FROM python:3.9-slim | | WORKDIR | 设置工作目录 | WORKDIR /app | | COPY | 复制文件到镜像 | COPY . /app | | ADD | 类似 COPY,支持 URL 和解压 | ADD tar.gz /app | | RUN | 执行命令 | RUN apt-get update | | CMD | 容器启动时执行的命令 | CMD ["python", "app.py"] | | ENTRYPOINT | 入口点,不可被覆盖 | ENTRYPOINT ["python"] | | ENV | 设置环境变量 | ENV KEY=value | | ARG | 构建参数 | ARG VERSION=1.0 | | EXPOSE | 暴露端口 | EXPOSE 8080 | | VOLUME | 挂载点 | VOLUME ["/data"] | | USER | 指定用户 | USER nobody | | HEALTHCHECK | 健康检查 | HEALTHCHECK CMD curl... | ### 9.3 多阶段构建(减小镜像体积) ```dockerfile # 构建阶段 FROM python:3.9 AS builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt # 运行阶段 FROM python:3.9-slim WORKDIR /app # 从构建阶段复制依赖 COPY --from=builder /root/.local /root/.local COPY . . # 设置环境变量 ENV PATH=/root/.local/bin:$PATH EXPOSE 8000 CMD ["python", "app.py"] ``` ### 9.4 最佳实践 ```dockerfile # ✅ 好的做法 FROM python:3.9-slim # 先复制依赖文件,利用缓存层 COPY requirements.txt . RUN pip install -r requirements.txt # 再复制应用代码 COPY . . # 使用非 root 用户 RUN useradd -m myuser USER myuser # ❌ 避免的做法 FROM python:3.9 COPY . . # 每次代码变更都会重新安装依赖 RUN pip install -r requirements.txt ``` --- ## 十、镜像打包与发布 ### 10.1 打包镜像 ```bash # 构建镜像 docker build -t myapp:1.0 . # 查看构建历史 docker history myapp:1.0 # 查看镜像大小 docker images myapp:1.0 # 导出为 tar docker save -o myapp-1.0.tar myapp:1.0 # 压缩导出 docker save myapp:1.0 | gzip > myapp-1.0.tar.gz ``` ### 10.2 推送到 Docker Hub ```bash # 登录 docker login # 给镜像打标签(格式:用户名/镜像名:标签) docker tag myapp:1.0 username/myapp:1.0 # 推送 docker push username/myapp:1.0 # 推送 latest 标签 docker tag myapp:1.0 username/myapp:latest docker push username/myapp:latest ``` ### 10.3 推送到阿里云镜像仓库 ```bash # 登录阿里云 docker login --username=你的阿里云账号 registry.cn-hangzhou.aliyuncs.com # 打标签 docker tag myapp:1.0 registry.cn-hangzhou.aliyuncs.com/命名空间/镜像名:1.0 # 推送 docker push registry.cn-hangzhou.aliyuncs.com/命名空间/镜像名:1.0 ``` ### 10.4 私有仓库搭建(Harbor) ```bash # 使用 Docker Compose 部署 Harbor curl -fsSL https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz | tar -xz cd harbor # 配置 cp harbor.yml.tmpl harbor.yml # 编辑 harbor.yml,设置 hostname 和端口 # 安装 sudo ./install.sh # 访问 https://your-hostname ``` --- ## 十一、Docker Compose ### 11.1 什么是 Docker Compose? > 用于定义和运行多容器应用的工具,使用 YAML 文件配置。 ### 11.2 docker-compose.yml 示例 ```yaml version: '3.8' services: # Web 服务 web: build: ./web # 从 Dockerfile 构建 image: myapp/web:latest # 或直接使用镜像 container_name: my-web ports: - "8080:80" volumes: - ./web/html:/usr/share/nginx/html - web-data:/data environment: - NGINX_HOST=localhost - NGINX_PORT=80 networks: - my-network depends_on: - db restart: always healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 30s timeout: 10s retries: 3 # 数据库服务 db: image: mysql:8.0 container_name: my-db environment: MYSQL_ROOT_PASSWORD: secretpassword MYSQL_DATABASE: myapp MYSQL_USER: appuser MYSQL_PASSWORD: apppass volumes: - db-data:/var/lib/mysql - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql networks: - my-network restart: always # Redis 缓存 redis: image: redis:7-alpine container_name: my-redis volumes: - redis-data:/data networks: - my-network restart: always # 数据卷 volumes: web-data: db-data: redis-data: # 网络 networks: my-network: driver: bridge ``` ### 11.3 Docker Compose 命令 ```bash # 启动所有服务 docker-compose up -d # 停止服务 docker-compose down # 停止并删除数据卷 docker-compose down -v # 查看日志 docker-compose logs docker-compose logs -f web # 重启服务 docker-compose restart web # 重新构建并启动 docker-compose up -d --build # 查看运行状态 docker-compose ps # 执行命令 docker-compose exec web /bin/bash docker-compose exec db mysql -u root -p # 拉取最新镜像 docker-compose pull # 查看配置 docker-compose config ``` ### 11.4 环境变量配置 ```yaml # docker-compose.yml version: '3.8' services: web: image: myapp:${VERSION:-latest} environment: - DB_HOST=${DB_HOST:-db} - DB_PORT=${DB_PORT:-3306} ``` ```bash # 使用环境变量文件 docker-compose --env-file .env up -d # .env 文件 VERSION=1.0 DB_HOST=db DB_PORT=3306 ``` --- ## 十二、实战案例 ### 12.1 部署 Python Web 应用 **项目结构:** ``` myapp/ ├── docker-compose.yml ├── Dockerfile ├── requirements.txt └── app.py ``` **Dockerfile:** ```dockerfile FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "app:app"] ``` **docker-compose.yml:** ```yaml version: '3.8' services: web: build: . ports: - "8000:8000" environment: - FLASK_ENV=production restart: always ``` **部署:** ```bash # 构建并启动 docker-compose up -d --build # 查看日志 docker-compose logs -f # 更新代码后重新部署 docker-compose down docker-compose up -d --build ``` ### 12.2 部署完整 LNMP 环境 ```yaml version: '3.8' services: nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./www:/var/www/html - ./ssl:/etc/nginx/ssl depends_on: - php restart: always php: image: php:8.1-fpm volumes: - ./www:/var/www/html restart: always mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: mydb volumes: - mysql-data:/var/lib/mysql restart: always phpmyadmin: image: phpmyadmin/phpmyadmin ports: - "8080:80" environment: PMA_HOST: mysql depends_on: - mysql restart: always volumes: mysql-data: ``` ### 12.3 CI/CD 集成示例 ```yaml # .github/workflows/docker.yml name: Docker Build and Push on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Login to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and Push