当前位置:首页 > 学习笔记 > 正文内容

Docker 入门到实战教程

廖万里12小时前学习笔记1

# Docker 入门到实战教程

前言

Docker 是当今最流行的容器化技术,它彻底改变了软件开发和部署的方式。无论是开发环境搭建、微服务架构,还是持续集成/持续部署(CI/CD),Docker 都扮演着至关重要的角色。

本教程将从 Docker 的基本概念讲起,逐步深入到镜像构建、容器编排、网络配置等高级主题,并通过大量实战案例帮助你掌握 Docker 的核心技能。

---

第一章:Docker 简介

1.1 什么是 Docker

Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖打包到一个可移植的容器中,然后在任何支持 Docker 的环境中运行。

核心概念:

  • 镜像(Image):只读模板,包含运行应用所需的代码、库、环境变量和配置文件
  • 容器(Container):镜像的运行实例,是一个轻量级的、独立的可执行软件包
  • 仓库(Registry):存储和分发镜像的地方,如 Docker Hub

1.2 Docker vs 虚拟机

| 特性 | Docker 容器 | 传统虚拟机 | |------|------------|-----------| | 启动速度 | 秒级 | 分钟级 | | 资源占用 | MB 级 | GB 级 | | 性能 | 接近原生 | 有损耗 | | 隔离性 | 进程级 | 操作系统级 | | 可移植性 | 极高 | 较低 |

1.3 Docker 的优势

1. 一致性:消除"在我电脑上能运行"的问题 2. 轻量级:相比虚拟机,更节省资源 3. 快速部署:秒级启动,加快开发和部署周期 4. 版本控制:镜像可以进行版本管理 5. 隔离性:容器之间相互隔离,互不影响

---

第二章:Docker 安装

2.1 Linux 安装

Ubuntu/Debian:

# 更新软件包索引
sudo apt-get update

# 安装依赖 sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 设置仓库 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 启动 Docker sudo systemctl start docker sudo systemctl enable docker

# 验证安装 sudo docker --version

CentOS/RHEL:

# 安装依赖
sudo yum install -y yum-utils

# 添加 Docker 仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装 Docker sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 启动 Docker sudo systemctl start docker sudo systemctl enable docker

# 验证安装 sudo docker --version

2.2 Windows 安装

1. 下载 Docker Desktop for Windows:https://www.docker.com/products/docker-desktop 2. 运行安装程序,按提示完成安装 3. 安装完成后重启电脑 4. 启动 Docker Desktop,等待启动完成

⚠️ 注意:Windows 需要启用 WSL 2 或 Hyper-V

2.3 macOS 安装

# 使用 Homebrew 安装
brew install --cask docker

# 或手动下载 Docker Desktop for Mac # https://www.docker.com/products/docker-desktop

2.4 配置国内镜像加速

# 编辑 Docker 配置文件
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"
  ]
}
EOF

# 重启 Docker sudo systemctl daemon-reload sudo systemctl restart docker

---

第三章:Docker 基础命令

3.1 镜像管理

搜索镜像:

# 搜索镜像
docker search nginx

# 搜索官方镜像 docker search --filter=is-official=true nginx

拉取镜像:

# 拉取最新版本
docker pull nginx

# 拉取指定版本 docker pull nginx:1.24

# 查看本地镜像 docker images

# 镜像详细信息 docker inspect nginx:1.24

删除镜像:

# 删除镜像
docker rmi nginx:1.24

# 强制删除(如果镜像被容器使用) docker rmi -f nginx:1.24

# 清理悬空镜像 docker image prune

# 清理所有未使用的镜像 docker image prune -a

导出/导入镜像:

# 导出镜像
docker save -o nginx.tar nginx:1.24

# 导入镜像 docker load -i nginx.tar

3.2 容器生命周期管理

创建并启动容器:

# 基本启动
docker run nginx

# 后台运行 docker run -d nginx

