Docker简介

在进行软件开发或评测时,经常会遇到这样的情况:一个项目 “在我电脑上能正常运行”,可测试、运维人员部署到服务器后,却频频出现环境不一致、依赖缺失、配置冲突等问题,导致无法复现出想要的结果。Docker 作为云原生时代不可或缺的基础设施,重构了现代软件的开发、交付与部署范式,彻底解决了“环境不一致”这一长期困扰开发者和运维人员的痛点。

Docker 是一款开源的应用容器引擎,诞生于 2013 年,最初由 dotCloud 公司(后更名为 Docker Inc)研发并开源,基于 Linux 内核的底层技术实现,如今已跨平台支持 Windows、macOS 等主流操作系统。

通俗来说,Docker 就像一个 “应用打包箱”:它可以将你的应用代码、运行环境、依赖库、配置文件等所有运行所需的内容,全部打包到一个标准化的 “容器” 中。这个容器具备极强的可移植性,无论你是在本地笔记本、测试服务器,还是公有云、私有云的主机上,都能实现一次构建,到处运行,彻底抹平2不同环境之间的差异,让软件交付不再受限于具体的操作系统和硬件配置。

Docker 与虚拟机的区别

在使用 Docker 时,我们往往需要拉取操作系统的镜像(例如 Ubuntu 系统),很多新手这时会产生疑问:连操作系统的镜像都要拉取,这与虚拟机的区别在哪里?

事实上,Docker 拉取的系统镜像并不包含系统内核。从技术本质来看,Docker 实现的是操作系统级虚拟化,区别于传统的硬件级虚拟机技术。虚拟机需要虚拟出完整的操作系统内核、硬件资源(CPU、内存、磁盘等),再在其上安装应用;而 Docker 直接共享宿主机的操作系统内核,仅为应用隔离出独立的运行空间,这也是它极致轻量、高效的核心原因。

相比于虚拟机,Docker 的优势十分显著:

  • 启动速度:Docker 秒级启动,虚拟机则需数分钟启动
  • 资源占用:单个容器仅占用 MB 级体积,虚拟机通常需 GB 级资源
  • 跨平台兼容性:Docker 跨平台适配更灵活,虚拟机受虚拟化平台限制
  • 性能表现:Docker 性能与宿主机原生性能几乎一致,虚拟机存在一定性能损耗

Docker 镜像的“一次构建,到处运行”特性更是新手需重点掌握的核心。很多新手每换一台机器运行,都重新构建 Docker 镜像,反复拉取软件镜像耗费大量时间,这完全不必要。构建好的镜像可推送到 Docker Hub 或其他镜像仓库,也可打包为压缩包,在其他机器直接下载运行,大幅提升交付效率。

什么是云原生

云原生(Cloud Native)是云原生计算基金会(CNCF)定义的一套架构理念、技术栈与工程实践体系,核心是让应用从设计之初就适配公有云、私有云、混合云等动态环境,充分利用云的弹性、分布式与自动化能力,而非简单将传统应用“搬上云”。

云原生以容器化(如 Docker)、微服务、Kubernetes 编排、服务网格、不可变基础设施、声明式 API 为核心技术,配合 DevOps 与 CI/CD 流程,实现应用快速迭代、弹性伸缩、故障自愈与高效运维,最终让系统更敏捷、可靠、易扩展,是现代云架构下应用开发与部署的主流模式。

Docker 的三大核心概念

1. 镜像(Image):容器的“标准化模板”

Docker 镜像是一个只读的模板文件,包含了应用运行所需的代码、运行环境、依赖库、环境变量、配置文件等所有内容,是创建 Docker 容器的基础。

镜像具备分层存储特性,基于联合文件系统(UnionFS)实现,一个镜像可由多个只读层叠加而成。例如构建 Java 应用镜像,可基于 Ubuntu 基础镜像,叠加 JDK 环境层,再叠加 Spring Boot 应用层。

分层存储的核心优势是层复用:多个镜像可共享同一基础层,大幅节省磁盘空间;同时镜像推送、拉取时仅需传输变更的层,极大提升传输和存储效率。

