Docker已成为现代软件开发和部署的关键技术,通过容器化实现应用的一致性运行环境。本文将全面介绍Docker的核心概念、安装配置、基础与进阶操作,以及实际部署案例,帮助你快速掌握这一强大工具。
1. Docker概述:容器化革命
1.1 Docker是什么?
Docker是一个开源的应用容器引擎,让开发者可以将应用及其依赖打包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux或Windows机器上。
1.2 为什么需要Docker?
- 一致的运行环境:解决"在我电脑上能运行"的问题
- 轻量级:比虚拟机更高效,启动时间秒级
- 隔离性:应用间互不影响,安全性高
- 易于扩展:快速扩缩容,适合微服务架构
- 版本控制:类似Git,可追踪镜像变更
1.3 核心概念
- 镜像(Image):只读模板,包含运行应用所需的一切
- 容器(Container):镜像的运行实例,可读写
- 仓库(Repository):存储和分发镜像的地方
1.4 Docker vs 虚拟机
上图清晰展示了Docker容器与传统虚拟机在架构设计上的根本区别。虚拟机架构中,每个应用需要一个完整的操作系统副本,这些虚拟机OS运行在虚拟机管理程序(Hypervisor)之上,形成了较厚的虚拟化层。而Docker架构则大幅简化了这一结构,所有容器直接共享宿主机的操作系统内核,只包含应用程序和必要的运行时环境,省去了独立OS的开销。正是这种架构上的精简设计,使得Docker相比虚拟机具有显著优势:
- 启动速度:秒级 vs 分钟级 - 容器无需启动完整OS,因此可以在几秒内完成启动
- 资源占用:MB级 vs GB级 - 容器只包含应用本身和必要依赖,无需存储完整的OS镜像
- 性能损耗:几乎为零 vs 有一定损耗 - 容器直接使用宿主机内核,无需虚拟化层的转换开销
这种架构差异使Docker特别适合微服务架构和需要快速部署、高密度运行的云环境应用场景。
2. Docker安装与配置
2.1 不同系统的安装方法
Ubuntu/Debian安装Docker
2.1 不同系统的安装方法
Ubuntu/Debian安装Docker
# 使用Docker官方便捷脚本安装
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 验证安装
sudo docker --version
sudo docker run hello-world
# 将当前用户添加到docker组(可选,避免每次使用sudo)
sudo usermod -aG docker $USER
# 注意:需要注销并重新登录才能生效
上述安装方法在Ubuntu 22.04.2(X86_64 emulation)和Debian GNU Linux 12 ARM64的服务器上测试通过
CentOS/RHEL安装Docker
# 卸载旧版本Docker(如果存在)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 安装yum-utils工具包
sudo yum install -y yum-utils
# 设置Docker仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装Docker Engine、CLI和containerd
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 启动Docker服务
sudo systemctl start docker
# 设置Docker开机自启
sudo systemctl enable docker
# 验证安装
sudo docker --version
sudo docker run hello-world
# 将当前用户添加到docker组(可选,避免每次使用sudo)
sudo usermod -aG docker $USER
# 注意:需要注销并重新登录才能生效
如果安装过程中出现问题,请参考CentOS安装Docker(超详细)以及如何在RedHat Linux系统中安装Docker及Docker hub的使用进行安装
Windows安装Docker Desktop
-
确保系统要求:
- Windows 10 64位: 专业版、企业版或教育版(Build 19041或更高版本)
- 启用硬件虚拟化(在BIOS中检查)
- 至少4GB RAM
-
安装WSL 2(推荐):
# 在PowerShell中执行(管理员权限) wsl --install -
下载并安装Docker Desktop:
- 访问Docker官网下载最新版Docker Desktop Installer.exe
- 双击安装文件,按照安装向导操作
- 选择"使用WSL 2"选项(推荐)
Mac安装Docker Desktop
-
确保系统要求:
- macOS 11.0或更高版本(Big Sur、Monterey或Ventura)
- 对于Intel芯片Mac: 2010年或更新的型号
- 对于Apple Silicon (M1/M2): 确保下载适用于ARM架构的版本
-
下载并安装Docker Desktop:
- 访问Docker官网下载Mac版Docker Desktop
- 下载完成后,双击Docker.dmg打开
- 将Docker拖到Applications文件夹
- 从Applications文件夹启动Docker
2.2 验证安装
# 检查Docker版本
docker --version
# 运行hello-world容器验证
docker run hello-world
如果安装成功,你将看到Docker版本信息和hello-world容器打印的欢迎消息,如下图所示:
2.3 配置镜像加速
国内用户可以配置镜像加速器提高下载速度:
# Linux配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://registry.docker-cn.com", "https://hub-mirror.c.163.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
对于Windows/Mac用户,在Docker Desktop设置中添加以上镜像地址。
3. Docker基本操作
3.1 镜像管理
常用镜像命令
# 查看本地镜像列表
docker images
# 搜索镜像
docker search nginx
# 拉取镜像(默认latest版本)
docker pull nginx
# 拉取指定版本镜像
docker pull nginx:1.19
# 删除镜像
docker rmi nginx:1.19
# 删除所有未使用的镜像
docker image prune -a
3.2 容器管理
容器生命周期管理
# 创建并启动容器
docker run -d --name my-nginx -p 80:80 nginx
# 参数说明:
# -d: 后台运行
# --name: 指定容器名称
# -p: 端口映射,主机端口:容器端口
# 查看运行中的容器
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
# 进入容器内部
docker exec -it my-nginx bash
# 以特定用户身份进入容器
docker exec -it -u root my-nginx bash
3.3 Dockerfile基础
Dockerfile是构建Docker镜像的脚本,由一系列指令组成。
常用Dockerfile指令
# 基础镜像
FROM node:14-alpine
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
# 执行命令
RUN npm install
# 复制应用代码
COPY . .
# 设置环境变量
ENV PORT=3000
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["npm", "start"]
构建和运行自定义镜像
# 构建镜像
docker build -t my-app:1.0 .
# 运行构建的镜像
docker run -d -p 3000:3000 --name my-node-app my-app:1.0
4. Docker进阶操作
4.1 Docker网络
Docker提供多种网络驱动,实现容器间通信和与外部网络的连接。
网络操作命令
# 查看所有网络
docker network ls
# 创建自定义网络
docker network create my-network
# 启动容器并连接到指定网络
docker run -d --name db --network my-network mongo
# 连接已存在的容器到网络
docker network connect my-network my-nginx
# 断开容器与网络的连接
docker network disconnect my-network my-nginx
# 检查网络详情
docker network inspect my-network
4.2 数据卷与持久化
数据卷(Volume)用于持久化数据和在容器间共享数据。
数据卷操作
# 创建数据卷
docker volume create my-data
# 查看所有数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect my-data
# 运行容器并挂载数据卷
docker run -d --name mysql -v my-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 挂载主机目录到容器
docker run -d --name nginx -v /host/path:/usr/share/nginx/html -p 80:80 nginx
4.3 Docker Compose多容器编排
Docker Compose用于定义和运行多容器Docker应用,使用YAML文件配置应用服务。
安装Docker Compose
# Linux安装
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Windows/Mac Docker Desktop已内置
docker-compose.yml示例
version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- app
app:
build: ./app
environment:
- DB_HOST=db
- DB_USER=postgres
- DB_PASSWORD=example
depends_on:
- db
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=example
- POSTGRES_USER=postgres
volumes:
postgres_data:
Compose常用命令
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs
# 停止所有服务
docker-compose down
# 重建服务
docker-compose up -d --build
4.4 Docker Swarm集群管理
Docker Swarm是Docker的原生集群管理工具,用于管理分布在多个主机上的Docker容器。
Swarm基本操作
# 初始化Swarm集群
docker swarm init --advertise-addr 192.168.1.10
# 添加Worker节点(在其他主机上执行init命令输出的join命令)
docker swarm join --token SWMTKN-1-xxxx 192.168.1.10:2377
# 查看节点列表
docker node ls
# 部署服务
docker service create --name web --replicas 3 -p 80:80 nginx
# 扩容服务
docker service scale web=5
# 更新服务
docker service update --image nginx:1.19 web
# 删除服务
docker service rm web
5. Docker应用部署实战
5.1 部署Web应用
SpringBoot应用Dockerfile
# 指定基础镜像,这里使用精简版的OpenJDK 11运行环境
FROM openjdk:11-jre-slim
# 设置容器内的工作目录
WORKDIR /app
# 将本地target目录下的jar文件复制到容器内的工作目录,并命名为app.jar
COPY target/*.jar app.jar
# 声明应用将使用8080端口(仅是声明,并不会自动映射)
EXPOSE 8080
# 容器启动时执行的命令,运行Java应用
CMD ["java", "-jar", "app.jar"]
构建和运行
# 构建Docker镜像,-t指定镜像名称和标签,最后的点表示使用当前目录的Dockerfile
docker build -t myapp:1.0 .
# 运行容器
# -d: 后台运行
# -p 8080:8080: 将主机的8080端口映射到容器的8080端口
# --name myapp: 为容器指定名称
docker run -d -p 8080:8080 --name myapp myapp:1.0
5.2 部署数据库
MySQL容器部署
# 从Docker Hub拉取MySQL 8.0版本的镜像
docker pull mysql:8.0
# 创建命名卷用于持久化MySQL数据
# 这样即使容器被删除,数据也会保留
docker volume create mysql_data
# 运行MySQL容器
docker run -d \
--name mysql \ # 设置容器名称为mysql
-e MYSQL_ROOT_PASSWORD=my-secret-pw \ # 设置root用户密码
-e MYSQL_DATABASE=myapp \ # 创建一个名为myapp的初始数据库
-e MYSQL_USER=myuser \ # 创建一个新的数据库用户
-e MYSQL_PASSWORD=mypassword \ # 设置该用户的密码
-p 3306:3306 \ # 将主机的3306端口映射到容器的3306端口
-v mysql_data:/var/lib/mysql \ # 将mysql_data卷挂载到容器内的/var/lib/mysql目录
mysql:8.0
# 连接到MySQL容器的交互式终端
# -it: 交互式终端
# mysql -uroot -p: 使用root用户登录MySQL,并提示输入密码
docker exec -it mysql mysql -uroot -p
5.3 前后端分离应用部署
使用Docker Compose部署前后端分离应用:
# docker-compose.yml文件定义多容器应用
version: '3' # 使用Docker Compose格式版本3
services: # 定义服务(容器)
# 前端服务
frontend:
build: ./frontend # 使用./frontend目录下的Dockerfile构建镜像
ports:
- "80:80" # 将主机的80端口映射到容器的80端口
depends_on:
- backend # 指定依赖关系,确保backend服务先启动
# 后端服务
backend:
build: ./backend # 使用./backend目录下的Dockerfile构建镜像
environment: # 设置环境变量
- DB_HOST=db # 数据库主机名为db(Docker Compose会自动解析服务名)
- DB_NAME=myapp # 数据库名称
- DB_USER=myuser # 数据库用户名
- DB_PASSWORD=mypassword # 数据库密码
ports:
- "8080:8080" # 将主机的8080端口映射到容器的8080端口
depends_on:
- db # 指定依赖关系,确保db服务先启动
# 数据库服务
db:
image: mysql:8.0 # 使用MySQL 8.0镜像
volumes:
- db_data:/var/lib/mysql # 挂载命名卷到容器内的/var/lib/mysql目录
environment: # 设置环境变量
- MYSQL_ROOT_PASSWORD=rootpassword # root密码
- MYSQL_DATABASE=myapp # 初始数据库名
- MYSQL_USER=myuser # 新建用户名
- MYSQL_PASSWORD=mypassword # 新建用户密码
ports:
- "3306:3306" # 将主机的3306端口映射到容器的3306端口
# 声明要创建的卷
volumes:
db_data: # 定义名为db_data的卷,用于持久化数据库数据
5.4 使用Nginx作为反向代理
# docker-compose.yml文件中添加Nginx服务
services:
# 添加Nginx服务作为反向代理
nginx:
image: nginx:latest # 使用最新版Nginx镜像
ports:
- "80:80" # HTTP端口映射
- "443:443" # HTTPS端口映射
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d # 挂载本地配置目录到容器
- ./nginx/ssl:/etc/nginx/ssl # 挂载SSL证书目录到容器
depends_on:
- frontend # 确保frontend服务已启动
- backend # 确保backend服务已启动
Nginx配置文件./nginx/conf.d/default.conf:
server {
listen 80; # 监听80端口
server_name myapp.com; # 设置服务器名称
# 对根路径的请求转发到前端服务
location / {
proxy_pass http://frontend; # 将请求代理到frontend服务
proxy_set_header Host $host; # 传递原始主机头
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
}
# 对/api路径的请求转发到后端服务
location /api {
proxy_pass http://backend:8080; # 将请求代理到backend服务的8080端口
proxy_set_header Host $host; # 传递原始主机头
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
}
}
5.5 容器化CI/CD配置
GitHub Actions工作流示例:
# .github/workflows/docker-build.yml文件
# 定义GitHub Actions工作流
name: Docker Build and Deploy # 工作流名称
on: # 触发条件
push:
branches: [ main ] # 仅在推送到main分支时触发
jobs: # 定义工作
build-and-deploy: # 构建和部署任务
runs-on: ubuntu-latest # 在Ubuntu最新版上运行
steps: # 定义步骤
- uses: actions/checkout@v2 # 第1步:检出代码
- name: Login to DockerHub # 第2步:登录到Docker Hub
uses: docker/login-action@v1 # 使用官方的Docker登录Action
with:
username: ${{ secrets.DOCKERHUB_USERNAME }} # 使用GitHub保存的密钥
password: ${{ secrets.DOCKERHUB_TOKEN }} # 使用GitHub保存的密钥
- name: Build and push Docker image # 第3步:构建并推送Docker镜像
uses: docker/build-push-action@v2 # 使用官方的Docker构建推送Action
with:
context: . # 构建上下文为当前目录
push: true # 推送到Docker Hub
tags: username/myapp:latest # 设置镜像标签
- name: Deploy to production server # 第4步:部署到生产服务器
uses: appleboy/ssh-action@master # 使用SSH Action
with:
host: ${{ secrets.SERVER_HOST }} # 服务器主机地址
username: ${{ secrets.SERVER_USER }} # SSH用户名
key: ${{ secrets.SERVER_KEY }} # SSH私钥
script: | # 在服务器上执行的脚本
cd /opt/myapp # 进入应用目录
docker-compose pull # 拉取最新镜像
docker-compose up -d # 启动容器(后台运行)
6. Docker常见问题与最佳实践
6.1 容器健康检查
# 在Dockerfile中添加健康检查指令
HEALTHCHECK --interval=30s \ # 每30秒检查一次
--timeout=3s \ # 检查命令超时时间为3秒
--start-period=5s \ # 启动后等待5秒再开始检查
--retries=3 \ # 连续失败3次则认为不健康
CMD curl -f http://localhost:8080/health || exit 1
# 检查命令:请求应用的健康端点,
# 如果返回非0状态码则判定为不健康
6.2 镜像瘦身技巧
多阶段构建示例:
# 构建阶段
FROM maven:3.8-openjdk-11 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests
# 运行阶段
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
6.3 安全最佳实践
- 使用非root用户运行容器
- 定期更新基础镜像
- 扫描镜像漏洞
- 限制容器资源
- 使用只读文件系统
# 使用非root用户示例
FROM node:14-alpine
# 创建非root用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# 设置工作目录
WORKDIR /app
# 复制并安装依赖
COPY package*.json ./
RUN npm install
# 复制应用代码
COPY . .
# 修改所有权
RUN chown -R appuser:appgroup /app
# 切换到非root用户
USER appuser
EXPOSE 3000
CMD ["npm", "start"]
6.4 资源限制
# 限制CPU和内存资源
docker run -d --name app \
--cpu-shares=512 \
--memory=1g \
--memory-swap=2g \
myapp:latest
7. 学习资源与参考
学习Docker的过程中,官方资源永远是最可靠的起点。Docker官方文档提供了从入门到精通的全面指南,尤其是其中的Get Started部分对新手特别友好。当你需要寻找现成的镜像时,Docker Hub是官方的镜像仓库,收录了成千上万的优质镜像。如果你对Docker的源码感兴趣或想了解最新进展,可以关注Docker的GitHub仓库。
对于想要系统学习的开发者,我强烈推荐Nigel Poulton的《Docker Deep Dive》,这本书深入浅出地讲解了Docker的核心概念和实践技巧。如果你更喜欢实战导向的学习方式,《Docker in Action》(Jeff Nickoloff著)和《Docker: Up & Running》(Sean P. Kane, Karl Matthias合著)都是不错的选择,这两本书都包含了大量实用案例和最佳实践。
在日常的Docker管理中,一些辅助工具能极大提升工作效率。Portainer提供了直观的Web界面来管理Docker环境,对不习惯命令行的用户特别友好。监控容器性能时,ctop是个轻量级但功能强大的工具,提供类似top命令的界面展示容器资源使用情况。如果你对Docker镜像体积优化感兴趣,docker-slim可以自动分析并精简镜像大小,有时甚至能减少30倍以上的体积。
总结
Docker作为容器化技术的领军者,已成为现代软件开发和部署的标准工具。通过本文的学习,你应该对Docker的基本概念、安装配置、常用操作以及进阶使用有了系统的了解。从开发、测试到生产环境,Docker都能为你提供一致的运行环境和高效的部署方式。
随着容器技术的不断发展,Docker生态系统也在不断壮大,学习和掌握Docker相关技术将为你的职业发展带来巨大优势。希望这篇文章能帮助你顺利踏入容器化的世界,并在实际工作中灵活运用Docker解决各种挑战。

被折叠的 条评论
为什么被折叠?