# 指定名称 docker run -d --name my-nginx nginx

# 端口映射 docker run -d --name my-nginx -p 8080:80 nginx

# 目录挂载 docker run -d --name my-nginx -p 8080:80 -v /host/html:/usr/share/nginx/html nginx

# 环境变量 docker run -d --name my-mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0

查看容器:

# 查看运行中的容器
docker ps

# 查看所有容器(包括停止的) docker ps -a

# 查看容器详细信息 docker inspect my-nginx

# 查看容器资源使用情况 docker stats my-nginx

容器操作:

# 停止容器
docker stop my-nginx

# 启动已停止的容器 docker start my-nginx

# 重启容器 docker restart my-nginx

# 暂停/恢复容器 docker pause my-nginx docker unpause 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

# 查看最后 100 行日志 docker logs --tail 100 my-nginx

3.3 容器与主机文件传输

# 从主机复制文件到容器
docker cp /host/file.txt my-nginx:/container/path/

# 从容器复制文件到主机 docker cp my-nginx:/container/path/file.txt /host/path/

---

第四章:Dockerfile 详解

4.1 Dockerfile 基础

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

常用指令:

| 指令 | 说明 | |------|------| | FROM | 指定基础镜像 | | LABEL | 添加元数据 | | RUN | 执行命令 | | CMD | 容器启动时执行的命令 | | ENTRYPOINT | 配置容器入口点 | | EXPOSE | 声明端口 | | ENV | 设置环境变量 | | ADD | 复制文件并解压 | | COPY | 复制文件 | | VOLUME | 创建挂载点 | | WORKDIR | 设置工作目录 | | USER | 指定运行用户 |

4.2 编写 Dockerfile

示例:构建 Python Web 应用

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

# 设置工作目录 WORKDIR /app

# 设置环境变量 ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ TZ=Asia/Shanghai

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

# 安装依赖 RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

# 复制项目文件 COPY . .

# 声明端口 EXPOSE 8000

# 启动命令 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

示例:构建 Node.js 应用

# 多阶段构建
# 构建阶段
FROM node:18-alpine AS builder

WORKDIR /app COPY package*.json ./ RUN npm ci --registry=https://registry.npmmirror.com COPY . . RUN npm run build

# 运行阶段 FROM nginx:alpine

# 复制构建产物 COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]

4.3 构建镜像

# 基本构建
docker build -t my-python-app .

# 指定 Dockerfile 路径 docker build -t my-python-app -f Dockerfile.dev .

# 指定标签 docker build -t my-python-app:v1.0 .

# 构建时传递参数 docker build -t my-python-app --build-arg NODE_ENV=production .

# 使用缓存加速构建 docker build -t my-python-app --cache-from my-python-app:latest .

---

第五章:Docker Compose 实战

5.1 Docker Compose 简介

Docker Compose 是用于定义和运行多容器应用的工具。通过一个 YAML 文件配置应用的服务,然后使用单个命令创建和启动所有服务。

5.2 docker-compose.yml 文件结构

version: '3.8'  # Compose 文件版本

services: # 定义服务 web: # 服务名称 build: . # 构建配置 ports: # 端口映射 - "8000:8000" volumes: # 数据卷挂载 - .:/app environment: # 环境变量 - DEBUG=1 depends_on: # 依赖关系 - db - redis networks: # 网络配置 - app-network

db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: myapp volumes: - db-data:/var/lib/mysql networks: - app-network

redis: image: redis:7-alpine networks: - app-network

volumes: # 定义数据卷 db-data:

networks: # 定义网络 app-network: driver: bridge

5.3 完整实战:部署 Web 应用栈

项目结构:

my-web-app/
├── docker-compose.yml
├── backend/
│   ├── Dockerfile
│   ├── app.py
│   └── requirements.txt
├── frontend/
│   ├── Dockerfile
│   └── dist/
└── nginx/
    └── nginx.conf

docker-compose.yml:

version: '3.8'