2. 容器(Container):镜像的运行实例

容器是镜像运行时的实体,是基于镜像创建的、独立的可读写运行环境。若将镜比作“类”,容器就是类的“实例对象”。

每个容器都拥有独立的文件系统、网络空间、进程空间,容器与容器之间、容器与宿主机之间相互隔离,互不干扰。容器的生命周期与运行的应用绑定——应用启动则容器运行,应用退出则容器停止。

默认情况下,容器内的写入操作仅在容器运行时有效,容器删除后写入的数据会随之丢失。因此生产环境中通常通过**数据卷(Volume)**实现数据的持久化存储,确保关键数据不随容器销毁而丢失。

3. 仓库(Repository):镜像的托管与分发中心

Docker 仓库是集中存储、管理、分发 Docker 镜像的平台,相当于代码领域的 GitHub/GitLab。开发者构建好镜像后,可推送到仓库中;其他环境、人员只需从仓库拉取镜像,就能直接运行对应应用,无需重复构建,实现镜像的标准化分发。

仓库分为公共仓库私有仓库两类:

  • 公共仓库:最主流的是 Docker 官方的 Docker Hub,包含海量官方镜像(如 Ubuntu、MySQL、Redis、Nginx、Python 等),开发者可直接拉取使用,无需从零构建
  • 私有仓库:企业内部通常搭建私有仓库(如 Harbor),用于存储企业内部业务镜像,保障数据安全、提升传输效率

Docker 安装

Docker 的安装流程因操作系统不同略有差异,以下是主流平台的安装方式概述:

Windows 系统

  1. 开启 Windows 虚拟化功能(Hyper-V 或 WSL2)
  2. 下载 Docker Desktop 安装包,双击运行并完成安装
  3. 启动 Docker Desktop,等待服务初始化完成即可使用

macOS 系统

  1. 下载 Docker Desktop for Mac 安装包
  2. 将 Docker 应用拖入应用文件夹,启动后完成初始化配置

Linux 系统(以 Ubuntu 为例)

  1. 更新系统包索引:
    sudo apt update && sudo apt upgrade -y
    
  2. 安装依赖包:
    sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
    
  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 Engine:
    sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io -y
    
  6. 启动 Docker 服务并设置开机自启:
    sudo systemctl start docker
    sudo systemctl enable docker
    
  7. 验证安装是否成功:
    docker --version
    

Dockerfile:镜像构建的自动化脚本

Dockerfile 是用于自动化构建 Docker 镜像的文本文件,包含了一系列指令和参数,用于定义镜像的构建步骤。通过编写 Dockerfile,我们可以标准化镜像构建流程,确保镜像的可复现性和可维护性。

常用 Dockerfile 指令

指令 作用 示例
FROM 指定基础镜像(必须为第一条指令) FROM ubuntu:22.04
RUN 执行命令(如安装依赖、编译代码等) RUN apt update && apt install -y nginx
COPY 复制本地文件/目录到镜像中 COPY ./app /app
ADD 复制文件/目录(支持解压压缩包、下载网络文件) ADD ./app.tar.gz /app
WORKDIR 设置工作目录 WORKDIR /app
EXPOSE 声明容器暴露的端口 EXPOSE 8080
ENV 设置环境变量 ENV APP_ENV=production
CMD 容器启动时执行的命令(仅可写一条,多条会被最后一条覆盖) CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT 容器入口命令(可与 CMD 配合,CMD 作为入口参数) ENTRYPOINT ["python", "app.py"]

构建镜像示例

以构建一个简单的 Nginx 镜像为例,步骤如下:

  1. 创建 Dockerfile 文件:
    # 基于官方 Nginx 镜像
    FROM nginx:latest
    # 复制自定义配置文件
    COPY ./nginx.conf /etc/nginx/conf.d/default.conf
    # 暴露 80 端口
    EXPOSE 80
    # 启动 Nginx 服务
    CMD ["nginx", "-g", "daemon off;"]
    
  2. 执行构建命令:
    docker build -t my-nginx:latest .
    
    其中 -t 用于指定镜像名称和标签(格式:名称:标签),. 表示 Dockerfile 所在目录。

