什么是Docker?
Docker是一个开源的容器化平台,它允许开发者将应用程序及其依赖环境打包成一个轻量级、可移植的容器。与传统的虚拟机不同,Docker容器直接运行在宿主机的操作系统内核上,无需额外的操作系统层,因此启动更快、资源占用更少。
核心概念:
- 镜像(Image):只读模板,包含运行应用所需的代码、库、环境配置等
- 容器(Container):镜像的运行实例,是独立、隔离的进程空间
- 仓库(Registry):存储镜像的地方,如Docker Hub
- Dockerfile:文本文件,定义如何构建镜像
为什么选择Docker?
1. 环境一致性
"在我机器上能跑,为什么到服务器就不行?"——这个经典问题在Docker时代得到解决。通过容器化,开发、测试、生产环境完全一致,避免了因环境差异导致的bug。
2. 快速部署与扩展
容器启动仅需秒级,远快于虚拟机。结合编排工具(如Kubernetes),可以实现应用的快速水平扩展和滚动更新。
3. 资源高效利用
多个容器共享宿主机内核,内存和CPU占用更少,同一台服务器可以运行更多应用实例。
4. 隔离与安全
每个容器拥有独立的文件系统、网络和进程空间,应用之间互不干扰,安全性更高。
快速开始:你的第一个Docker容器
安装Docker
以Ubuntu系统为例:
# 更新包索引
sudo apt-get update
# 安装必要依赖
sudo apt-get install apt-transport-https ca-certificates curl 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 run hello-world
运行第一个容器
# 拉取Nginx镜像
docker pull nginx:latest
# 运行Nginx容器
docker run -d -p 80:80 --name my-nginx nginx
# 查看运行中的容器
docker ps
# 访问服务
curl http://localhost
Dockerfile实战:构建自定义镜像
创建一个简单的Node.js应用并容器化:
项目结构:
my-app/
├── app.js
├── package.json
└── Dockerfile
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 on port ${port}`)
})
package.json:
{
"name": "my-app",
"version": "1.0.0",
"main": "app.js",
"dependencies": {
"express": "^4.18.2"
}
}
Dockerfile:
# 使用Node.js官方镜像作为基础镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制package.json和package-lock.json
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["node", "app.js"]
构建和运行:
# 构建镜像
docker build -t my-node-app .
# 运行容器
docker run -d -p 3000:3000 --name my-app my-node-app
# 测试应用
curl http://localhost:3000
Docker常用命令速查
| 命令 | 说明 | 示例 |
|---|---|---|
docker pull | 拉取镜像 | docker pull nginx |
docker images | 列出本地镜像 | docker images |
docker run | 运行容器 | docker run -d nginx |
docker ps | 查看运行中的容器 | docker ps -a |
docker stop | 停止容器 | docker stop container_id |
docker rm | 删除容器 | docker rm container_id |
docker rmi | 删除镜像 | docker rmi image_id |
docker logs | 查看容器日志 | docker logs container_id |
docker exec | 进入容器 | docker exec -it container_id /bin/bash |
docker build | 构建镜像 | docker build -t my-image . |
数据持久化:Volume与Bind Mount
容器默认是"无状态"的,重启后数据会丢失。为了持久化数据,Docker提供了两种方式:
1. Volume(推荐)
# 创建volume
docker volume create my-volume
# 运行容器并挂载volume
docker run -d -v my-volume:/data --name my-container nginx
# 查看volume
docker volume ls
2. Bind Mount(主机目录挂载)
# 将主机目录挂载到容器
docker run -d -v /host/path:/container/path nginx
网络管理
Docker提供多种网络模式:
- bridge:默认模式,容器通过虚拟网桥通信
- host:容器直接使用主机网络
- none:无网络
- 自定义网络:创建隔离的网络环境
# 创建自定义网络
docker network create my-network
# 运行容器并加入网络
docker run -d --network my-network --name app1 nginx
docker run -d --network my-network --name app2 nginx
# 容器间可以通过容器名通信
docker exec app1 ping app2
Docker Compose:多容器编排
对于复杂的多容器应用,使用Docker Compose可以简化管理:
docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
app:
build: .
ports:
- "3000:3000"
depends_on:
- redis
redis:
image: redis:alpine
启动服务:
# 启动所有服务
docker-compose up -d
# 停止服务
docker-compose down
生产环境最佳实践
1. 使用多阶段构建
减少镜像体积,提高安全性:
# 构建阶段
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# 生产阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm install --production
EXPOSE 3000
CMD ["node", "dist/app.js"]
2. 使用非root用户运行
FROM node:18-alpine
RUN addgroup -g 1000 nodeuser && adduser -u 1000 -G nodeuser -s /bin/sh -D nodeuser
USER nodeuser
# ... 其他指令
3. 设置资源限制
# 限制内存和CPU
docker run -d --memory=512m --cpus=1 nginx
4. 使用.dockerignore文件
避免将不必要的文件复制到镜像中,加快构建速度:
node_modules
.git
*.log
.env