Docker 从入门到上手:概念、实战与常用命令一次讲清
Docker 新手入门指南|附完整命令
在现代软件开发中,Docker 已经成为非常重要的基础工具。无论你是后端开发、前端开发、测试工程师,还是运维人员,只要涉及应用部署、环境管理、微服务开发,几乎都绕不开 Docker。
很多新手第一次接触 Docker 时,会觉得它概念很多:镜像、容器、仓库、Dockerfile、数据卷、网络、Compose……看起来复杂,但只要理解了核心思想,Docker 其实非常好上手。
本文将从零开始介绍 Docker 的基本概念、安装方式、常用命令、镜像与容器管理、数据卷、网络、Dockerfile、Docker Compose 等内容,并附上完整常用命令,帮助你快速入门 Docker。
一、什么是 Docker?
Docker 是一个开源的容器化平台,它可以将应用程序及其依赖环境打包到一个标准化的单元中,这个单元就叫做“容器”。
简单来说,Docker 可以让你做到:
在我的电脑上能运行,在你的电脑上也能运行;
在开发环境能运行,在测试、生产环境也能运行。
传统部署方式中,应用运行依赖操作系统、语言环境、系统库、配置文件等。如果开发环境和生产环境稍有不同,就可能出现各种问题,比如:
- 本地使用 JDK 17,服务器只有 JDK 8;
- 本地 MySQL 是 8.0,服务器是 5.7;
- 本地 Node.js 版本和线上版本不同;
- 某些系统依赖库没有安装;
- 配置文件路径不一致。
Docker 的出现,就是为了解决“环境不一致”的问题。
通过 Docker,我们可以把应用、依赖、配置全部打包成镜像,然后在任何支持 Docker 的机器上运行这个镜像,最终得到一致的运行环境。
二、Docker 的核心概念
学习 Docker 前,需要先理解几个核心概念。
1. 镜像 Image
镜像可以理解为一个只读模板,里面包含了应用运行所需的全部环境。
例如:
nginx镜像包含了 Nginx 服务;mysql镜像包含了 MySQL 数据库;redis镜像包含了 Redis 服务;openjdk镜像包含了 Java 运行环境;node镜像包含了 Node.js 环境。
你可以基于镜像创建容器。
可以把镜像理解为“类”,容器理解为“对象”。
2. 容器 Container
容器是镜像运行后的实例。
如果说镜像是一个安装包,那么容器就是这个安装包运行起来后的程序。
一个镜像可以创建多个容器。例如,你可以使用同一个 nginx 镜像启动多个 Nginx 容器,并让它们监听不同端口。
容器具有以下特点:
- 启动速度快;
- 占用资源少;
- 相互隔离;
- 可快速创建和删除;
- 适合部署应用和服务。
3. 仓库 Repository
仓库用于存放镜像。
最常见的公共镜像仓库是 Docker Hub:
https://hub.docker.com
你可以从 Docker Hub 拉取别人制作好的镜像,也可以把自己的镜像推送到远程仓库。
常见镜像仓库包括:
- Docker Hub;
- 阿里云容器镜像服务;
- 腾讯云容器镜像服务;
- 华为云镜像仓库;
- Harbor 私有仓库。
4. Dockerfile
Dockerfile 是用来构建镜像的脚本文件。
它里面定义了镜像的构建过程,例如:
- 使用哪个基础镜像;
- 安装哪些依赖;
- 拷贝哪些文件;
- 暴露哪些端口;
- 容器启动时执行什么命令。
通过 Dockerfile,我们可以把应用构建成自己的镜像。
5. Docker Compose
Docker Compose 是 Docker 官方提供的多容器编排工具。
当一个项目需要同时启动多个服务时,比如:
- Spring Boot 应用;
- MySQL;
- Redis;
- Nginx;
- RabbitMQ;
如果每个服务都手动执行 docker run 命令,会比较麻烦。Docker Compose 可以通过一个 docker-compose.yml 文件统一管理这些服务,一条命令即可启动或停止整个项目环境。
三、Docker 与虚拟机的区别
很多初学者会把 Docker 和虚拟机混淆。它们都可以提供隔离环境,但原理不同。
| 对比项 | Docker 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级启动 | 通常需要几十秒甚至几分钟 |
| 资源占用 | 较少 | 较多 |
| 隔离级别 | 进程级隔离 | 操作系统级隔离 |
| 是否包含完整系统 | 不包含完整操作系统 | 包含完整操作系统 |
| 镜像大小 | 通常较小 | 通常较大 |
| 使用场景 | 应用部署、微服务、开发测试 | 完整系统隔离、复杂环境模拟 |
Docker 并不是虚拟机,它是基于操作系统内核能力实现的容器技术。它比虚拟机更轻量,但隔离性通常不如虚拟机彻底。
四、Docker 安装方式
不同系统安装 Docker 的方式略有不同。
1. Windows 安装 Docker
Windows 推荐安装 Docker Desktop。
下载地址:
https://www.docker.com/products/docker-desktop/
安装完成后,打开终端执行:
docker version
如果能看到客户端和服务端版本信息,说明安装成功。
查看 Docker 运行状态:
docker info
2. macOS 安装 Docker
macOS 同样推荐安装 Docker Desktop。
下载地址:
https://www.docker.com/products/docker-desktop/
安装完成后执行:
docker version
测试运行:
docker run hello-world
如果输出欢迎信息,说明 Docker 可以正常工作。
3. Linux 安装 Docker
以 Ubuntu 为例,可以使用以下命令安装:
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
添加 Docker 官方 GPG 密钥:
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
添加 Docker 软件源:
echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装 Docker Engine:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
启动 Docker:
sudo systemctl start docker
设置开机自启:
sudo systemctl enable docker
查看 Docker 版本:
docker version
测试 Docker:
sudo docker run hello-world
如果不想每次都输入 sudo,可以把当前用户加入 Docker 用户组:
sudo usermod -aG docker $USER
然后重新登录终端。
五、Docker 常用命令总览
下面是 Docker 新手最常用的一批命令。
1. 查看 Docker 信息
查看版本:
docker version
查看系统信息:
docker info
查看帮助:
docker --help
查看某个命令帮助:
docker run --help
2. 镜像相关命令
搜索镜像:
docker search nginx
拉取镜像:
docker pull nginx
拉取指定版本镜像:
docker pull nginx:1.25
查看本地镜像:
docker images
或:
docker image ls
删除镜像:
docker rmi nginx
根据镜像 ID 删除:
docker rmi 镜像ID
强制删除镜像:
docker rmi -f 镜像ID
查看镜像详细信息:
docker inspect nginx
查看镜像构建历史:
docker history nginx
给镜像打标签:
docker tag nginx:latest my-nginx:v1
保存镜像为压缩包:
docker save -o nginx.tar nginx:latest
从压缩包加载镜像:
docker load -i nginx.tar
清理无用镜像:
docker image prune
清理所有未使用镜像:
docker image prune -a
3. 容器相关命令
创建并启动容器:
docker run nginx
后台运行容器:
docker run -d nginx
指定容器名称:
docker run -d --name my-nginx nginx
端口映射:
docker run -d --name my-nginx -p 8080:80 nginx
以上命令表示将宿主机的 8080 端口映射到容器内的 80 端口。访问:
http://localhost:8080
即可看到 Nginx 默认页面。
查看正在运行的容器:
docker ps
查看所有容器,包括已停止容器:
docker ps -a
停止容器:
docker stop my-nginx
启动已停止容器:
docker start my-nginx
重启容器:
docker restart my-nginx
删除容器:
docker rm my-nginx
强制删除运行中的容器:
docker rm -f my-nginx
查看容器日志:
docker logs my-nginx
实时查看日志:
docker logs -f my-nginx
查看最近 100 行日志:
docker logs --tail 100 my-nginx
进入正在运行的容器:
docker exec -it my-nginx bash
如果容器中没有 bash,可以使用:
docker exec -it my-nginx sh
退出容器:
exit
查看容器详细信息:
docker inspect my-nginx
查看容器资源占用:
docker stats
复制宿主机文件到容器:
docker cp ./index.html my-nginx:/usr/share/nginx/html/index.html
复制容器文件到宿主机:
docker cp my-nginx:/usr/share/nginx/html/index.html ./index.html
批量停止所有运行中的容器:
docker stop $(docker ps -q)
批量删除所有已停止容器:
docker rm $(docker ps -aq)
六、Docker run 常用参数详解
docker run 是 Docker 中最重要的命令之一。常用格式如下:
docker run [参数] 镜像名 [命令]
常见参数如下:
| 参数 | 说明 |
|---|---|
-d |
后台运行容器 |
--name |
指定容器名称 |
-p |
端口映射 |
-P |
随机端口映射 |
-v |
挂载数据卷或目录 |
-e |
设置环境变量 |
--rm |
容器停止后自动删除 |
-it |
交互式终端 |
--network |
指定网络 |
--restart |
设置重启策略 |
示例一:启动 Nginx:
docker run -d --name nginx-demo -p 8080:80 nginx
示例二:启动 MySQL:
docker run -d \
--name mysql-demo \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
示例三:启动 Redis:
docker run -d \
--name redis-demo \
-p 6379:6379 \
redis
示例四:启动 Ubuntu 并进入终端:
docker run -it ubuntu bash
示例五:容器停止后自动删除:
docker run --rm hello-world
七、数据卷 Volume
容器默认是临时的。如果容器被删除,容器内部的数据也可能随之丢失。
例如,你运行了一个 MySQL 容器,如果没有挂载数据卷,删除容器后数据库数据也会消失。
为了解决这个问题,Docker 提供了数据卷。
1. 使用数据卷的好处
数据卷可以实现:
- 数据持久化;
- 容器之间共享数据;
- 宿主机和容器之间共享文件;
- 方便备份和迁移;
- 避免数据随着容器删除而丢失。
2. 数据卷常用命令
创建数据卷:
docker volume create mysql-data
查看数据卷:
docker volume ls
查看数据卷详情:
docker volume inspect mysql-data
删除数据卷:
docker volume rm mysql-data
清理无用数据卷:
docker volume prune
3. 使用数据卷启动 MySQL
docker run -d \
--name mysql-demo \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v mysql-data:/var/lib/mysql \
mysql:8.0
这里的:
-v mysql-data:/var/lib/mysql
表示将 Docker 数据卷 mysql-data 挂载到容器内的 /var/lib/mysql 目录。
这样即使删除 MySQL 容器,只要数据卷还在,数据库数据就不会丢失。
4. 挂载宿主机目录
除了使用 Docker 数据卷,也可以直接挂载宿主机目录:
docker run -d \
--name nginx-demo \
-p 8080:80 \
-v /home/user/html:/usr/share/nginx/html \
nginx
这表示将宿主机 /home/user/html 目录挂载到容器内 Nginx 网站目录。
在开发环境中,这种方式非常常用,因为你可以直接修改宿主机文件,容器内会同步生效。
八、Docker 网络
Docker 容器之间可以通过网络通信。Docker 默认提供几种网络模式。
查看网络列表:
docker network ls
常见网络类型:
| 网络类型 | 说明 |
|---|---|
bridge |
默认网络模式,适合单机容器通信 |
host |
容器直接使用宿主机网络 |
none |
不配置网络 |
| 自定义网络 | 推荐用于多个容器互相访问 |
1. 创建自定义网络
docker network create app-network
查看网络详情:
docker network inspect app-network
删除网络:
docker network rm app-network
2. 容器加入自定义网络
启动 MySQL:
docker run -d \
--name mysql-demo \
--network app-network \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
启动应用容器时也加入同一个网络:
docker run -d \
--name app-demo \
--network app-network \
my-app:latest
在同一个自定义网络中,容器之间可以通过容器名称访问。例如应用连接 MySQL 时,数据库地址可以写:
mysql-demo:3306
而不是写 IP 地址。
九、Dockerfile 入门
Dockerfile 是 Docker 镜像构建的核心。下面以一个简单的 Node.js 项目为例。
假设项目结构如下:
my-node-app/
├── Dockerfile
├── package.json
└── app.js
app.js 内容:
const http = require('http');
const server = http.createServer((req, res) => {
res.end('Hello Docker');
});
server.listen(3000, () => {
console.log('Server running at http://0.0.0.0:3000');
});
package.json 内容:
{
"scripts": {
"start": "node app.js"
},
"dependencies": {}
}
Dockerfile 内容:
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
构建镜像:
docker build -t my-node-app:v1 .
运行容器:
docker run -d \
--name node-demo \
-p 3000:3000 \
my-node-app:v1
访问:
http://localhost:3000
即可看到输出:
Hello Docker
十、Dockerfile 常用指令说明
| 指令 | 说明 |
|---|---|
FROM |
指定基础镜像 |
WORKDIR |
设置工作目录 |
COPY |
复制文件到镜像中 |
ADD |
复制文件,支持自动解压和远程 URL |
RUN |
构建镜像时执行命令 |
CMD |
容器启动时默认执行命令 |
ENTRYPOINT |
容器启动入口 |
EXPOSE |
声明容器端口 |
ENV |
设置环境变量 |
ARG |
设置构建参数 |
VOLUME |
声明数据卷 |
USER |
指定运行用户 |
Dockerfile 编写建议
- 尽量使用官方基础镜像;
- 优先选择轻量镜像,如
alpine; - 合理利用缓存,把变化少的步骤放前面;
- 不要在镜像中写死敏感信息;
- 使用
.dockerignore排除无关文件; - 一个容器尽量只运行一个主要进程;
- 镜像标签不要永远使用
latest; - 生产环境应尽量减少镜像体积。
.dockerignore 示例:
node_modules
.git
.log
Dockerfile
docker-compose.yml
十一、Docker Compose 入门
当项目中包含多个容器时,推荐使用 Docker Compose。
例如,我们需要同时启动一个 Web 应用和 MySQL 数据库,可以编写 docker-compose.yml。
示例:
services:
mysql:
image: mysql:8.0
container_name: mysql-demo
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: app_db
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-network
redis:
image: redis:7
container_name: redis-demo
ports:
- "6379:6379"
networks:
- app-network
nginx:
image: nginx:latest
container_name: nginx-demo
ports:
- "8080:80"
networks:
- app-network
volumes:
mysql-data:
networks:
app-network:
启动所有服务:
docker compose up -d
查看服务状态:
docker compose ps
查看日志:
docker compose logs
实时查看日志:
docker compose logs -f
停止服务:
docker compose stop
启动服务:
docker compose start
重启服务:
docker compose restart
停止并删除容器:
docker compose down
停止并删除容器、网络、数据卷:
docker compose down -v
重新构建镜像并启动:
docker compose up -d --build
十二、常见实战示例
1. 快速启动 Nginx
docker run -d \
--name nginx-test \
-p 8080:80 \
nginx
访问:
http://localhost:8080
查看日志:
docker logs -f nginx-test
删除容器:
docker rm -f nginx-test
2. 快速启动 MySQL
docker run -d \
--name mysql-test \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=test_db \
-v mysql-test-data:/var/lib/mysql \
mysql:8.0
进入 MySQL 容器:
docker exec -it mysql-test bash
登录 MySQL:
mysql -uroot -p
输入密码:
123456
3. 快速启动 Redis
docker run -d \
--name redis-test \
-p 6379:6379 \
redis:7
进入 Redis:
docker exec -it redis-test redis-cli
测试:
set name docker
get name
4. 启动带密码的 Redis
docker run -d \
--name redis-auth \
-p 6379:6379 \
redis:7 redis-server --requirepass 123456
连接:
docker exec -it redis-auth redis-cli
认证:
auth 123456
十三、Docker 清理命令
Docker 使用久了之后,会积累很多无用镜像、容器、网络和数据卷,可以定期清理。
查看磁盘占用:
docker system df
清理停止的容器、无用网络、悬空镜像:
docker system prune
清理所有未使用镜像:
docker system prune -a
清理并删除未使用数据卷:
docker system prune -a --volumes
删除所有容器:
docker rm -f $(docker ps -aq)
删除所有镜像:
docker rmi -f $(docker images -q)
注意:清理命令具有破坏性,生产环境不要随意执行,尤其是带
--volumes的命令,可能会删除重要数据。
十四、Docker 新手常见问题
1. 为什么端口访问不了?
常见原因包括:
- 容器没有启动成功;
- 没有使用
-p做端口映射; - 宿主机防火墙未开放端口;
- 应用只监听了
127.0.0.1,没有监听0.0.0.0; - 端口被其他程序占用。
排查命令:
docker ps
docker logs 容器名
docker inspect 容器名
2. 容器删除后数据为什么没了?
如果数据只保存在容器内部,删除容器后数据就会丢失。
解决方案是使用数据卷:
-v mysql-data:/var/lib/mysql
或者挂载宿主机目录:
-v /data/mysql:/var/lib/mysql
3. 为什么容器启动后马上退出?
常见原因是容器主进程执行完毕。
例如:
docker run ubuntu
这个命令会很快退出,因为没有持续运行的前台进程。
如果想进入交互终端,应使用:
docker run -it ubuntu bash
4. 容器之间如何互相访问?
推荐创建自定义网络:
docker network create app-network
然后让容器加入同一个网络:
docker run -d --name mysql --network app-network mysql:8.0
docker run -d --name app --network app-network my-app:latest
应用中可以通过容器名访问:
mysql:3306
十五、Docker 学习路线建议
对于新手来说,建议按照以下顺序学习 Docker:
- 理解镜像和容器的区别;
- 掌握
docker run、docker ps、docker logs、docker exec; - 学会启动常见服务,如 Nginx、MySQL、Redis;
- 掌握端口映射和数据卷挂载;
- 学习 Dockerfile,能够构建自己的镜像;
- 学习 Docker Compose,管理多容器项目;
- 理解 Docker 网络;
- 学习镜像优化和生产部署;
- 了解 CI/CD 中 Docker 的使用;
- 进一步学习 Kubernetes。
十六、Docker 常用命令速查表
| 功能 | 命令 |
|---|---|
| 查看版本 | docker version |
| 查看信息 | docker info |
| 拉取镜像 | docker pull nginx |
| 查看镜像 | docker images |
| 删除镜像 | docker rmi 镜像名 |
| 启动容器 | docker run 镜像名 |
| 后台启动 | docker run -d 镜像名 |
| 查看运行容器 | docker ps |
| 查看所有容器 | docker ps -a |
| 停止容器 | docker stop 容器名 |
| 启动容器 | docker start 容器名 |
| 重启容器 | docker restart 容器名 |
| 删除容器 | docker rm 容器名 |
| 查看日志 | docker logs 容器名 |
| 进入容器 | docker exec -it 容器名 bash |
| 查看资源占用 | docker stats |
| 创建网络 | docker network create 网络名 |
| 查看网络 | docker network ls |
| 创建数据卷 | docker volume create 数据卷名 |
| 查看数据卷 | docker volume ls |
| 构建镜像 | docker build -t 镜像名:标签 . |
| 保存镜像 | docker save -o 镜像.tar 镜像名 |
| 加载镜像 | docker load -i 镜像.tar |
| Compose 启动 | docker compose up -d |
| Compose 停止 | docker compose down |
| 清理资源 | docker system prune |
十七、总结
Docker 的核心价值在于解决应用运行环境一致性问题。它通过镜像和容器的方式,让应用可以快速打包、分发和运行。
对于新手来说,不需要一开始就深入研究 Docker 底层原理。建议先掌握以下重点:
- 镜像是模板,容器是运行实例;
- 使用
docker pull拉取镜像; - 使用
docker run启动容器; - 使用
-p做端口映射; - 使用
-v做数据持久化; - 使用
docker logs查看日志; - 使用
docker exec进入容器; - 使用 Dockerfile 构建自己的镜像;
- 使用 Docker Compose 管理多个服务。
当你能熟练启动 Nginx、MySQL、Redis,并能为自己的项目编写 Dockerfile 和 docker-compose.yml 时,就已经具备了 Docker 日常开发和部署的基础能力。
Docker 是进入云原生世界的重要入口。学会 Docker 后,再学习 Kubernetes、CI/CD、微服务部署、DevOps 自动化都会更加顺畅。对于开发者来说,Docker 已经不是可选技能,而是非常值得掌握的基础能力。