docker run:运行单个容器的核心命令

docker run 是创建并启动容器的核心命令,通过参数控制容器的运行模式、网络、存储、资源等配置,命令格式为:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

该命令每次仅能启动一个容器,所有配置均通过命令行参数传入,适合快速测试、调试单个应用,但在多容器应用场景下,配置繁琐且难以维护。

基础示例

docker run -d \
  --name my-app \
  -p 8080:80 \
  -e DB_HOST=localhost \
  -v ./data:/app/data \
  --network my-net \
  my-image:latest

常用参数详解

一、运行模式
参数 说明 示例
-d / --detach 后台运行(守护进程),返回容器 ID docker run -d nginx
-it 交互模式(-i 保持输入打开 + -t 分配伪终端),用于进入容器操作 docker run -it ubuntu bash
--rm 容器退出后自动删除(适合一次性任务) docker run --rm -it ubuntu
--name 指定容器名称(默认随机生成) docker run --name my-nginx nginx
二、网络配置
参数 说明 示例
-p / --publish 指定端口映射(主机端口:容器端口),支持绑定指定地址 -p 8080:80-p 127.0.0.1:8080:80
-P / --publish-all 随机映射容器暴露的所有端口 docker run -P nginx
--network 指定容器网络(bridge/host/none/自定义网络) --network my-net
--add-host 自定义容器 hosts 映射 --add-host host.docker.internal:host-gateway
--dns 指定容器 DNS 服务器 --dns 8.8.8.8
三、存储与数据持久化
参数 说明 示例
-v / --volume 挂载主机目录/卷到容器(格式:主机路径:容器路径[:权限]) -v /host/data:/container/data:ro(ro 表示只读)
--mount 更灵活的挂载方式(推荐),支持多种挂载类型 --mount type=bind,src=/host,dst=/container
--tmpfs 挂载内存临时文件系统(数据不持久化,容器停止后丢失) --tmpfs /tmp
--read-only 将容器根文件系统设为只读(提升安全性) docker run --read-only nginx
四、环境变量
参数 说明 示例
-e / --env 设置单个环境变量 -e MYSQL_ROOT_PASSWORD=123456
--env-file 从文件加载环境变量(适合多环境变量配置) --env-file ./.env
五、资源限制
参数 说明 示例
-m / --memory 限制容器内存使用上限 -m 512m(512MB)、-m 2g(2GB)
--cpus 限制容器使用的 CPU 核心数 --cpus 1.5(1.5 核)
--ulimit 限制系统资源(如最大打开文件数) --ulimit nofile=65535:65535
六、其他常用配置
参数 说明 示例
-h / --hostname 设置容器主机名 -h my-container
-w / --workdir 指定容器工作目录 -w /app
--user 指定容器运行用户(UID 或用户名) --user 1000--user nginx
--privileged 授予容器特权模式(允许访问主机设备) docker run --privileged ubuntu
--entrypoint 覆盖镜像默认入口命令 --entrypoint /bin/sh

命令缺点

docker run 仅支持单容器运行,参数过多时难以维护且无法版本控制;多容器应用需手动管理服务依赖、网络连接等,团队协作效率低,因此实际生产中较少单独使用。

Docker Compose:多容器应用编排工具

Docker Compose 是用于管理多容器应用的工具,通过 docker-compose.yml 配置文件定义多个服务的依赖关系、网络、存储等,一条命令即可启动或停止整个应用栈,完美解决了 docker run 在多容器场景下的痛点。

核心配置文件(docker-compose.yml)

Compose 采用 YAML 格式编写配置,核心包含 versionservicesvolumes 等部分,示例如下:

# 指定 Compose 版本
version: '3.8'

