1.Docker 安装与核心概念

2026年5月3日 Nginx_Docker 17 分钟阅读 17 次阅读
📖 文章摘要

从零讲解 Docker 核心概念(镜像、容器、卷、网络),附 Ubuntu 环境完整安装步骤与常用命令速查表,适合入门学习。

Docker 安装与核心概念

一、Docker 是什么

Docker 是一个容器化工具,让你把应用和它的所有依赖打包到一个"容器"里,在任何地方都能运行。

类比:你把一道菜的所有食材、调料、锅具打包成一个箱子,搬到任何厨房都能直接做出来,不用担心"这个厨房没有酱油"的问题。


二、核心概念

镜像(Image)

只读的模板,用来创建容器。

类比:

  • 镜像 = 一张光盘(ISO 安装盘)
  • 容器 = 用这张光盘装好的、正在运行的操作系统

你可以从网上下载别人做好的镜像(比如 python:3.11、nginx:latest),也可以自己用 Dockerfile 制作镜像。

镜像的特点:

  • 只读——你不能改镜像里面的东西,只能在容器里改
  • 可以叠加——比如基于 python:3.11 镜像,再加上你的代码,变成一个新的镜像
  • 可以分发——你做好的镜像可以给别人用

容器(Container)

镜像的运行实例,一个独立的小环境。

类比:

  • 容器 = 用光盘装好的、正在运行的操作系统
  • 你可以同时运行多个容器,每个容器互相隔离

容器的特点:

  • 可读写——你可以在容器里创建文件、修改配置
  • 临时的——容器删了,里面的数据就没了(除非用了卷)
  • 隔离的——容器 A 里的操作不影响容器 B

Dockerfile

制作镜像的配方。

你写一个文本文件,告诉 Docker:

  • 基于什么镜像(FROM)
  • 复制哪些文件进去(COPY)
  • 执行什么命令(RUN)
  • 启动时运行什么(CMD)

Docker 读这个文件,自动帮你构建出一个镜像。

卷(Volume)

让容器里的数据持久化。

容器删了数据就没了,但如果你把一个目录"挂载"到容器外面,数据就存在宿主机上,容器删了数据还在。

宿主机目录 /data  ←→  容器目录 /app/data

类比:容器是临时租的房子,卷是你自己买的 U 盘——搬走房子(删容器),U 盘(数据)还在。

它们的关系

Dockerfile(配方)
    ↓ docker build
镜像(光盘)
    ↓ docker run
容器(正在运行的系统)
    ↑
  用卷挂载数据(持久化)

三、Docker 安装(Ubuntu)

方式一:使用国内镜像源(推荐)

# 1. 安装依赖工具
sudo apt install -y ca-certificates curl gnupg
# ca-certificates:系统 SSL 安全证书,用于安全下载 Docker 官方文件
# curl:网络下载工具,用来拉取 Docker 官方密钥、源文件
# gnupg:加密签名工具,校验 Docker 软件包真伪,防止篡改

# 2. 添加 Docker 的 GPG 密钥(让 apt 信任 Docker 的软件包)
sudo mkdir -p /etc/apt/keyrings
# -p核心参数:
# 如果 /etc/apt/keyrings 文件夹不存在 → 自动逐层创建;
# /etc/apt/keyrings
# 路径含义:Ubuntu 系统存放第三方软件源加密密钥的标准目录。

curl -fsSL https://mirrors.tencentyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# -f:下载失败直接抛出错误,不会静默卡住;
# -s:静默模式,不打印下载进度、多余日志;
# -L:自动跟随网址重定向;
# gpg:加密校验工具;
# --dearmor:转换格式,把网页下载的文本密钥,转为 apt 软件源能识别的二进制密钥文件;
# -o = output 输出,把转换完成的密钥保存到第一步创建的目录里,文件名叫 docker.gpg。

# 3. 添加 Docker 的 apt 源(用国内镜像)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tencentyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# deb:声明这是 Debian/Ubuntu 二进制软件源(安装程序包用);
# [arch=$(dpkg --print-architecture)]:自动识别服务器架构(amd64/arm64),适配 x86、ARM 机器;
# signed-by=/etc/apt/keyrings/docker.gpg:指定用刚才导入的密钥校验本软件源所有安装包;
# 中间网址:国内 Docker 镜像源,比官方海外源下载速度快很多;
# $(lsb_release -cs):自动读取系统 Ubuntu 版本代号(jammy/focal 等),不用手动改版本;
# stable:稳定版 Docker 分支,不装测试、开发版。