services: # 后端服务 backend: build: ./backend container_name: my-backend restart: always environment: - DATABASE_URL=postgresql://user:password@db:5432/myapp - REDIS_URL=redis://redis:6379/0 - SECRET_KEY=your-secret-key depends_on: db: condition: service_healthy redis: condition: service_started networks: - app-network volumes: - ./backend:/app - backend-data:/app/data

# 前端服务 frontend: build: ./frontend container_name: my-frontend restart: always ports: - "80:80" depends_on: - backend networks: - app-network

# 数据库服务 db: image: postgres:15-alpine container_name: my-postgres restart: always environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: myapp volumes: - db-data:/var/lib/postgresql/data networks: - app-network healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d myapp"] interval: 10s timeout: 5s retries: 5

# 缓存服务 redis: image: redis:7-alpine container_name: my-redis restart: always command: redis-server --appendonly yes volumes: - redis-data:/data networks: - app-network

volumes: db-data: redis-data: backend-data:

networks: app-network: driver: bridge

Docker Compose 常用命令:

# 启动所有服务
docker compose up -d

# 查看服务状态 docker compose ps

# 查看日志 docker compose logs

# 查看指定服务日志 docker compose logs backend

# 实时查看日志 docker compose logs -f

# 停止所有服务 docker compose stop

# 启动所有服务 docker compose start

# 重启所有服务 docker compose restart

# 停止并删除所有服务 docker compose down

# 停止并删除所有服务和数据卷 docker compose down -v

# 进入容器 docker compose exec backend /bin/bash

# 重新构建镜像 docker compose build

# 重新构建并启动 docker compose up -d --build

---

第六章:Docker 网络管理

6.1 网络类型

Docker 提供了多种网络驱动:

| 网络类型 | 说明 | |---------|------| | bridge | 默认网络,容器间通过 IP 通信 | | host | 容器使用主机网络,无网络隔离 | | none | 无网络 | | overlay | 跨主机网络,用于 Swarm 集群 | | macvlan | 为容器分配 MAC 地址,像物理设备 |

6.2 自定义网络

# 创建网络
docker network create my-network

# 指定网络类型 docker network create -d bridge my-bridge-network

# 创建子网 docker network create --subnet=172.20.0.0/16 my-network

# 查看网络 docker network ls

# 查看网络详情 docker network inspect my-network

# 连接容器到网络 docker network connect my-network my-container

# 断开容器网络 docker network disconnect my-network my-container

# 删除网络 docker network rm my-network

6.3 容器间通信

# 创建网络
docker network create app-network

# 启动数据库容器 docker run -d --name db --network app-network \ -e POSTGRES_PASSWORD=password postgres:15

# 启动应用容器 docker run -d --name app --network app-network \ -e DATABASE_URL=postgres://postgres:password@db:5432/myapp \ my-app

# 在 app 容器中可以通过容器名 "db" 访问数据库

---

第七章:Docker 数据管理

7.1 数据卷(Volume)

数据卷是 Docker 管理的数据存储方式,独立于容器生命周期。

# 创建数据卷
docker volume create my-volume

# 查看数据卷 docker volume ls

# 查看数据卷详情 docker volume inspect my-volume

# 使用数据卷 docker run -d --name nginx -v my-volume:/usr/share/nginx/html nginx

# 删除数据卷 docker volume rm my-volume

# 清理未使用的数据卷 docker volume prune

7.2 绑定挂载(Bind Mount)

绑定挂载将主机目录挂载到容器中。

# 绑定挂载
docker run -d --name nginx \
  -v /host/path:/container/path \
  nginx

# 只读挂载 docker run -d --name nginx \ -v /host/path:/container/path:ro \ nginx

7.3 tmpfs 挂载

tmpfs 挂载将数据存储在内存中,适合敏感数据。

# tmpfs 挂载
docker run -d --name nginx \
  --tmpfs /run \
  nginx

---