# 定义服务
services:
  # 应用服务
  app:
    # 基于本地镜像
    image: my-app:latest
    # 端口映射
    ports:
      - "8080:80"
    # 环境变量
    environment:
      - DB_HOST=db
      - REDIS_HOST=redis
    # 数据卷挂载
    volumes:
      - ./app-data:/app/data
    # 依赖服务(启动顺序:db、redis → app)
    depends_on:
      - db
      - redis
    # 自定义网络
    networks:
      - app-net

  # 数据库服务
  db:
    image: postgres:16
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=app_db
    # 数据卷持久化
    volumes:
      - pg-data:/var/lib/postgresql/data
    networks:
      - app-net

  # 缓存服务
  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    networks:
      - app-net

# 定义数据卷
volumes:
  pg-data:
  redis-data:

# 定义自定义网络
networks:
  app-net:

常用 Compose 命令

# 构建所有服务的镜像(只构建,不启动)
docker compose build

# 构建并立即启动所有服务(最常用,开发必备)
docker compose up -d --build

# 只构建某个服务,不构建其他
docker compose build app

# 不使用缓存,强制重新构建(解决缓存导致构建不更新的问题)
docker compose build --no-cache

# 启动所有服务(-d 表示后台运行)
docker compose up -d

# 停止并清理容器(保留数据卷)
docker compose down

# 停止并清理容器+数据卷
docker compose down -v

# 查看所有服务日志(-f 实时跟踪)
docker compose logs -f

# 重启指定服务
docker compose restart app

# 查看服务状态
docker compose ps

Docker run 与 Docker Compose 对比

维度 docker run docker compose
容器数量 单个 多个
配置方式 命令行参数 YAML 配置文件
可维护性 差,参数繁琐 好,可纳入 Git 版本控制
服务依赖 手动管理 自动处理(depends_on)
网络配置 手动创建 自动创建共享网络
适用场景 快速测试、调试单个容器 开发环境、完整多容器应用部署

适用场景

  • docker run:临时运行工具、快速验证镜像、单容器调试
  • docker compose:任何涉及多个服务的项目(web + db + cache 等)

实际项目中几乎都用 docker compose,因为配置可复用、可共享、易维护。

常用 Docker 命令实操汇总

结合实际使用场景,这里整理了高频 Docker 命令,覆盖镜像管理、容器操作、数据持久化与系统清理,是日常开发/运维的“必备工具箱”。

一、镜像管理:构建、拉取、推送与打包

镜像作为容器的基础,是容器化的核心载体,以下是全流程操作命令:

1. 查看本地镜像
# 列出所有本地镜像(含镜像ID、仓库、标签、大小)
docker images

# 只显示镜像ID(适合脚本批量操作)
docker images -q
2. 搜索远程镜像(Docker Hub)
# 搜索指定名称的镜像(如 MySQL)
docker search mysql
3. 拉取远程镜像
# 拉取最新版镜像(等价于 mysql:latest)
docker pull mysql

# 拉取指定版本镜像(如 MySQL 8.0)
docker pull mysql:8.0
4. 构建本地镜像(通过 Dockerfile)
# 进入 Dockerfile 所在目录
cd /path/to/dockerfile/dir

# 构建镜像:-t 指定名称:标签,. 表示当前目录为构建上下文
docker build -t my-app:1.0 .

# 构建时指定镜像标签(多版本管理)
docker build -t my-app:latest -t my-app:1.0 .
5. 标记镜像(打标签/重命名)
# 格式:docker tag 原镜像:原标签 新镜像:新标签
docker tag my-app:1.0 my-registry.com/my-team/my-app:1.0
6. 推送镜像到远程仓库
# 登录私有仓库(Docker Hub 无需替换地址)
docker login my-registry.com

# 推送标记好的镜像
docker push my-registry.com/my-team/my-app:1.0

# 退出登录
docker logout my-registry.com
7. 打包/导出镜像(无网络环境传输必备)
# 打包为普通 tar 包
docker save -o my-app.tar my-app:1.0

# 打包并压缩为 gz 包(体积更小,推荐)
docker save my-app:1.0 | gzip > my-app.tar.gz

# 导入镜像到本地
docker load -i my-app.tar          # 普通 tar 包
docker load -i my-app.tar.gz        # 压缩包

二、容器管理:创建、启动、停止、进入与日志

