docker入门
核心概念
- 容器(Container):轻量化的运行实例,包含应用代码、运行时环境和依赖库。基于镜像创建,与其他容器隔离,共享主机操作系统内核(比虚拟机更高效)。
- 镜像(Image):只读模板,定义了容器的运行环境(如操作系统、软件配置等)。通过分层存储(Layer)优化空间和构建速度。
- Dockerfile:文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等)。
- 仓库(Registry):存储和分发镜像的平台,如 Docker Hub(官方公共仓库)或私有仓库(如 Harbor)。

和k8s的关系:Docker 和 Kubernetes(K8s)是互补但不同层级的容器技术,它们的关系可以用“Docker 是造砖的,K8s 是用砖盖楼的”来比喻。
常见误解澄清
误解1: "K8s会替代Docker"
事实: 不,它们是不同层级的工具。就像"GitHub不会替代Git"
误解2: "K8s必须使用Docker"
事实: K8s通过CRI接口支持多种运行时,Docker只是选项之一
误解3: "小项目不需要K8s"
事实: 正确。单机/少数容器用Docker Compose足够
容器通信机制:
容器与宿主机及外部的通信,主要通过三种机制实现:网络(Network)、端口映射(Port Publishing) 和 存储卷(Volume)。
1. 网络 - 容器间的通信
Docker 提供了多种网络驱动,创建不同的网络环境:
- bridge(桥接网络): 默认网络。Docker 会为容器创建一个虚拟交换机(
docker0),每个容器分配一个内部 IP(如172.17.0.2)。同 bridge 网络下的容器可以通过容器名或 IP 直接通信。与宿主机隔离。 - host(主机网络): 容器直接使用宿主机的网络命名空间,不进行网络隔离。容器对外暴露的端口直接使用宿主机的端口。性能最好,但安全性最低,端口容易冲突。
- none(无网络): 禁用所有网络,容器只有一个回环地址(
127.0.0.1)。用于极度强调安全或特殊定制的场景。
关键点: 如果你想部署一个 Web 应用(如 Nginx)和一个数据库(如 MySQL)并让它们互通,最常用的做法就是创建一个自定义的 bridge 网络,然后把两个容器都加入这个网络。这样,Nginx 容器就可以直接用 mysql 这个容器名来访问 MySQL 容器,无需知道其内部 IP。
2. 端口映射 - 容器与外部世界的通信
这是让外部(宿主机或其他主机)能够访问容器内服务的关键。
- 原理: 将宿主机的一个端口(如
3306)映射到容器的另一个端口(如3306)。 - 命令: 使用
-p或--publish参数。-p 8080:80:将宿主机的8080端口映射到容器的80端口。-p 3306:3306:将宿主机的3306端口映射到容器的3306端口。
- 效果: 当外部用户访问
<宿主机IP>:8080时,流量会被自动转发到容器的80端口。
3. 存储卷 - 数据持久化
容器本身是易变的,容器被删除,其内部的文件系统也会被删除。为了持久化数据(如数据库文件、配置文件、日志),必须使用存储卷。
- Bind Mount(绑定挂载): 将宿主机的一个特定目录或文件直接挂载到容器中。两者实时同步。
- Volume(卷): 由 Docker 完全管理的存储方式。卷创建在宿主机的某个区域(通常是
/var/lib/docker/volumes/),但最佳实践是通过 Docker 命令来操作它,而不是直接操作宿主机的文件。更推荐这种方式,因为它更便携、更易备份和迁移。
常用命令:
好的,Docker 的常用命令是使用它的基础。我们可以将这些命令分为几大类来理解和记忆。
---
### 一、镜像管理命令
镜像是创建容器的模板。
| 命令 | 说明 | 示例 |
| :--- | :--- | :--- |
| `docker images` | **列出本地已下载的镜像** | `docker images` |
| `docker pull <镜像名:标签>` | **从仓库拉取(下载)镜像** | `docker pull nginx:alpine` |
| `docker rmi <镜像ID或名>` | **删除本地镜像** | `docker rmi nginx:alpine` |
| `docker image prune` | **删除所有未被使用的镜像(悬空镜像)** | `docker image prune -a` |
| `docker build -t <标签> .` | **根据 Dockerfile 构建镜像** (`-t` 用于给镜像打标签) | `docker build -t my-app:1.0 .` |
| `docker search <关键词>` | **在 Docker Hub 上搜索镜像** | `docker search mysql` |
---
### 二、容器生命周期管理命令
容器是镜像的运行实例。
| 命令 | 说明 | 示例 |
| :--- | :--- | :--- |
| `docker run [选项] <镜像>` | **创建并启动一个新容器** | `docker run -d --name my-nginx nginx` |
| `docker start <容器>` | **启动一个已停止的容器** | `docker start my-nginx` |
| `docker stop <容器>` | **停止一个运行中的容器**(发送 SIGTERM,优雅停止) | `docker stop my-nginx` |
| `docker restart <容器>` | **重启容器** | `docker restart my-nginx` |
| `docker pause/unpause <容器>` | **暂停/恢复容器的所有进程** | `docker pause my-nginx` |
| `docker rm <容器>` | **删除一个已停止的容器** | `docker rm my-nginx` |
| `docker rm -f <容器>` | **强制删除一个容器(包括运行中的)** | `docker rm -f my-nginx` |
| `docker container prune` | **删除所有已停止的容器** | `docker container prune` |
| `docker exec [选项] <容器> <命令>` | **在正在运行的容器中执行命令** | `docker exec -it my-nginx bash` |
| `docker update <选项> <容器>` | **更新容器的配置(如内存、CPU)** | `docker update --memory 512m my-nginx` |
---
### 三、容器查询与查看命令
用于查看容器状态和日志。
| 命令 | 说明 | 示例 |
| :--- | :--- | :--- |
| `docker ps` | **列出正在运行的容器** | `docker ps` |
| `docker ps -a` | **列出所有容器(包括已停止的)** | `docker ps -a` |
| `docker logs [选项] <容器>` | **查看容器的日志输出** | `docker logs my-nginx` |
| `docker logs -f <容器>` | **实时追踪(follow)日志输出** | `docker logs -f my-nginx` |
| `docker top <容器>` | **查看容器内运行的进程** | `docker top my-nginx` |
| `docker stats` | **实时显示所有容器的资源使用情况(CPU、内存等)** | `docker stats` |
| `docker inspect <容器或镜像>` | **获取容器或镜像的底层详细信息(JSON格式)** | `docker inspect my-nginx` |
| `docker port <容器>` | **查看容器的端口映射情况** | `docker port my-nginx` |
---
### 四、网络管理命令
用于管理容器网络。
| 命令 | 说明 | 示例 |
| :--- | :--- | :--- |
| `docker network ls` | **列出所有网络** | `docker network ls` |
| `docker network create <网络名>` | **创建一个新的网络(默认是bridge驱动)** | `docker network create my-net` |
| `docker network inspect <网络名>` | **查看网络的详细信息** | `docker network inspect bridge` |
| `docker network connect <网络> <容器>` | **将容器连接到某个网络** | `docker network connect my-net my-nginx` |
| `docker network disconnect <网络> <容器>` | **将容器从某个网络断开** | `docker network disconnect my-net my-nginx` |
| `docker network prune` | **删除所有未被使用的网络** | `docker network prune` |
---
### 五、数据卷管理命令
用于管理持久化数据。
| 命令 | 说明 | 示例 |
| :--- | :--- | :--- |
| `docker volume ls` | **列出所有数据卷** | `docker volume ls` |
| `docker volume create <卷名>` | **创建一个数据卷** | `docker volume create my-data` |
| `docker volume inspect <卷名>` | **查看数据卷的详细信息** | `docker volume inspect my-data` |
| `docker volume rm <卷名>` | **删除一个数据卷** | `docker volume rm my-data` |
| `docker volume prune` | **删除所有未被使用的数据卷** | `docker volume prune` |
---
### 六、组合命令与系统信息
| 命令 | 说明 | 示例 |
| :--- | :--- | :--- |
| `docker system df` | **查看 Docker 的磁盘使用情况(镜像、容器、卷)** | `docker system df` |
| `docker system prune -a` | **彻底清理(删除所有停止的容器、所有网络、所有悬空镜像、所有构建缓存)** **慎用!** | `docker system prune -a` |
| `docker version` | **显示 Docker 版本信息** | `docker version` |
| `docker info` | **显示 Docker 系统范围的信息** | `docker info` |
---
### 核心 `docker run` 选项详解
这是最复杂也是最重要的命令,其常用选项总结如下:
| 选项 | 简写 | 说明 | 示例 |
| :--- | :--- | :--- | :--- |
| `--detach` | `-d` | 在后台运行容器 | `-d` |
| `--interactive --tty` | `-it` | 以**交互模式**运行容器,通常与 `bash` 等命令连用 | `-it ubuntu bash` |
| `--publish` | `-p` | 映射端口 `宿主机端口:容器端口` | `-p 8080:80` |
| `--volume` | `-v` | 挂载数据卷或目录 `宿主机目录:容器目录` 或 `卷名:容器目录` | `-v /opt/data:/data` |
| `--env` | `-e` | 设置环境变量 | `-e MYSQL_ROOT_PASSWORD=123` |
| `--name` | | 为容器指定一个名称 | `--name my-web` |
| `--rm` | | 容器停止后**自动删除**它(常用于测试) | `--rm` |
| `--network` | | 将容器连接到指定网络 | `--network my-net` |
| `--restart` | | 设置重启策略(如 `always`, `unless-stopped`) | `--restart unless-stopped` |
### 实战记忆:一个完整的例子
部署一个 Nginx 网站并更新它:
1. **拉取镜像**:`docker pull nginx:alpine`
2. **运行容器**:
```bash
docker run -d \
--name my-web \
-p 80:80 \
-v $(pwd)/html:/usr/share/nginx/html \ # 挂载本地html目录
nginx:alpine
```
3. **查看状态**:`docker ps`
4. **查看日志**:`docker logs my-web`
5. **进入容器**:`docker exec -it my-web /bin/sh` (Alpine 镜像用 `sh`, Ubuntu 用 `bash`)
6. **修改本地 `html` 目录下的文件**,浏览器刷新即可看到变化。
7. **停止容器**:`docker stop my-web`
8. **删除容器**:`docker rm my-web`
希望这个分类总结能帮助你更好地记忆和使用 Docker 命令!
容器之间访问可以通过分配的内部IP,或者docker network,这样通过“域名”就能互相访问
容器如果出现异常,通过docker logs 来查看
最佳实践:
通过镜像说明,依次配置端口、文件映射、数据映射、配置信息