第八章:Docker 实战案例

8.1 部署 LNMP 环境

version: '3.8'

services: nginx: image: nginx:alpine container_name: lnmp-nginx ports: - "80:80" - "443:443" volumes: - ./www:/usr/share/nginx/html - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/ssl:/etc/nginx/ssl depends_on: - php networks: - lnmp-network

php: build: context: ./php dockerfile: Dockerfile container_name: lnmp-php volumes: - ./www:/usr/share/nginx/html networks: - lnmp-network

mysql: image: mysql:8.0 container_name: lnmp-mysql environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: myapp volumes: - mysql-data:/var/lib/mysql - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf networks: - lnmp-network

redis: image: redis:7-alpine container_name: lnmp-redis volumes: - redis-data:/data networks: - lnmp-network

volumes: mysql-data: redis-data:

networks: lnmp-network: driver: bridge

8.2 部署监控栈(Prometheus + Grafana)

version: '3.8'

services: prometheus: image: prom/prometheus:latest container_name: prometheus ports: - "9090:9090" volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' networks: - monitor-network

grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana-data:/var/lib/grafana depends_on: - prometheus networks: - monitor-network

node-exporter: image: prom/node-exporter:latest container_name: node-exporter ports: - "9100:9100" networks: - monitor-network

cadvisor: image: gcr.io/cadvisor/cadvisor:latest container_name: cadvisor ports: - "8080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:rw - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro networks: - monitor-network

volumes: prometheus-data: grafana-data:

networks: monitor-network: driver: bridge

8.3 CI/CD 流水线示例

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables: IMAGE_NAME: my-app REGISTRY: registry.example.com

build: stage: build script: - docker build -t $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA . - docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA

test: stage: test script: - docker run --rm $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA npm test

deploy: stage: deploy script: - docker pull $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA - docker tag $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA $REGISTRY/$IMAGE_NAME:latest - docker push $REGISTRY/$IMAGE_NAME:latest - ssh deploy@server "cd /app && docker compose pull && docker compose up -d" only: - main

---

第九章:Docker 最佳实践

9.1 镜像优化

1. 使用多阶段构建:

# 构建阶段
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

# 运行阶段 FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/myapp . CMD ["./myapp"]

2. 使用小型基础镜像:

# 推荐
FROM alpine:latest
FROM node:18-alpine
FROM python:3.11-slim

# 避免 FROM ubuntu:latest FROM node:18

3. 合并 RUN 指令:

# 推荐
RUN apt-get update && apt-get install -y \
    package1 \
    package2 \
    && rm -rf /var/lib/apt/lists/*

# 避免 RUN apt-get update RUN apt-get install -y package1 RUN apt-get install -y package2

9.2 安全实践

# 创建非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# 设置只读文件系统 # docker run --read-only my-image

# 限制容器资源 # docker run --memory="512m" --cpus="1" my-image

# 使用安全扫描 # docker scan my-image

9.3 日志管理

# docker-compose.yml
services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

---

总结

本教程系统讲解了 Docker 的核心概念和实战技能:

1. 基础概念:镜像、容器、仓库的理解 2. 基本操作:镜像管理、容器生命周期控制 3. Dockerfile:编写高效的镜像构建脚本 4. Docker Compose:多容器应用的编排与管理 5. 网络与存储:容器间通信和数据持久化 6. 实战部署:LNMP、监控栈、CI/CD 等典型案例

学习建议:

  • 多动手实践,在实践中加深理解
  • 关注镜像大小优化,提高部署效率
  • 学习 Kubernetes,进入容器编排进阶领域
  • 保持对 Docker 新特性的关注
Docker 是现代开发运维的必备技能,掌握它将极大提升你的开发效率。祝你学习顺利!

本文链接:https://www.kkkliao.cn/?id=648 转载需授权!

分享到:

版权声明:本文由廖万里的博客发布,如需转载请注明出处。


发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。