# 4. 更新索引并安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# docker-ce:Docker 核心引擎,容器运行底层服务;
# docker-ce-cli:Docker 命令行工具,你敲docker xxx全靠它;
# containerd.io:容器运行时,管理容器生命周期;
# docker-compose-plugin:多容器编排插件,开发必备;

# 5. 把当前用户加入 docker 组(以后不用每次 sudo)
sudo usermod -aG docker $USER
newgrp docker
# -G:附加附加用户组(不是登录主组)
# -a:append 追加;不能省略
# 不加 -a 只写 -G 会清空你用户原本所有附加组,造成权限丢失
# newgrp:
# new group,临时切换当前终端会话的用户组环境。
# docker:
# 切换到 docker 用户组。

# 6. 验证安装
docker run hello-world

方式二:使用官方一键脚本

# 阿里云镜像
curl -fsSL https://get.docker.com | sudo sh -s -- --mirror Aliyun
# 或 Azure 中国镜像
curl -fsSL https://get.docker.com | sudo sh -s -- --mirror AzureChinaCloud

安装过程踩坑记录

  1. apt install docker.io 报错 containerd.io : Conflicts: containerd

    • 原因:Ubuntu 自带的 docker.io 包跟已安装的 containerd.io 冲突
    • 解决:不要用 docker.io,用 Docker 官方源安装 docker-ce
  2. curl get.docker.com 连接被重置

    • 原因:服务器无法直接访问 Docker 官网
    • 解决:使用国内镜像源
  3. docker 命令需要 sudo

    • 原因:普通用户不在 docker 组
    • 解决:sudo usermod -aG docker $USER 然后 newgrp docker

四、Docker 常用命令

镜像相关

# 查看本地所有镜像
docker images

# 搜索远程镜像
docker search nginx

# 拉取镜像(从 Docker Hub 下载)
docker pull nginx:latest
docker pull python:3.11-slim

# 删除镜像
docker rmi 镜像名:标签

容器相关

# 创建并启动容器
docker run -d -p 80:80 nginx
# -d 后台运行
# -p 宿主机端口:容器端口

# 查看运行中的容器
docker ps

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

# 停止容器
docker stop 容器名/容器ID

# 启动已停止的容器
docker start 容器名/容器ID

# 删除容器(必须先停止)
docker rm 容器名/容器ID

# 强制删除运行中的容器
docker rm -f 容器名/容器ID

# 查看容器日志
docker logs 容器名
docker logs -f 容器名    # 实时跟踪

# 进入容器内部
docker exec -it 容器名 bash

# 查看容器资源使用
docker stats

构建相关

# 从 Dockerfile 构建镜像
docker build -t 镜像名:标签 .
# -t 指定镜像名称和标签
# . 表示当前目录(Dockerfile 所在目录)

卷相关

# 运行容器时挂载卷
docker run -d -v 宿主机路径:容器路径 镜像名
# 例:docker run -d -v /data/blog:/app/data blog-api

# 命名卷(Docker 管理的卷)
docker volume create mydata
docker run -d -v mydata:/app/data 镜像名

清理相关

# 删除所有已停止的容器
docker container prune

# 删除所有未使用的镜像
docker image prune

# 删除所有未使用的数据(容器+镜像+卷)
docker system prune -a

五、Docker 网络

Docker 会自动创建一个虚拟网络,容器之间可以通过容器名互相访问。

# 查看 Docker 网络
docker network ls

# 运行两个容器在同一个网络
docker network create mynet
docker run -d --name api --network mynet 镜像名
docker run -d --name web --network mynet 镜像名

# 在 web 容器里可以通过 http://api 访问 api 容器

六、Docker vs 虚拟机

对比 Docker 容器 虚拟机
启动速度 秒级 分钟级
镜像大小 MB 级 GB 级
性能 接近原生 有损耗
隔离级别 进程级 OS 级
内核 共享宿主机内核 独立内核

面试常问:Docker 和虚拟机的区别?
答:Docker 容器共享宿主机内核,启动快、占用资源少;虚拟机有独立内核,隔离性更强但更重。Docker 适合微服务和快速部署,虚拟机适合需要强隔离的场景。