启动示例:
# 启动一个MySQL数据库容器 docker run -d \ # 后台运行 --name mysql_db \ # 指定容器名 -p 3306:3306 \ # 端口映射 -e MYSQL_ROOT_PASSWORD=secret \ # 设置root密码环境变量 -e MYSQL_DATABASE=myapp \ # 设置初始化数据库环境变量 -v mysql_data:/var/lib/mysql \ # 挂载volume持久化数据 --restart unless-stopped \ # 设置自动重启策略 -m 1g \ # 限制内存为1GB mysql:8.0 # 镜像名:标签
简化多容器应用的神器
好的,我们来详细讲讲 Docker Compose。
### 什么是 Docker Compose?
Docker Compose 是一个用于**定义和运行多容器 Docker 应用程序的工具**。你可以使用一个 YAML 文件(通常是 `docker-compose.yml`)来配置你的应用所需的所有服务(容器)、网络、数据卷等。然后,只需一个简单的命令,就可以根据配置创建并启动所有服务。
简单来说,如果 `docker run` 是手动挡,需要你一个个地配置和启动容器,那么 Docker Compose 就是自动挡,让你用一个“脚本”来自动化完成所有繁琐的步骤。
---
### 为什么需要 Docker Compose?
想象一下,一个典型的 Web 应用可能包含以下服务:
1. 一个用 Python/Node.js 写的应用容器
2. 一个 Nginx 反向代理容器
3. 一个 Redis 缓存容器
4. 一个 PostgreSQL 数据库容器
如果使用 `docker run`,你需要为每个容器编写冗长且复杂的命令,并确保它们之间的网络连接正确。这非常容易出错且难以管理。
**Docker Compose 解决了这个问题:**
* **一键启停**:一条命令启动或停止整个应用栈。
* **配置即代码**:将整个应用的环境(服务、网络、存储)定义在一个文件中,易于版本控制和共享。
* **服务依赖**:可以明确指定服务之间的依赖关系,确保服务按正确顺序启动。
* **环境隔离**:每个项目使用独立的 `docker-compose.yml`,互不干扰。
---
### 核心概念与工作流程
1. **定义一个 `docker-compose.yml` 文件**:这是核心,你在这里描述应用所需的全部基础设施。
2. **运行 `docker-compose up`**:Compose 会读取 YML 文件,自动为你完成:
* 构建或拉取镜像
* 创建网络(默认会为你的项目创建一个独立网络,所有服务都在其中,可以通过服务名互相访问)
* 创建数据卷
* 启动所有容器
3. **运行 `docker-compose down`**:停止并删除所有由 `up` 创建的容器、网络。
---
### `docker-compose.yml` 文件结构详解
一个典型的 Compose 文件包含以下主要部分:
```yaml
# 版本号(通常与Docker Engine版本对应,现代推荐使用'3.8'或以上,或省略版本使用最新语法)
version: '3.8'
# 定义所有服务(容器)
services:
# 服务名称:webapp
webapp:
# 构建镜像的上下文路径,Compose会基于此路径下的Dockerfile构建镜像
build: .
# 容器启动后执行的命令(可覆盖Dockerfile中的CMD)
command: python app.py
# 端口映射
ports:
- "5000:5000"
# 挂载数据卷,将本地代码目录挂载到容器,实现代码实时同步(用于开发)
volumes:
- .:/code
# 环境变量
environment:
- REDIS_HOST=redis
# 声明依赖,确保redis服务先于webapp启动
depends_on:
- redis
# 服务名称:redis
redis:
# 直接使用Docker Hub上的官方镜像
image: "redis:alpine"
# 挂载数据卷,持久化Redis数据
volumes:
- redis_data:/data
# 定义数据卷,所有服务都可以使用
volumes:
redis_data:
```
---
### 最常用的 Docker Compose 命令
| 命令 | 作用 |
| :--- | :--- |
| `docker-compose up` | 创建并启动所有服务。**如果终端在前台,可以用 `Ctrl+C` 停止。** |
| `docker-compose up -d` | **在后台(守护进程模式)** 创建并启动所有服务。 |
| `docker-compose down` | **停止并移除**所有容器、网络(默认不会移除数据卷)。 |
| `docker-compose down -v` | **停止并移除所有容器、网络,同时移除数据卷**(危险操作!)。 |
| `docker-compose ps` | 列出本项目相关的所有容器。 |
| `docker-compose logs` | 查看所有服务的日志输出。 |
| `docker-compose logs [service-name]` | 查看某个特定服务的日志(如 `docker-compose logs webapp`)。 |
| `docker-compose exec [service-name] [command]` | 在正在运行的容器中执行命令(如 `docker-compose exec webapp bash`)。 |
| `docker-compose build` | 重新构建服务的镜像(如果你修改了Dockerfile)。 |
| `docker-compose stop` | 停止所有服务,但**不删除**容器。 |
| `docker-compose start` | 启动之前被停止的服务。 |
| `docker-compose restart` | 重启所有服务。 |
---
### 实战示例:部署一个 WordPress 博客
用 `docker run` 部署 WordPress 非常复杂,但用 Compose 却异常简单。
1. **创建项目目录并进入**:
```bash
mkdir my-wordpress-site
cd my-wordpress-site
```
2. **创建 `docker-compose.yml` 文件**:
```yaml
version: '3.8'
services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: some_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: some_wordpress_password
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: some_wordpress_password
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
volumes:
db_data:
wp_data:
```
3. **一键启动**:
```bash
docker-compose up -d
```
现在,打开浏览器访问 `http://localhost:8000`,你就可以看到 WordPress 的安装界面了!整个环境(MySQL + WordPress)已经全部就绪。
4. **停止并清理**:
```bash
docker-compose down
# 或者,如果你想保留数据以便下次使用,就不要加 -v
docker-compose down -v
```
### 总结
| 特性 | `docker run` | `docker-compose` |
| :--- | :--- | :--- |
| **适用场景** | 运行单个容器,快速测试 | 定义和运行**多容器**复杂应用 |
| **配置方式** | 冗长的命令行参数 | 清晰、可版本化的 YAML 文件 |
| **网络管理** | 需要手动创建和连接网络 | **自动创建项目网络**,服务可通过名称直接通信 |
| **依赖管理** | 无,需手动控制启动顺序 | 通过 `depends_on` 声明依赖关系 |
| **效率** | 低,尤其对于多容器应用 | **高,一键部署和销毁整个环境** |
**总而言之,Docker Compose 是开发、测试和部署多容器应用的绝对利器,它极大简化了容器编排的复杂性,是每个 Docker 使用者都必须掌握的核心工具。** 它是学习更复杂的编排工具(如 Kubernetes)前非常好的铺垫。
yml配置文件示例:
# 必须使用空格进行缩进,冒号后面必须有一个空格。 # 1. 版本 (键值对) version: '3.8' # 2. 服务 (键值对,值是一个复杂的映射/字典) services: # 3. 服务项 ‘web’ (键),值是一个映射 web: # 4. ‘build’ 键的值是字符串 ‘.’ build: . # 5. ‘ports’ 键的值是一个列表 ports: - "5000:5000" # 6. 列表项是字符串 # 7. ‘environment’ 键的值是一个映射 environment: DEBUG: "true" # 8. 映射中的键值对 # 另一个服务 ‘redis’ redis: image: "redis:alpine" # 键值对 # 9. ‘volumes’ 键的值是一个映射 (这里定义了一个命名卷) volumes: # 一个名为 ‘db-data’ 的卷,使用空映射 {} 表示默认配置 db-data: {}

浙公网安备 33010602011771号