容器是镜像的运行实例,日常操作围绕容器生命周期展开:

1. 查看容器状态
# 列出正在运行的容器
docker ps

# 列出所有容器(含停止的)
docker ps -a

# 只显示容器ID
docker ps -aq
2. 启动/停止/重启容器
# 启动容器(容器ID/名称)
docker start my-container

# 停止容器(优雅关闭,推荐)
docker stop my-container

# 强制停止容器(紧急场景,可能丢失数据)
docker kill my-container

# 重启容器
docker restart my-container
3. 进入运行中的容器
# 交互模式进入容器(分配终端+保持输入)
docker exec -it my-container /bin/bash

# 进入容器后执行单条命令(无需进入终端)
docker exec my-container ls /app
4. 查看容器日志
# 查看容器日志
docker logs my-container

# 实时跟踪日志(类似 tail -f)
docker logs -f my-container

# 查看最近100行日志
docker logs --tail 100 my-container

# 查看日志时间戳
docker logs -t my-container
5. 删除容器
# 删除停止的容器
docker rm my-container

# 强制删除运行中的容器(谨慎使用)
docker rm -f my-container

# 批量删除所有停止的容器
docker rm $(docker ps -aq)

三、数据持久化:解决容器数据丢失问题

容器默认是“临时”的,销毁后数据会丢失,因此必须通过数据卷/挂载实现持久化:

1. 挂载主机目录(bind 挂载,最常用)
# 格式:-v 主机绝对路径:容器路径[:权限]
# 示例:将主机 ./data 挂载到容器 /app/data,只读(ro)
docker run -d \
  --name my-app \
  -v ./data:/app/data:ro \
  my-app:latest
2. 使用 Docker 管理卷(Volume,推荐)
# 创建数据卷
docker volume create pg-data

# 运行容器并挂载数据卷
docker run -d \
  --name postgres \
  -v pg-data:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

# 查看数据卷详情(含主机实际存储路径)
docker volume inspect pg-data

# 批量删除无用数据卷
docker volume prune -f
3. 内存临时挂载(临时数据,不持久)
# 挂载 tmpfs 到容器 /tmp,重启后数据消失
docker run -d --tmpfs /tmp my-app:latest

四、系统清理:释放磁盘空间

Docker 长期使用会产生大量无用镜像、容器、网络,需定期清理:

1. 一键清理(推荐,安全无风险)
# 清理停止的容器、悬空镜像、未使用网络
docker system prune

# 强制清理所有无用镜像+容器+网络(更彻底)
docker system prune -a -f
2. 分维度清理
# 清理无用容器
docker container prune -f

# 清理无用镜像(悬空镜像+未使用镜像)
docker image prune -a -f

# 清理未使用网络
docker network prune -f

# 清理未使用数据卷(谨慎,会删除未挂载的卷)
docker volume prune -f

五、其他高频操作

1. 查看容器/镜像详细信息
# 查看容器详细信息(如IP、挂载卷、环境变量)
docker inspect my-container

# 查看镜像详细信息
docker inspect my-app:latest
2. 复制文件到/从容器
# 从主机复制文件到容器
docker cp /host/path/file my-container:/container/path

# 从容器复制文件到主机
docker cp my-container:/container/path/file /host/path
3. 查看容器资源占用
# 查看所有容器资源占用(CPU、内存、磁盘IO)
docker stats

# 查看指定容器资源占用
docker stats my-container

实战总结:Docker 完整工作流

一个标准的 Docker 容器化项目工作流如下:

  1. 编写 Dockerfile:定义镜像构建步骤(基础镜像、依赖、代码、启动命令)。
  2. 构建镜像:执行 docker build -t 项目名:版本 . 生成本地镜像。
  3. 本地测试:用 docker run 单容器测试,或 docker compose 多容器联调。
  4. 镜像推送:打标签后推送到私有/公共仓库,实现跨环境共享。
  5. 部署运行:在服务器拉取镜像,用 docker compose 启动服务(生产环境优先)。
  6. 日常维护:定期清理无用资源、查看容器日志、备份数据卷。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