Docker 基础操作完全指南
目录
引言
Docker作为轻量级的容器化技术,彻底改变了应用的开发、交付和运行方式。它允许开发者将应用及其依赖打包成一个标准化的单元(容器),实现了"一次构建,随处运行"的承诺。对于初学者或需要快速查阅命令的用户来说,一份清晰的操作手册至关重要。本文旨在提供一份全面、实用的Docker基础操作指南,覆盖在线/离线场景下的核心操作。
1. 安装Docker
首先,需在系统上安装Docker引擎。请根据操作系统访问Docker官方文档获取最新、最准确的安装指南:
- Linux : 通常可通过包管理器(如
apt、yum)安装。 - macOS : 下载并安装 Docker Desktop。
- Windows : 下载并安装 Docker Desktop(需Windows 10/11 专业版/企业版/教育版,并启用 Hyper-V/WSL 2)。
验证安装
安装完成后,执行以下命令验证是否成功:
bash
docker --version
成功输出示例:Docker version 20.10.17, build 100c701(版本号可能不同)。
2. 核心概念
| 概念 | 定义 |
|---|---|
| 镜像 (Image) | 只读模板,包含创建容器所需的文件系统、代码、库、环境变量和配置,是容器的"蓝图"。 |
| 容器 (Container) | 镜像的运行实例,一个隔离的、轻量级的可运行环境,可启动、停止、移动或删除。 |
| 仓库 (Registry) | 存放镜像的仓库,公共仓库如Docker Hub,私有仓库如Harbor。 |
3. 镜像操作
3.1 搜索镜像(Docker Hub)
在Docker Hub上查找公共镜像:
bash
docker search [镜像名称] # 示例:docker search nginx(搜索nginx镜像)
3.2 拉取镜像(从仓库下载)
从远程仓库下载镜像到本地:
bash
docker pull [镜像名称]:[标签] # 示例:docker pull nginx:latest(拉取最新版nginx)
# 标签省略时默认拉取latest(最新版):docker pull redis
3.3 列出本地镜像
查看本地已存储的所有镜像(包括拉取、加载、构建的镜像):
bash
docker images # 等价于 docker image ls
输出包含镜像ID、名称、标签、大小等信息。
3.4 删除本地镜像
删除本地不需要的镜像(需先停止依赖该镜像的容器):
bash
# 单个删除(通过镜像ID或名称:标签)
docker rmi [镜像ID/名称:标签] # 示例:docker rmi nginx:latest 或 docker rmi 1234567890ab
# 批量删除所有镜像(谨慎使用!)
docker rmi $(docker images -q)
3.5 导出本地镜像为文件(备份/迁移)
将本地镜像打包为.tar文件,用于离线传输或备份:
bash
# 格式:docker save -o [输出文件路径.tar] [镜像ID/名称:标签]
docker save -o ~/backup/nginx-backup.tar nginx:latest # 示例:导出nginx到本地目录
# 批量导出多个镜像到一个文件
docker save -o multi-images.tar nginx:latest redis:6.2 mysql:8.0
- 选项
-o:指定输出文件路径(必须带.tar后缀)。
3.6 从本地镜像文件加载镜像(导入)
将离线.tar镜像文件加载到本地Docker(加载后可通过docker images查看):
bash
# 格式1:通过文件路径加载(推荐)
docker load -i ~/backup/nginx-backup.tar # 示例:加载nginx备份文件
# 格式2:省略-i,直接跟文件路径
docker load ~/backup/redis.tar
# 格式3:通过管道加载(适用于压缩包/远程传输)
cat ~/backup/mysql.tar | docker load
3.7 镜像重命名/修改标签
给本地镜像添加新标签(便于识别和使用):
bash
# 格式:docker tag [原镜像ID/名称:旧标签] [新名称:新标签]
docker tag 1234567890ab nginx:offline-v1 # 示例:给镜像ID为1234567890ab的镜像添加标签
docker tag nginx:latest nginx:test-env # 给已有镜像新增标签(原标签保留)
4. 容器操作
4.1 运行容器(基于本地镜像创建并启动)
前提 :本地已存在目标镜像(通过docker images确认)。
基于镜像创建并启动容器,核心命令:
bash
docker run [选项] [镜像名称:标签/镜像ID] [命令] [参数...]
常用选项说明
| 选项 | 作用 |
|---|---|
-d |
后台运行容器( detached mode) |
-p 宿主机端口:容器端口 |
端口映射(示例:-p 8080:80,将主机8080端口映射到容器80端口) |
-v 宿主机目录:容器目录 |
数据卷挂载(持久化数据,示例:-v ~/data:/app/data) |
--name 容器名 |
指定容器名称(避免自动生成随机名称,示例:--name my-nginx) |
--rm |
容器退出后自动删除(适用于临时容器) |
-it |
交互式运行(-i保持输入打开,-t分配终端,适用于需要进入容器操作) |
示例
bash
# 后台运行nginx容器,端口映射8080->80,命名为my-nginx
docker run -d -p 8080:80 --name my-nginx nginx:latest
# 交互式运行ubuntu容器(进入容器终端)
docker run -it --rm ubuntu:20.04 /bin/bash
4.2 列出容器
查看容器运行状态:
bash
docker ps # 查看正在运行的容器(等价于 docker container ls)
docker ps -a # 查看所有容器(包括已停止的)
docker ps -q # 只输出正在运行的容器ID(用于批量操作)
4.3 启动/停止/重启容器
bash
docker start [容器ID/名称] # 启动已停止的容器(示例:docker start my-nginx)
docker stop [容器ID/名称] # 停止运行中的容器(示例:docker stop my-nginx)
docker restart [容器ID/名称] # 重启容器(示例:docker restart my-nginx)
4.4 进入运行中的容器
进入后台运行的容器终端(执行命令、查看文件等):
bash
# 格式:docker exec -it [容器ID/名称] [终端命令]
docker exec -it my-nginx /bin/bash # 示例:进入my-nginx容器的bash终端
# 若容器无bash,用sh:docker exec -it my-redis /bin/sh
- 退出容器终端:执行
exit(容器不会停止,仅退出终端)。
4.5 查看容器日志
查看容器运行日志(排查启动失败、运行报错等问题):
bash
docker logs [容器ID/名称] # 查看全部日志
docker logs -f [容器ID/名称] # 持续跟踪日志(类似tail -f,按Ctrl+C退出)
docker logs --tail 100 [容器名] # 查看最后100行日志
4.6 删除容器
删除不需要的容器(运行中的容器需先停止或强制删除):
bash
docker rm [容器ID/名称] # 删除已停止的容器(示例:docker rm my-nginx)
docker rm -f [容器ID/名称] # 强制删除运行中的容器(谨慎使用!)
docker rm $(docker ps -aq) # 删除所有已停止的容器
5. 网络基础
Docker提供多种网络模式(默认bridge模式),用于容器间通信或容器与主机通信。
5.1 列出网络
查看Docker已创建的网络:
bash
docker network ls # 等价于 docker network list
5.2 创建自定义网络
创建自定义桥接网络(容器加入同一网络后可通过容器名通信):
bash
docker network create [网络名] # 示例:docker network create my-net
5.3 容器连接网络
bash
# 1. 创建容器时直接连接网络
docker run -d --name nginx-net --network my-net nginx:latest
# 2. 给已存在的容器连接网络
docker network connect my-net [容器名] # 示例:docker network connect my-net my-nginx
5.4 断开容器与网络的连接
bash
docker network disconnect my-net [容器名] # 示例:docker network disconnect my-net my-nginx
6. 数据管理
Docker提供两种持久化存储方式,避免容器删除后数据丢失。
6.1 命名卷(Named Volumes)
由Docker统一管理的持久化存储(推荐,无需关心主机存储路径):
bash
# 1. 创建命名卷
docker volume create [卷名] # 示例:docker volume create nginx-data
# 2. 运行容器时挂载命名卷
docker run -d -v nginx-data:/usr/share/nginx/html --name nginx-with-vol nginx:latest
# 3. 列出所有命名卷
docker volume ls
# 4. 查看卷详情(包括主机实际存储路径)
docker volume inspect nginx-data
# 5. 删除命名卷(需先停止使用该卷的容器)
docker volume rm nginx-data
6.2 绑定挂载(Bind Mounts)
将主机上的目录/文件直接挂载到容器(需指定主机绝对路径):
bash
# 格式:docker run -v [主机绝对路径]:[容器路径] [镜像名]
docker run -d -v ~/nginx/html:/usr/share/nginx/html -p 80:80 --name nginx-bind nginx:latest
- 主机路径必须是绝对路径 (示例中
~/nginx/html等价于/home/用户/nginx/html); - 容器对挂载目录的修改会实时同步到主机,反之亦然。
7. Dockerfile 与构建镜像
通过编写Dockerfile自定义镜像(适用于开发自定义应用镜像)。
7.1 简单Dockerfile示例(Python应用)
在项目根目录创建Dockerfile文件(无后缀):
dockerfile
# 1. 指定基础镜像(必填,基于已有镜像构建)
FROM python:3.9-slim
# 2. 设置容器内工作目录(后续命令均在此目录执行)
WORKDIR /app
# 3. 复制主机文件到容器(复制当前目录所有文件到容器/app目录)
COPY . .
# 4. 执行命令(安装依赖)
RUN pip install --no-cache-dir -r requirements.txt
# 5. 暴露端口(仅文档说明,运行时需-p映射)
EXPOSE 8000
# 6. 容器启动时执行的命令(必填,指定入口程序)
CMD ["python", "app.py"]
7.2 构建自定义镜像
在Dockerfile所在目录执行构建命令:
bash
# 格式:docker build -t [镜像名]:[标签] .
docker build -t my-python-app:1.0 . # 示例:构建镜像,命名为my-python-app,标签1.0
-t:指定镜像名称和标签(必填);- 末尾的
.:表示Dockerfile在当前目录(不可省略)。
7.3 基于自定义镜像启动容器
bash
docker run -d -p 8000:8000 --name my-app my-python-app:1.0
8. 常用组合命令与技巧
8.1 一键清理无用资源
bash
# 删除所有已停止的容器
docker container prune
# 删除所有未被使用的镜像(无容器引用)
docker image prune
# 删除所有未被使用的卷
docker volume prune
# 删除所有未被使用的网络
docker network prune
# 一键清理所有无用资源(容器、镜像、网络、卷,慎用!)
docker system prune -a
8.2 查看Docker资源使用情况
实时查看容器CPU、内存、网络等资源占用:
bash
docker stats # 按Ctrl+C退出
8.3 查看容器/镜像详细信息
bash
# 查看容器详细配置(网络、挂载、环境变量等)
docker inspect [容器ID/名称] # 示例:docker inspect my-nginx
# 查看镜像详细信息
docker inspect [镜像ID/名称:标签] # 示例:docker inspect nginx:latest
8.4 批量停止所有运行中的容器
bash
docker stop $(docker ps -q)
9. 常见问题 (FAQ)
Q1: 执行Docker命令提示Got permission denied?
原因 :当前用户无Docker操作权限。
解决:
bash
# 将用户加入docker用户组(永久生效)
sudo usermod -aG docker $USER
# 退出当前终端,重新登录后生效
- 临时解决方案:用
sudo执行Docker命令(不推荐,如sudo docker run ...)。
Q2: 端口映射时提示"端口已被占用"?
解决:
-
更换宿主机端口(示例:将
-p 8080:80改为-p 8081:80); -
查找并停止占用端口的进程(Linux/macOS):
bashsudo lsof -i :8080 # 查找占用8080端口的进程 sudo kill -9 [进程PID] # 停止进程
Q3: 容器启动后立即退出?
原因 :容器内主进程(CMD/ENTRYPOINT指定)执行完毕或报错。
排查:
bash
docker logs [容器ID/名称] # 查看容器日志,定位报错原因
- 常见解决:确保
CMD/ENTRYPOINT指定的进程是前台运行(如避免nohup等后台命令)。
Q4: 数据卷中的数据在容器删除后还存在吗?
存在 :命名卷(docker volume create)和绑定挂载(主机目录)的数- 据会持久化,不受容器生命周期影响;
不存在:未挂载存储的容器内部文件系统修改,会随容器删除而丢失。
Q5: 如何离线迁移容器(含数据)?
-
导出镜像:
docker save -o 镜像.tar 镜像名:标签; -
备份数据卷(若使用命名卷):
bash# 查看卷存储路径:docker volume inspect 卷名 → "Mountpoint"字段 # 复制路径下的文件到备份目录:cp -r /var/lib/docker/volumes/卷名/_data ~/backup/卷数据/ -
将镜像文件和卷数据复制到目标机器;
-
目标机器加载镜像:
docker load -i 镜像.tar; -
恢复数据卷:
bashdocker volume create 卷名 # 创建同名卷 cp -r ~/backup/卷数据/* /var/lib/docker/volumes/卷名/_data/ # 覆盖卷数据 -
启动容器(挂载恢复的卷)。