Docker基础入门
Docker是一个开源的应用容器引擎,它让开发者可以将应用及其依赖打包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统上。本文将介绍Docker的基本概念和使用方法,帮助你快速入门容器化技术。
容器技术简介
什么是容器?
容器是一种轻量级的虚拟化技术,它允许应用程序及其依赖在资源隔离的环境中运行。与传统虚拟机相比,容器不需要模拟整个操作系统,而是共享主机的操作系统内核,因此启动更快、资源消耗更少。
容器 vs 虚拟机
特性 | 容器 | 虚拟机 |
---|---|---|
隔离级别 | 进程级隔离 | 硬件级隔离 |
启动时间 | 秒级 | 分钟级 |
资源消耗 | 轻量级 | 较重 |
镜像大小 | MB级别 | GB级别 |
操作系统 | 共享主机内核 | 完整的客户机操作系统 |
Docker的核心概念
- 镜像(Image): 一个只读的模板,包含创建容器的指令
- 容器(Container): 镜像的运行实例,可以被创建、启动、停止、删除和暂停
- 仓库(Repository): 集中存放镜像的地方,最常用的是Docker Hub
- Dockerfile: 用于构建Docker镜像的文本文件,包含一系列命令和指令
- Docker Compose: 用于定义和运行多容器Docker应用程序的工具
安装Docker
Windows 10/11 安装
- 下载并安装 Docker Desktop for Windows
- 确保开启了WSL 2功能 (Windows Subsystem for Linux)
- 启动Docker Desktop应用程序
- 验证安装是否成功:
docker --version docker run hello-world
macOS 安装
- 下载并安装 Docker Desktop for Mac
- 启动Docker Desktop应用程序
- 验证安装是否成功:
docker --version docker run hello-world
Ubuntu 安装
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加官方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 Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
配置非root用户运行Docker (Linux)
# 创建docker组
sudo groupadd docker
# 将当前用户添加到docker组
sudo usermod -aG docker $USER
# 应用新组设置 (重新登录或执行以下命令)
newgrp docker
# 测试无需sudo运行
docker run hello-world
Docker基本命令
镜像管理
# 查看本地镜像
docker images
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 构建镜像
docker build -t my-app:1.0 .
# 删除镜像
docker rmi nginx:latest
# 镜像历史
docker history nginx:latest
# 导出镜像
docker save -o nginx.tar nginx:latest
# 导入镜像
docker load -i nginx.tar
容器管理
# 创建并启动容器
docker run -d -p 80:80 --name my-nginx nginx:latest
# 列出运行中的容器
docker ps
# 列出所有容器(包括停止的)
docker ps -a
# 启动/停止/重启容器
docker start my-nginx
docker stop my-nginx
docker restart my-nginx
# 删除容器
docker rm my-nginx
# 进入容器
docker exec -it my-nginx bash
# 查看容器日志
docker logs my-nginx
# 查看容器资源使用情况
docker stats my-nginx
数据卷管理
# 创建数据卷
docker volume create my-data
# 列出数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect my-data
# 删除数据卷
docker volume rm my-data
# 清理未使用的数据卷
docker volume prune
网络管理
# 创建网络
docker network create my-network
# 列出网络
docker network ls
# 查看网络详情
docker network inspect my-network
# 将容器连接到网络
docker network connect my-network my-nginx
# 断开容器与网络的连接
docker network disconnect my-network my-nginx
# 删除网络
docker network rm my-network
使用Dockerfile构建镜像
Dockerfile是一个文本文件,包含一系列指令,用于构建Docker镜像。
基本结构
# 基础镜像
FROM node:14
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY package.json package-lock.json ./
# 安装依赖
RUN npm install
# 复制应用代码
COPY . .
# 构建应用
RUN npm run build
# 暴露端口
EXPOSE 3000
# 容器启动命令
CMD ["npm", "start"]
常用指令
- FROM: 指定基础镜像
- WORKDIR: 设置工作目录
- COPY/ADD: 复制文件到容器中
- RUN: 在构建过程中执行命令
- ENV: 设置环境变量
- EXPOSE: 声明容器将监听的端口
- VOLUME: 声明数据卷
- CMD: 指定容器启动时执行的命令
- ENTRYPOINT: 设置容器入口点
- ARG: 定义构建时变量
构建镜像
# 基本构建
docker build -t my-app:1.0 .
# 指定Dockerfile
docker build -t my-app:1.0 -f Dockerfile.prod .
# 构建时传递参数
docker build -t my-app:1.0 --build-arg NODE_ENV=production .
多阶段构建示例
多阶段构建可以减小最终镜像的大小,适合前端应用和编译型语言。
# 构建阶段
FROM node:14 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker Compose
Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。使用YAML文件配置应用的服务,然后一个命令就可以创建并启动所有服务。
安装Docker Compose
Windows/macOS: Docker Desktop已包含Docker Compose
Linux:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
docker-compose.yml示例
version: '3.8'
services:
webapp:
build:
context: ./webapp
dockerfile: Dockerfile
ports:
- "80:80"
depends_on:
- db
environment:
- DATABASE_URL=postgres://postgres:password@db:5432/mydb
volumes:
- ./webapp:/app
networks:
- app-network
db:
image: postgres:13
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
postgres-data:
常用命令
# 启动所有服务
docker-compose up
# 以守护进程模式启动
docker-compose up -d
# 停止所有服务
docker-compose down
# 仅构建服务
docker-compose build
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs
# 执行服务中的命令
docker-compose exec webapp bash
# 扩展服务实例
docker-compose up -d --scale webapp=3
实用Docker配置和技巧
持久化数据
使用数据卷:
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=password \
mysql:8
使用主机目录:
docker run -d \
--name nginx \
-v $(pwd)/html:/usr/share/nginx/html \
-p 80:80 \
nginx:alpine
环境变量
docker run -d \
--name node-app \
-e NODE_ENV=production \
-e API_KEY=secret \
my-node-app:latest
容器间通信
使用Docker网络:
# 创建网络
docker network create app-net
# 将容器连接到网络
docker run -d --name db --network app-net mongo
docker run -d --name api --network app-net my-api
# 此时,api容器可以通过主机名"db"连接到数据库
健康检查
在Dockerfile中添加健康检查:
FROM nginx:alpine
HEALTHCHECK \
CMD curl -f http://localhost/ || exit 1
或者在docker run命令中添加:
docker run -d \
--name nginx \
--health-cmd="curl -f http://localhost/ || exit 1" \
--health-interval=30s \
nginx:alpine
常见问题及解决方案
容器无法访问网络
问题: 容器内无法访问互联网或其他容器。
解决方案:
- 检查网络配置:
docker network inspect bridge
- 确认DNS配置: 可能需要添加
--dns
选项 - 检查防火墙规则
磁盘空间不足
问题: Docker镜像和容器占用过多磁盘空间。
解决方案:
# 清理未使用的资源
docker system prune -a
# 清理未使用的数据卷
docker volume prune
# 显示Docker占用的磁盘空间
docker system df
容器权限问题
问题: 容器内进程没有足够权限访问挂载的卷。
解决方案:
- 检查挂载卷的权限
- 在容器内使用适当的用户运行应用
- 在Dockerfile中使用
USER
指令设置正确的用户
FROM node:14
# 创建用户并设置权限
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY . .
# 更改目录权限
RUN chown -R appuser:appuser /app
USER appuser
CMD ["node", "app.js"]
Docker最佳实践
镜像优化
- 使用官方镜像:官方镜像通常经过优化和安全更新
- 选择特定标签:避免使用
latest
标签,使用特定版本号确保一致性 - 使用轻量级基础镜像:如Alpine Linux版本
- 多阶段构建:减小最终镜像大小
- 最小化层数:合并RUN命令减少层数
安全性
- 不要以root用户运行容器:在Dockerfile中使用
USER
指令指定非root用户 - 扫描镜像漏洞:使用工具如Trivy、Clair定期扫描
- 使用只读文件系统:
--read-only
选项和临时文件系统 - 限制资源使用:使用
--memory
和--cpu
选项限制资源 - 敏感信息使用:使用Docker Secrets而非环境变量存储敏感信息
日志管理
默认的json-file日志驱动可能导致磁盘空间问题,可以配置日志轮转:
docker run -d \
--name nginx \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx:alpine
或使用其他日志驱动,如syslog、journald等。
监控与资源限制
# 限制内存
docker run -d --name app --memory=512m my-app
# 限制CPU
docker run -d --name app --cpus=0.5 my-app
# 监控容器资源使用
docker stats
Docker的未来发展
随着容器技术的普及,Docker生态系统也在不断发展:
- Kubernetes(K8s): 容器编排平台,用于自动部署、扩展和管理容器化应用
- 微服务架构: 容器特别适合微服务架构,每个服务独立容器化
- Serverless容器: 如AWS Fargate、Azure Container Instances
- 安全强化: 加强容器隔离和安全性的解决方案
- 容器标准化: OCI(开放容器倡议)标准的持续发展
总结
Docker为应用的开发、测试和部署带来了革命性的变化。通过容器化技术,可以确保应用在不同环境中的一致性,简化部署流程,提高资源利用率。本文介绍的基础知识和最佳实践,希望能帮助你快速入门Docker,并在项目中有效地使用容器技术。
随着经验的积累,你可以进一步探索更高级的主题,如容器编排(Kubernetes)、持续集成/持续部署(CI/CD)流水线集成,以及更复杂的多容器应用架构。
如有任何Docker相关问题或讨论,欢迎联系我进行交流。