Docker教程从入门到精通(0基础)
📖 第一部分:核心概念与原理
1.1 什么是容器?为什么需要它?
简单来说,容器就是将应用及其所有依赖(如库、配置文件等)打包在一起的标准化单元。它解决了环境不一致带来的“在我的机器上能运行,在服务器上就不行”的经典难题。
容器与虚拟机的关键区别在于:
-
虚拟机:模拟整个操作系统(包括硬件),资源占用大,启动慢。
-
容器:共享宿主机操作系统内核,只隔离应用进程,轻量、快速,启动时间仅秒级。
| 对比维度 | 传统虚拟机 | Docker 容器 |
|---|---|---|
| 启动速度 | 分钟级 | 秒级 |
| 资源占用 | 几个GB | 几十MB |
| 隔离性 | 强隔离(完全虚拟化) | 进程级隔离 |
| 内核 | 每个VM有独立内核 | 共享宿主机内核 |
1.2 Docker的三大核心组件
理解Docker,关键是记住这三个“零件”:
-
镜像(Image):一个只读的模板,好比是安装程序的“快照”。它包含了运行一个应用所需的一切。
-
容器(Container):从镜像运行起来的实例。你可以把它看作是一个“轻量级的虚拟机”,可以被启动、停止、删除。
-
仓库(Repository):集中存放镜像的地方。最著名的是官方的Docker Hub,你可以从那里拉取(
pull)镜像,也可以推送(push)自己的镜像。
1.3 Docker是如何工作的?
Docker利用了Linux内核的底层技术来实现隔离和资源控制:
-
Namespace(命名空间):为容器创建独立的“视图”,让容器内的进程“看”不到也影响不了宿主机或其他容器,实现了隔离。
-
Cgroups(控制组):限制一个容器可以使用的CPU、内存等资源,防止某个容器耗尽宿主机资源,实现了资源限制。
-
Union File System(联合文件系统):允许镜像分层构建,使镜像更轻量、传输更快。
🛠️ 第二部分:安装与环境配置
2.1 Linux安装(以CentOS为例)
-
卸载旧版本(如果有):
-
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine ```[citation:9] -
安装依赖并添加Docker官方仓库:
bash sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo ```[citation:9] -
安装Docker引擎:
bash sudo yum install -y docker-ce docker-ce-cli containerd.io ```[citation:9] -
启动Docker并设置开机自启:
bash sudo systemctl start docker sudo systemctl enable docker ```[citation:9] -
验证安装:
bash sudo docker run hello-world看到欢迎信息即为成功。
-
(可选)让普通用户不用sudo运行docker:
bash sudo groupadd docker sudo usermod -aG docker $USER newgrp docker ```[citation:5][citation:9]
2.2 配置镜像加速器(国内必备)
由于网络原因,直接拉取镜像可能很慢,需要配置国内加速器。创建或修改/etc/docker/daemon.json文件:
json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
保存后重启Docker服务:sudo systemctl restart docker。
⌨️ 第三部分:核心命令实战
Docker的大部分操作都通过命令行(CLI)完成,掌握以下几组命令就掌握了80%的日常操作。
3.1 镜像管理(对“模板”的操作)
| 命令 | 说明 | 示例 |
|---|---|---|
docker pull |
从仓库拉取镜像 | docker pull nginx:latest |
docker images |
列出本地所有镜像 | docker images |
docker rmi |
删除指定镜像 | docker rmi <IMAGE_ID> |
docker tag |
给镜像打标签,通常用于版本管理或推送到私有仓库 | docker tag nginx:latest myrepo/nginx:v1 |
docker build |
根据Dockerfile构建镜像 | docker build -t my-app . |
3.2 容器生命周期管理(对“实例”的操作)
| 命令 | 说明 | 示例 |
|---|---|---|
docker run |
最核心的命令:创建并启动一个容器 | docker run -d --name web -p 80:80 nginx |
docker ps |
列出当前正在运行的容器 | docker ps |
docker ps -a |
列出所有容器(包括已停止的) | docker ps -a |
docker stop |
停止一个运行中的容器 | docker stop web |
docker start |
启动一个已停止的容器 | docker start web |
docker restart |
重启容器 | docker restart web |
docker rm |
删除一个已停止的容器 | docker rm web |
docker exec |
进入正在运行的容器执行命令,常用于调试 | docker exec -it web /bin/bash |
docker logs |
查看容器的输出日志 | docker logs -f web |
docker run 常用参数详解
bash
docker run -d \ # -d: 后台运行(detach)
--name web \ # 给容器起个名字
-p 8080:80 \ # 端口映射:宿主机的8080映射到容器内的80
-v /data:/usr/share/nginx/html \ # 数据卷挂载:将宿主机目录挂载到容器内
-e MYSQL_PASSWORD=123 \ # 设置环境变量
--restart=always \ # 自动重启策略
nginx:latest # 使用的镜像名和标签
[citation:9]
3.3 常用辅助命令
docker stats:实时查看所有容器的资源占用(CPU、内存等)。
docker inspect:查看一个容器或镜像的详细配置信息(IP地址、挂载卷等)。
docker system df:查看Docker占用的磁盘空间情况。
docker network ls:列出Docker的网络环境。
docker volume ls:列出数据卷列表。
📄 第四部分:使用Dockerfile定制镜像
Dockerfile是一个文本文件,包含了构建镜像所需的全部指令。通过它,你可以将应用容器化,实现环境一致性。
4.1 基本结构与指令
以一个Python Flask应用为例,Dockerfile可以这样写:
dockerfile
# 1. 指定基础镜像(Base Image)
FROM python:3.11-slim
# 2. 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
# 3. 设置工作目录
WORKDIR /app
# 4. 先复制依赖文件(利用Docker缓存,提高构建效率)
COPY requirements.txt .
# 5. 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 6. 复制应用代码
COPY . .
# 7. 创建并使用非root用户运行(提高安全性)
RUN adduser --disabled-password --gecos "" appuser
USER appuser
# 8. 声明容器运行时监听的端口
EXPOSE 5000
# 9. 指定容器启动时运行的命令
CMD ["python", "app.py"]
[citation:6]
4.2 多阶段构建(优化镜像大小)
多阶段构建可以在一个Dockerfile中使用多个FROM指令,最终只将必要的运行文件复制到最终镜像,从而极大减小体积。这对于编译型语言(如Java、Go、Rust)特别有用。
以Rust应用为例:
dockerfile
# 阶段1:构建阶段
FROM rust:1.75-slim AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
# 阶段2:运行阶段
FROM alpine:latest
WORKDIR /app
# 只从构建阶段复制编译好的二进制文件
COPY --from=builder /app/target/release/myapp .
CMD ["./myapp"]
[citation:6]
🔗 第五部分:数据持久化(Volumes)
容器是“无状态”的,容器一旦删除,内部的数据也会丢失。为了持久化数据(如数据库文件),需要将数据存储在容器外部。Docker提供了三种方式:
-
Volume(数据卷):由Docker管理,存储在宿主机特定目录下。最推荐的生产环境方式。
-
Bind Mount(挂载宿主目录):直接将宿主机上的某个目录挂载到容器内。非常适合开发环境,因为代码更改可以实时反映在容器内。
-
tmpfs Mount:数据存储在宿主机内存中,不会持久化到磁盘。用于存放临时敏感信息。
例子:使用具名Volume运行MySQL
bash
docker volume create mysql-data
docker run -d --name mysql-db \
-e MYSQL_ROOT_PASSWORD=123456 \
-v mysql-data:/var/lib/mysql \
mysql:8.0
[citation:6][citation:9]
即使删除了容器,mysql-data卷中的数据依然安全。
🌐 第六部分:网络配置
Docker容器需要与外界或容器间通信,主要网络模式如下:
-
Bridge(桥接模式):Docker默认模式。容器连接到虚拟网桥
docker0上,通过NAT(端口映射-p)访问外部。适合单机容器通信。 -
Host(主机模式):容器直接使用宿主机的网络栈,性能最好,但失去了网络隔离性。
-
None(无网络模式):容器有自己的Network Namespace,但不进行任何网络配置。需要用户手动配置,用于高度自定义的场景。
-
自定义Bridge网络:强烈推荐,它提供了内置DNS解析,容器之间可以通过容器名直接通信。
bash
# 创建自定义网络
docker network create my-net
# 运行容器并连接到该网络
docker run -d --name web --network my-net nginx
docker run -d --name app --network my-net my-app
# app容器中可以直接通过 ping web 来访问nginx容器
[citation:5][citation:12]
🚀 第七部分:多容器编排(Docker Compose)
微服务通常由多个容器组成(如App、MySQL、Redis)。docker-compose.yml文件允许你定义和运行多个容器作为一个项目。
实战示例:部署Spring Boot + MySQL + Redis
yaml
# docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: demo_db
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis:alpine
container_name: redis-cache
ports:
- "6379:6379"
app:
build: ./app # 从当前目录的Dockerfile构建
container_name: springboot-app
depends_on:
- mysql
- redis
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/demo_db?useSSL=false
SPRING_REDIS_HOST: redis
ports:
- "8080:8080"
volumes:
mysql-data:
[citation:10]
常用Compose命令:
-
docker-compose up -d:在后台启动所有服务。 -
docker-compose down:停止并移除所有容器、网络。 -
docker-compose logs -f:查看聚合日志。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)