Docker 教程:容器化平台详解
1. 什么是 Docker?
Docker 是一个开源的容器化平台,它允许开发者将应用及其依赖打包成一个轻量级、可移植的容器,然后在任何环境中运行。Docker 容器与虚拟机不同,它共享主机操作系统的内核,因此更加轻量级、启动更快,并且资源占用更少。
1.1 核心概念
- 镜像(Image):容器的只读模板,包含运行应用所需的所有文件和依赖。
- 容器(Container):镜像的运行实例,可以被创建、启动、停止、删除和暂停。
- 仓库(Repository):存储镜像的地方,如 Docker Hub。
- Dockerfile:定义如何构建镜像的文本文件。
- Docker Compose:用于定义和运行多容器 Docker 应用的工具。
1.2 核心特性
- 容器化:将应用及其依赖打包成容器,实现环境隔离和一致性。
- 镜像管理:通过镜像仓库管理和分发应用。
- 网络管理:提供容器间的网络通信能力。
- 存储管理:管理容器的数据持久化。
- 编排:通过 Docker Compose、Kubernetes 等工具管理多容器应用。
1.3 适用场景
- 应用打包和分发:确保应用在不同环境中运行一致。
- 微服务架构:每个服务作为独立容器运行,便于管理和扩展。
- 持续集成和持续部署:加速构建、测试和部署流程。
- 开发环境标准化:确保开发、测试和生产环境一致。
- 资源隔离:在同一主机上运行多个隔离的应用。
2. 安装和配置
2.1 Windows 安装
- 下载 Docker Desktop for Windows:https://www.docker.com/products/docker-desktop
- 运行安装程序,按照提示完成安装。
- 启动 Docker Desktop,等待它完全启动。
- 验证安装:
docker --version
docker-compose --version2.2 macOS 安装
- 下载 Docker Desktop for Mac:https://www.docker.com/products/docker-desktop
- 运行安装程序,按照提示完成安装。
- 启动 Docker Desktop,等待它完全启动。
- 验证安装:
docker --version
docker-compose --version2.3 Linux 安装
以 Ubuntu 为例:
# 更新包索引
sudo apt-get update
# 安装必要的依赖
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# 添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加 Docker 仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 更新包索引并安装 Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker --version
# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo docker-compose --version2.4 配置 Docker
2.4.1 非 root 用户使用 Docker(Linux)
sudo usermod -aG docker $USER
# 重新登录或执行以下命令使更改生效
su - $USER2.4.2 配置 Docker 镜像加速
对于中国用户,可以配置 Docker 镜像加速以提高拉取镜像的速度:
- 登录阿里云容器镜像服务:https://cr.console.aliyun.com/
- 获取镜像加速器地址
- 配置 Docker daemon.json 文件:
{
"registry-mirrors": ["https://你的加速器地址.mirror.aliyuncs.com"]
}- 重启 Docker 服务:
# Linux
sudo systemctl restart docker
# Windows/macOS
# 在 Docker Desktop 中重启3. 基本使用
3.1 镜像管理
# 拉取镜像
docker pull ubuntu
# 列出本地镜像
docker images
# 删除镜像
docker rmi ubuntu
# 构建镜像
docker build -t my-app .3.2 容器管理
# 运行容器
docker run -it --name my-container ubuntu bash
# 运行后台容器
docker run -d --name my-container ubuntu
# 查看运行中的容器
docker ps
# 查看所有容器
docker ps -a
# 停止容器
docker stop my-container
# 启动容器
docker start my-container
# 删除容器
docker rm my-container
# 进入运行中的容器
docker exec -it my-container bash3.3 网络管理
# 创建网络
docker network create my-network
# 运行容器并连接到网络
docker run -d --name container1 --network my-network nginx
docker run -d --name container2 --network my-network nginx
# 查看网络
docker network ls
# 查看网络详情
docker network inspect my-network3.4 存储管理
# 创建卷
docker volume create my-volume
# 运行容器并挂载卷
docker run -d --name my-container -v my-volume:/app nginx
# 查看卷
docker volume ls
# 查看卷详情
docker volume inspect my-volume
# 删除卷
docker volume rm my-volume
# 挂载主机目录
docker run -d --name my-container -v /host/path:/container/path nginx4. 高级功能
4.1 Dockerfile
创建一个 Dockerfile 文件来定义如何构建镜像:
# 指定基础镜像
FROM node:14-alpine
# 设置工作目录
WORKDIR /app
# 复制 package.json 和 package-lock.json
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["node", "app.js"]4.2 Docker Compose
创建一个 docker-compose.yml 文件来定义和运行多容器应用:
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: mongo
volumes:
- mongo-data:/data/db
volumes:
mongo-data:4.3 多阶段构建
使用多阶段构建来减小镜像大小:
# 构建阶段
FROM node:14-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]5. 实用案例
5.1 部署一个简单的 Node.js 应用
场景:使用 Docker 部署一个简单的 Node.js Express 应用。
步骤:
- 创建应用目录:
mkdir docker-node-app && cd docker-node-app- 创建 package.json 文件:
{
"name": "docker-node-app",
"version": "1.0.0",
"description": "Node.js app with Docker",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.17.1"
}
}- 创建 app.js 文件:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello Docker!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});- 创建 Dockerfile 文件:
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]- 构建镜像:
docker build -t node-app .- 运行容器:
docker run -d --name node-container -p 3000:3000 node-app- 测试应用:
打开浏览器访问 http://localhost:3000,应该看到 "Hello Docker!"。
5.2 使用 Docker Compose 部署多容器应用
场景:使用 Docker Compose 部署一个包含 Node.js 应用和 MongoDB 数据库的多容器应用。
步骤:
- 创建应用目录:
mkdir docker-compose-app && cd docker-compose-app- 创建 package.json 文件:
{
"name": "docker-compose-app",
"version": "1.0.0",
"description": "App with Docker Compose",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.13.7"
}
}- 创建 app.js 文件:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const port = 3000;
// 连接到 MongoDB
mongoose.connect('mongodb://db:27017/docker-compose-demo', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// 定义模型
const Item = mongoose.model('Item', {
name: String
});
// 路由
app.get('/', async (req, res) => {
// 创建一个新项
const item = new Item({ name: 'Test Item' });
await item.save();
// 获取所有项
const items = await Item.find();
res.send(`Items: ${JSON.stringify(items)}`);
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});- 创建 Dockerfile 文件:
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]- 创建 docker-compose.yml 文件:
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: mongo
volumes:
- mongo-data:/data/db
volumes:
mongo-data:- 启动应用:
docker-compose up -d- 查看容器状态:
docker-compose ps- 测试应用:
打开浏览器访问 http://localhost:3000,应该看到包含测试项的响应。
- 停止应用:
docker-compose down6. 代码示例
6.1 构建和运行简单应用
Dockerfile:
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]构建和运行命令:
# 构建镜像
docker build -t my-app .
# 运行容器
docker run -d --name my-container -p 3000:3000 my-app
# 查看容器状态
docker ps
# 停止容器
docker stop my-container
# 删除容器
docker rm my-container6.2 使用 Docker Compose 部署多容器应用
docker-compose.yml:
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
db:
image: postgres
environment:
- POSTGRES_PASSWORD=secret
- POSTGRES_USER=user
- POSTGRES_DB=app
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:启动和停止命令:
# 启动应用
docker-compose up -d
# 查看日志
docker-compose logs
# 停止应用
docker-compose down7. 常见问题和解决方案
7.1 容器无法启动
问题:容器启动后立即退出。
解决方案:
- 检查容器日志:
docker logs [容器名称] - 确保容器有一个前台进程在运行
- 检查应用是否有错误
7.2 端口映射失败
问题:无法通过主机端口访问容器应用。
解决方案:
- 检查端口映射是否正确:
docker run -p [主机端口]:[容器端口] - 确保容器内的应用正在监听正确的端口
- 检查主机防火墙是否阻止了该端口
7.3 数据持久化问题
问题:容器重启后数据丢失。
解决方案:
- 使用 Docker 卷:
docker run -v [卷名]:[容器路径] - 使用主机目录挂载:
docker run -v [主机路径]:[容器路径]
7.4 镜像拉取缓慢
问题:从 Docker Hub 拉取镜像速度缓慢。
解决方案:
- 配置 Docker 镜像加速
- 使用国内镜像源
7.5 容器间通信问题
问题:同一网络中的容器无法相互通信。
解决方案:
- 确保容器在同一个网络中:
docker network create和docker run --network - 使用容器名称作为主机名进行通信
- 检查容器的网络配置:
docker network inspect
8. 总结
Docker 是一个强大的容器化平台,它彻底改变了应用的开发、部署和运行方式。通过将应用及其依赖打包成容器,Docker 实现了环境的一致性和可移植性,大大简化了应用的部署和管理。
8.1 优点
- 环境一致性:确保应用在不同环境中运行一致
- 轻量级:相比虚拟机,容器更加轻量级,启动更快
- 可移植性:容器可以在任何支持 Docker 的环境中运行
- 资源隔离:容器之间相互隔离,避免资源冲突
- 易于管理:提供了简单易用的命令行工具和 API
8.2 局限性
- 学习曲线:对于初学者来说,Docker 有一定的学习曲线
- 网络复杂性:在复杂的网络环境中,容器网络配置可能变得复杂
- 存储管理:容器的存储管理需要额外的配置和考虑
- 安全考虑:需要注意容器的安全配置,避免安全漏洞
8.3 适用场景
- 微服务架构:每个服务作为独立容器运行
- 持续集成和持续部署:加速构建、测试和部署流程
- 开发环境标准化:确保开发、测试和生产环境一致
- 多环境部署:快速在不同环境中部署应用
- 资源优化:提高服务器资源利用率
通过本教程,你应该已经掌握了 Docker 的基本概念、安装配置、基本使用和常见场景的应用。在实际开发和部署中,Docker 可以大大简化工作流程,提高开发效率和应用的可靠性。