七、Dockerfile 基础语法

# 基础镜像
FROM python:3.11-slim

# 设置工作目录
WORKDIR /app

# 复制文件到容器
COPY requirements.txt .
COPY . .

# 执行命令(构建时执行)
RUN pip install -r requirements.txt

# 暴露端口(声明,不是实际映射)
EXPOSE 8001

# 启动命令(容器运行时执行)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"]

常用指令

指令 作用 示例
FROM 指定基础镜像 FROM python:3.11-slim
WORKDIR 设置工作目录 WORKDIR /app
COPY 复制文件到容器 COPY . .
RUN 构建时执行命令 RUN pip install -r requirements.txt
EXPOSE 声明端口 EXPOSE 8001
CMD 容器启动命令 CMD ["uvicorn", "main:app"]
ENV 设置环境变量 ENV PYTHONUNBUFFERED=1
ARG 构建时的变量 ARG VERSION=1.0

指令类比

指令 类比 说明
FROM 买一台新电脑 选择一个操作系统和预装环境
WORKDIR 设定工作区 cd到某个目录
COPY 拷文件进去 把代码和数据复制到镜像
RUN 装软件、配环境 执行一次性的安装和配置
CMD 设置开机启动 容器启动时自动运行的命令
EXPOSE 告诉别人端口号 声明应用监听哪个端口

分层缓存机制

Dockerfile 的每条指令都会创建一层。Docker 会缓存每一层,如果某一层没有变化,就用缓存而不是重新构建。

# 这样写更好——先复制依赖文件,再复制代码
COPY requirements.txt .     # 只要 requirements.txt 没变,这一层就用缓存
RUN pip install -r requirements.txt
COPY . .                    # 代码变了只重建这一层

如果写反了(先 COPY . . 再 RUN pip install),每次代码改动都会重新安装依赖,很慢。


八、docker-compose 基础

什么是 docker-compose

用一个 YAML 文件定义多个容器,一条命令全部启动。

类比:Docker 是一个厨师做一道菜,docker-compose 是一份菜谱,告诉多个厨师分别做什么,一起端上来。

基本格式

version: '3'
services:
  后端服务名:
    build: ./backend
    ports:
      - "8001:8001"
    volumes:
      - ./data:/app/data
    restart: always

  前端服务名:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - 后端服务名
    restart: always

常用命令

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

# 停止所有服务
docker-compose down

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

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

常用配置项

配置 作用
build 指定 Dockerfile 所在目录
ports 端口映射(宿主机:容器)
volumes 卷挂载(宿主机:容器)
environment 环境变量
depends_on 启动顺序依赖
restart 重启策略(always/on-failure/no)
networks 指定网络

九、问答

Q:Docker 和虚拟机的区别?
Docker 容器共享宿主机内核,启动快(秒级)、占用资源少(MB级);虚拟机有独立内核,启动慢(分钟级)、占用资源多(GB级)。Docker 适合微服务和快速部署,虚拟机适合需要强隔离的场景。

Q:镜像和容器的区别?
镜像是只读模板,容器是镜像的运行实例。一个镜像可以创建多个容器,容器之间互相隔离。类比:镜像=光盘,容器=用光盘装好的操作系统。

Q:Dockerfile 中 COPY 和 ADD 的区别?
COPY 只做简单复制。ADD 除了复制还能自动解压 tar 包、支持 URL 下载。一般用 COPY 就够了,需要解压时才用 ADD。

Q:数据持久化怎么做?
用 -v 参数挂载卷:docker run -v 宿主机路径:容器路径。容器删了数据还在宿主机上。也可以用命名卷(docker volume create)让 Docker 管理。

Q:docker-compose 是什么?
用一个 YAML 文件定义多个容器的启动配置,一条 docker-compose up 命令全部启动。适合需要多个服务协作的场景(比如前端+后端+数据库)。

Q:Dockerfile 的分层缓存是什么?
Dockerfile 每条指令创建一层,Docker 会缓存每一层。如果某层没变化就用缓存,不重新构建。所以要把不常变的指令(如安装依赖)放前面,常变的(如复制代码)放后面。

文章创建于:2026年5月3日CC BY-NC-SA 4.0

评论

暂无评论,来写第一条吧

别老叽霸扫描爆破后台了,个人博客能存啥有价值的东西,有这时间不如去扫俩放片的网站