一、什么是docker
在云计算和微服务架构盛行的今天,Docker 作为容器技术的标杆,彻底改变了应用部署和运行的方式。简单来说,Docker 是一个开源的容器化平台,它通过将应用程序及其依赖环境打包成一个轻量级、可移植的容器,实现了 “一次构建,到处运行” 的终极目标。
二、为什么需要Docker?
在学习技术之前,我们先搞懂一个问题:为什么要用 Docker?
如果你经历过这些场景,那 Docker 就是为你准备的:
- 开发时:“我本地能跑啊,怎么到你那就报错了?”
- 部署时:“服务器环境少了个依赖,等我装一下... 哦不对,版本不对!”
- 运维时:“这台服务器跑了 10 个应用,资源互相抢占,崩溃了都不知道是谁的锅。”
Docker 的出现就是为了解决这些问题。它通过容器化技术,把应用和依赖 “打包” 成一个独立的 “容器”,实现了 “一次构建,到处运行”。无论在开发机、测试环境还是生产服务器,容器里的应用运行结果完全一致,彻底告别 “环境不一致” 的噩梦。
三、Docker 的核心概念
要理解 Docker,需先掌握以下核心概念:
1. 镜像(Image)
- 定义:镜像可以理解为一个 “只读模板”,包含了运行应用所需的代码、库、环境变量、配置文件等所有依赖。例如,一个 Nginx 镜像包含了 Nginx 服务器的所有运行文件。
- 特性:
- 只读性:镜像一旦构建完成,就无法修改,确保环境一致性。
- 分层存储:镜像由多个只读层叠加而成,相同层可被多个镜像共享,节省存储空间。
- 可继承性:通过
Dockerfile
基于基础镜像(如ubuntu
、centos
)构建新镜像,简化配置。
2. 容器(Container)
- 定义:容器是镜像的运行实例,是镜像在内存中的动态表现形式。它在镜像的只读层之上添加了一个可写层,所有运行时的修改(如文件创建、配置变更)都保存在这一层。
- 特性:
- 隔离性:容器之间通过 namespace 隔离进程、网络、文件系统等资源,互不干扰。
- 轻量级:容器共享宿主机的内核,无需像虚拟机一样模拟完整操作系统,启动速度快(秒级)、资源占用低。
- 可移植性:相同镜像在任何支持 Docker 的环境中运行结果一致,解决 “开发环境能跑,生产环境报错” 的问题。
3. 仓库(Repository)
- 定义:仓库是用于存放和分发 Docker 镜像的平台,类似代码仓库(如 GitHub),你可以从仓库拉取别人做好的镜像,也可以把自己构建的镜像推到仓库分享。。
- 常见仓库:
- Docker Hub:官方公共仓库Docker Hub(https://hub.docker.com/),里面有数十万现成的镜像(比如 MySQL、Redis、Nginx 等),直接拿来就能用。。
- 私有仓库:企业或团队内部搭建的仓库(如 Harbor),用于存储私有镜像,保障安全性。
四、Docker 安装:3 步搞定环境搭建
接下来我们动手安装 Docker,支持 Windows、macOS 和 Linux,步骤都很简单:
1. Windows 安装
- 系统要求:Windows 10/11 专业版 / 企业版(需开启 Hyper - V),或使用 WSL2;
- 下载地址:Docker Desktop for Windows;
- 安装:双击安装包,一路 “下一步”,安装完成后启动 Docker(桌面会出现鲸鱼图标)。
2. Linux 安装(以 Ubuntu 为例)
# 更新包索引
sudo apt-get update
# 安装依赖
sudo apt-get install ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装(运行hello-world)
sudo docker run hello-world
安装完成后,运行docker --version
查看版本,出现类似Docker version 24.0.6, build ed223bc
的输出就说明安装成功了!
五、Docker 的基本工作流程
构建镜像
通过编写Dockerfile
定义镜像的构建步骤(如基础镜像选择、依赖安装、应用部署等),然后执行docker build
命令生成镜像。
示例Dockerfile
片段:FROM python:3.9 # 基础镜像 WORKDIR /app # 工作目录 COPY . . # 复制本地文件到容器 RUN pip install -r requirements.txt # 安装依赖 CMD ["python", "app.py"] # 容器启动命令
分发镜像
将构建好的镜像推送到仓库(如 Docker Hub 或私有仓库),供其他环境或团队成员使用。运行容器
从仓库拉取镜像,通过docker run
命令创建并启动容器,指定端口映射、数据卷挂载等参数。
示例:docker run -d -p 8080:80 --name myapp myapp:v1
(-d 后台运行,-p 端口映射,--name 容器名称)管理容器生命周期
通过命令停止(docker stop
)、启动(docker start
)、删除(docker rm
)容器,或查看日志(docker logs
)、进入容器(docker exec
)等。
六、Docker 常用命令
操作场景 | 命令示例 | 说明 |
---|---|---|
镜像相关 | docker pull [镜像名] |
从仓库拉取镜像 |
docker build -t [镜像名:版本] . |
基于 Dockerfile 构建镜像 | |
docker images |
查看本地镜像列表 | |
容器相关 | docker run -d -p 80:80 --name [容器名] [镜像名] |
创建并启动容器(-d 后台运行,-p 端口映射) |
docker ps |
查看运行中的容器 | |
docker ps -a |
查看所有容器(包括停止的) | |
docker stop [容器名/ID] |
停止容器 | |
docker rm [容器名/ID] |
删除容器 | |
仓库相关 | docker push [镜像名:版本] |
推送镜像到仓库 |
六、实战:用 Docker 部署一个 Node.js Web 应用
光说不练假把式,我们来实战部署一个简单的 Node.js Web 应用,体验完整的 Docker 流程:
1. 准备应用代码
创建一个简单的 Node.js 应用,目录结构如下:
myapp/
├── app.js # 应用代码
├── package.json # 依赖配置
└── Dockerfile # Docker构建文件
app.js
内容:
const http = require('http');
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello Docker! This is my Node.js app.\n');
});
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
package.json
内容:
{
"name": "my-docker-app",
"version": "1.0.0",
"main": "app.js",
"dependencies": {}
}
2. 编写 Dockerfile:定义镜像构建规则
Dockerfile
是构建镜像的 “说明书”,内容如下:
# 基础镜像:使用Node.js官方镜像(包含Node环境)
FROM node:16-alpine
# 设置工作目录(容器内的目录)
WORKDIR /app
# 复制本地文件到容器的工作目录
COPY package*.json ./
COPY app.js ./
# 安装依赖(因为package.json中无依赖,这步可省略,但保留规范)
RUN npm install
# 暴露容器的3000端口(告诉Docker容器会使用这个端口)
EXPOSE 3000
# 容器启动命令(运行Node应用)
CMD ["node", "app.js"]
3. 构建镜像与运行容器
# 进入myapp目录,构建镜像(-t指定镜像名和版本)
docker build -t my-node-app:v1 .
# 查看构建好的镜像
docker images | grep my-node-app
# 输出:my-node-app v1 abc123456789 1 minute ago 110MB
# 运行容器(映射宿主机3000端口到容器3000端口)
docker run -d -p 3000:3000 --name myapp-container my-node-app:v1
# 访问应用:打开浏览器访问 http://localhost:3000,能看到“Hello Docker! This is my Node.js app.”就成功了!
4. 推送镜像到仓库(可选)
如果你想把镜像分享给团队或部署到服务器,可以推送到 Docker Hub(需先注册账号并登录):
# 登录Docker Hub
docker login
# 给镜像打标签(格式:用户名/镜像名:版本)
docker tag my-node-app:v1 你的用户名/my-node-app:v1
# 推送镜像到仓库
docker push 你的用户名/my-node-app:v1
七、Docker 进阶:数据持久化与网络配置
实际应用中,我们还需要解决数据持久化(容器删除后数据不丢失)和容器间通信的问题。
1. 数据卷(Volume):让数据 “长生不老”
容器内的数据默认是临时的,容器删除后数据会丢失。用数据卷可以将容器内的目录映射到宿主机,实现数据持久化:
# 创建数据卷
docker volume create nginx-data
# 运行Nginx容器并挂载数据卷(将容器的/usr/share/nginx/html目录映射到nginx-data卷)
docker run -d -p 8080:80 -v nginx-data:/usr/share/nginx/html --name mynginx nginx
# 现在往宿主机的数据卷目录写文件,容器内会同步(数据卷在宿主机的路径可通过docker inspect查看)
2. 网络配置:让容器 “互联互通”
Docker 默认提供了桥接网络,容器可以通过名称或 IP 通信:
# 创建自定义网络
docker network create my-network
# 运行两个容器并加入同一网络
docker run -d --name app1 --network my-network my-node-app:v1
docker run -d --name app2 --network my-network nginx
# 在app1容器中访问app2(通过容器名)
docker exec -it app1 ping app2
# 能ping通说明网络连通成功
八、总结与后续学习方向
通过这篇文章,你已经掌握了 Docker 的核心概念、安装方法、基础命令和实战部署流程。Docker 的核心价值在于环境一致性、轻量级隔离和快速部署,这些特性让它成为现代软件开发和云原生架构的基石。
后续可以深入学习这些内容:
- Docker Compose:多容器应用编排工具,通过 yaml 文件定义多个容器的关系;
- Docker Swarm:Docker 原生的容器集群管理工具;
- Kubernetes(K8s):容器编排王者,用于大规模容器集群的管理(Docker 是基础);
- Docker 进阶技巧:镜像优化(减小体积)、多阶段构建、私有仓库搭建等。
Docker 不难,多动手实践就能熟练掌握。从今天开始,用 Docker 规范你的开发环境,提升部署效率吧!如果有问题,欢迎在评论区交流~