Docker容器化部署入门全面指南
作者:黄思搏
Docker是一个开源的容器化平台,它允许开发者打包、分发和运行应用程序在任何地方,无需担心底层环境的差异,本文给大家介绍Docker容器化部署入门全面指南,感兴趣的朋友跟随小编一起看看吧
什么是Docker
Docker是一个开源的容器化平台,可以将应用程序及其依赖打包成标准化的容器,实现"一次构建,到处运行"。
核心概念:
- 镜像(Image):只读模板,包含运行应用所需的代码、库、依赖
- 容器(Container):镜像的运行实例,轻量级、可移植
- 仓库(Registry):存储和分发镜像的服务,如Docker Hub
安装Docker
macOS
1. 下载Docker Desktop
- 访问官网:https://www.docker.com/products/docker-desktop
- 根据芯片类型选择对应版本:
- Intel芯片:选择"Mac with Intel chip"
- Apple芯片:选择"Mac with Apple chip"
2. 安装步骤
# 双击下载的.dmg文件 # 将Docker图标拖动到Applications文件夹 # 从启动台打开Docker Desktop # 首次启动需要输入系统密码授权
3. 验证安装
# 查看版本 docker --version # 运行测试容器 docker run hello-world # 应该看到 "Hello from Docker!" 消息
Linux (Ubuntu)
1. 安装Docker
# 更新包索引 sudo apt update # 安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common -y # 添加Docker官方GPG密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加Docker仓库 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 # 更新包索引 sudo apt update # 安装Docker sudo apt install docker-ce docker-ce-cli containerd.io -y # 启动Docker服务 sudo systemctl start docker sudo systemctl enable docker
2. 配置用户权限(重要)
# 将当前用户添加到docker组,避免每次使用sudo sudo usermod -aG docker $USER # 使权限立即生效 newgrp docker # 或者注销后重新登录
3. 验证安装
# 查看版本 docker --version # 测试运行(无需sudo) docker run hello-world
Windows
1. 系统要求
- Windows 10/11 64位:专业版、企业版或教育版
- 必须启用Hyper-V和WSL2
2. 启用WSL2
# 以管理员身份运行PowerShell wsl --install # 重启电脑
3. 下载安装Docker Desktop
- 访问:https://www.docker.com/products/docker-desktop
- 下载Windows版本并安装
- 安装时选择"Use WSL 2 instead of Hyper-V"
4. 验证安装
docker --version docker run hello-world
基础命令
镜像操作
# 搜索镜像 docker search nginx # 拉取镜像 docker pull nginx:latest # 查看本地镜像 docker images # 删除镜像 docker rmi nginx:latest
容器操作
# 运行容器 docker run -d -p 8080:80 --name mynginx nginx # 参数说明: # -d: 后台运行 # -p: 端口映射 主机端口:容器端口 # --name: 容器名称 # 查看运行中的容器 docker ps # 查看所有容器(包括停止的) docker ps -a # 停止容器 docker stop mynginx # 启动容器 docker start mynginx # 重启容器 docker restart mynginx # 删除容器 docker rm mynginx # 查看容器日志 docker logs mynginx # 进入容器 docker exec -it mynginx /bin/bash
开始实战前的准备
环境检查
在开始实战案例之前,请先确认Docker环境配置正确:
# 1. 检查Docker是否正常运行 docker info # 如果提示权限错误,Linux用户需要执行: # sudo usermod -aG docker $USER # newgrp docker # 2. 检查Docker版本 docker --version docker-compose --version # 如果需要使用Docker Compose
端口检查
避免端口冲突,检查常用端口是否被占用:
# macOS/Linux检查端口 lsof -i :8080 # 检查8080端口 lsof -i :3000 # 检查3000端口 lsof -i :3306 # 检查3306端口(MySQL) # Windows检查端口 netstat -ano | findstr :8080 netstat -ano | findstr :3000 netstat -ano | findstr :3306 # 如果端口被占用,可以: # 1. 修改映射端口,如 -p 8081:80 # 2. 关闭占用端口的进程
清理已存在的容器
如果之前运行过示例,先清理旧容器避免命名冲突:
# 停止并删除可能存在的容器 docker rm -f mynginx myweb myapp mysql 2>/dev/null || true # 查看当前运行的容器 docker ps # 查看所有容器(包括停止的) docker ps -a
验证网络连接
确保可以正常拉取镜像:
# 测试拉取一个小镜像
docker pull alpine
# 如果速度慢,可以配置国内镜像源
# Docker Desktop: Settings → Docker Engine
# 添加:
# {
# "registry-mirrors": [
# "https://mirror.aliyuncs.com",
# "https://docker.mirrors.ustc.edu.cn"
# ]
# }实战案例
案例1:运行Nginx Web服务器
# 0. 清理可能存在的容器 docker rm -f myweb 2>/dev/null || true # 1. 拉取镜像 docker pull nginx # 2. 创建本地HTML文件 mkdir -p ~/web echo "<h1>Hello Docker!</h1>" > ~/web/index.html # 3. 运行容器并挂载目录 docker run -d \ -p 8080:80 \ -v ~/web:/usr/share/nginx/html \ --name myweb \ nginx # 4. 验证容器运行 docker ps | grep myweb echo "访问 http://localhost:8080" # 5. 测试访问 curl http://localhost:8080 # 预期输出:<h1>Hello Docker!</h1> # 6. 查看日志 docker logs myweb
验证成功标准:
- 浏览器访问 http://localhost:8080 显示 “Hello Docker!”
docker ps显示myweb容器状态为Upcurl命令返回HTML内容
### 案例2:运行MySQL数据库 ```bash # 0. 清理可能存在的容器 docker rm -f mysql 2>/dev/null || true # 1. 拉取镜像 docker pull mysql:8.0 # 2. 运行MySQL容器 docker run -d \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -e MYSQL_DATABASE=mydb \ --name mysql \ mysql:8.0 # 3. 等待MySQL启动(约10-30秒) echo "等待MySQL启动..." sleep 15 # 4. 验证容器运行 docker ps | grep mysql # 5. 查看启动日志 docker logs mysql | tail -20 # 6. 测试连接数据库 docker exec -it mysql mysql -uroot -p123456 -e "SHOW DATABASES;" # 应该能看到mydb数据库 # 7. 进入交互式命令行(可选) # docker exec -it mysql mysql -uroot -p123456
验证成功标准:
docker ps显示mysql容器状态为Up且健康- 日志中显示 “ready for connections”
SHOW DATABASES;命令能看到mydb数据库- 可以成功执行SQL查询
### 案例3:运行Node.js应用
```bash
# 0. 清理环境
docker rm -f myapp 2>/dev/null || true
docker rmi myapp 2>/dev/null || true
rm -rf myapp # 确保目录不存在
# 1. 创建项目目录
mkdir myapp && cd myapp
# 2. 创建package.json
cat > package.json << 'EOF'
{
"name": "myapp",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"express": "^4.18.0"
}
}
EOF
# 3. 创建index.js
cat > index.js << 'EOF'
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello from Docker!');
});
app.get('/health', (req, res) => {
res.json({ status: 'OK', time: new Date() });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
EOF
# 4. 创建Dockerfile
cat > Dockerfile << 'EOF'
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
EOF
# 5. 构建镜像
docker build -t myapp .
echo "镜像构建完成"
# 6. 运行容器
docker run -d -p 3000:3000 --name myapp myapp
# 7. 等待应用启动
echo "等待应用启动..."
sleep 3
# 8. 验证容器运行
docker ps | grep myapp
# 9. 查看日志
docker logs myapp
# 10. 测试访问
echo "测试主页:"
curl http://localhost:3000
echo -e "\n测试健康检查:"
curl http://localhost:3000/health验证成功标准:
- 浏览器访问 http://localhost:3000 显示 “Hello from Docker!”
- 访问 http://localhost:3000/health 返回JSON状态
docker ps显示myapp容器状态为Up- 日志显示 “Server running on port 3000”
curl命令成功返回内容
清理资源:
# 停止并删除容器 docker rm -f myapp # 删除镜像 docker rmi myapp # 删除项目目录 cd .. && rm -rf myapp
Dockerfile详解
# 基础镜像 FROM node:18-alpine # 设置工作目录 WORKDIR /app # 复制依赖文件 COPY package*.json ./ # 安装依赖 RUN npm install # 复制应用代码 COPY . . # 暴露端口 EXPOSE 3000 # 启动命令 CMD ["node", "index.js"]
指令说明:
FROM:指定基础镜像WORKDIR:设置工作目录COPY:复制文件到镜像RUN:执行命令(构建时)EXPOSE:声明端口CMD:容器启动命令
Docker Compose
管理多容器应用的工具。
docker-compose.yml示例
version: '3.8'
services:
web:
image: nginx
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:Compose命令
# 启动所有服务 docker-compose up -d # 停止所有服务 docker-compose down # 查看服务状态 docker-compose ps # 查看日志 docker-compose logs -f
数据持久化
数据卷(Volume)
# 创建数据卷 docker volume create mydata # 使用数据卷 docker run -d -v mydata:/data --name mycontainer alpine # 查看数据卷 docker volume ls # 删除数据卷 docker volume rm mydata
挂载目录(Bind Mount)
# 挂载主机目录 docker run -d -v /host/path:/container/path nginx
网络管理
基础网络操作
# 创建网络 docker network create mynetwork # 在网络中运行容器 docker run -d --network mynetwork --name web nginx docker run -d --network mynetwork --name db mysql # 容器间可通过容器名通信 # web容器可以通过 db:3306 访问mysql # 查看网络 docker network ls # 查看网络详情 docker network inspect mynetwork # 删除网络 docker network rm mynetwork
实战:容器间通信演示
这个案例演示Web应用如何通过Docker网络连接MySQL数据库:
# 0. 清理环境 docker rm -f web-app db-server 2>/dev/null || true docker network rm app-network 2>/dev/null || true # 1. 创建自定义网络 docker network create app-network # 2. 启动MySQL数据库容器 docker run -d \ --network app-network \ --name db-server \ -e MYSQL_ROOT_PASSWORD=secret123 \ -e MYSQL_DATABASE=testdb \ mysql:8.0 # 3. 等待MySQL启动 echo "等待MySQL启动..." sleep 15 # 4. 启动Web容器(使用Alpine作为演示) docker run -d \ --network app-network \ --name web-app \ alpine sleep 3600 # 5. 测试网络连通性 echo "测试容器间网络连通性:" # 5.1 测试DNS解析 docker exec web-app ping -c 3 db-server echo "DNS解析成功!" # 5.2 测试端口连通性(需要先安装nc工具) docker exec web-app sh -c "apk add --no-cache netcat-openbsd && nc -zv db-server 3306" echo "端口3306连通!" # 6. 从Web容器连接MySQL数据库 # 安装MySQL客户端 docker exec web-app sh -c "apk add --no-cache mysql-client" # 连接数据库并执行查询 docker exec web-app mysql -h db-server -uroot -psecret123 -e "SHOW DATABASES;" echo "数据库连接成功!" # 7. 查看网络详情 docker network inspect app-network # 8. 查看容器的网络配置 docker inspect web-app | grep -A 20 "Networks"
验证成功标准:
ping db-server能够成功解析并ping通nc -zv db-server 3306显示端口开放- MySQL客户端能够连接并查询数据库
docker network inspect显示两个容器都在同一网络中
重要说明:
- 同一网络中的容器可以通过容器名互相访问
- 不需要知道容器的IP地址
- 这是Docker推荐的容器间通信方式
- 容器重启后IP可能变化,但容器名不变
清理资源:
docker rm -f web-app db-server docker network rm app-network
镜像优化技巧
1. 使用多阶段构建
# 构建阶段 FROM node:18 AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 运行阶段 FROM node:18-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules CMD ["node", "dist/index.js"]
2. 减小镜像体积
- 使用alpine基础镜像
- 合并RUN命令减少层数
- 删除不必要的文件
- 使用.dockerignore排除文件
3. .dockerignore示例
node_modules npm-debug.log .git .gitignore README.md .env
常用技巧
清理Docker资源
# 删除所有停止的容器 docker container prune # 删除未使用的镜像 docker image prune # 删除未使用的数据卷 docker volume prune # 清理所有未使用资源 docker system prune -a
查看资源占用
# 查看容器资源使用 docker stats # 查看磁盘使用 docker system df
导出和导入镜像
# 导出镜像 docker save -o nginx.tar nginx:latest # 导入镜像 docker load -i nginx.tar
最佳实践
- 单一职责:每个容器只运行一个进程
- 最小化层数:合并RUN命令
- 使用缓存:将不常变化的指令放前面
- 安全性:不在镜像中存储敏感信息
- 健康检查:添加HEALTHCHECK指令
- 日志管理:合理配置日志驱动
- 资源限制:设置内存和CPU限制
故障排查
# 查看容器详细信息 docker inspect mynginx # 查看容器进程 docker top mynginx # 实时日志 docker logs -f mynginx # 复制文件 docker cp mynginx:/etc/nginx/nginx.conf ./ # 查看端口映射 docker port mynginx
常见问题FAQ
Q1: Docker启动失败或提示权限错误
问题表现:
permission denied while trying to connect to the Docker daemon socket
解决方案:
Linux系统:
# 将当前用户添加到docker组 sudo usermod -aG docker $USER # 立即生效(或注销重新登录) newgrp docker # 验证 docker run hello-world
macOS/Windows:
- 确保Docker Desktop正在运行
- 检查系统托盘中的Docker图标
- 重启Docker Desktop
Q2: 端口已被占用
问题表现:
Error: bind: address already in use
解决方案:
# macOS/Linux - 查找占用端口的进程 lsof -i :8080 # 或 sudo netstat -tulpn | grep :8080 # Windows - 查找占用端口的进程 netstat -ano | findstr :8080 # 方法1: 关闭占用端口的进程 kill -9 <PID> # 方法2: 使用不同的端口 docker run -p 8081:80 nginx # 改用8081端口
Q3: 容器无法启动或立即退出
诊断步骤:
# 1. 查看容器状态 docker ps -a # 2. 查看容器日志 docker logs 容器名 # 3. 查看详细错误信息 docker inspect 容器名 | grep -i error # 4. 尝试交互式运行查看错误 docker run -it 镜像名 /bin/sh
常见原因:
- 容器内主进程退出(CMD命令执行完毕)
- 配置文件错误
- 环境变量缺失
- 依赖服务未就绪
Q4: 镜像拉取速度很慢
解决方案:配置国内镜像源
Docker Desktop:
打开 Settings → Docker Engine,添加:
{
"registry-mirrors": [
"https://mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}Linux系统:
# 编辑配置文件
sudo vim /etc/docker/daemon.json
# 添加以下内容
{
"registry-mirrors": [
"https://mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
# 重启Docker服务
sudo systemctl daemon-reload
sudo systemctl restart dockerQ5: 容器数据丢失
问题:
容器删除后数据消失
解决方案:使用数据卷持久化
# 方法1: 使用命名数据卷
docker volume create mydata
docker run -v mydata:/app/data nginx
# 方法2: 挂载主机目录
docker run -v /host/path:/container/path nginx
# 方法3: 在docker-compose中使用
version: '3.8'
services:
app:
image: nginx
volumes:
- mydata:/data
volumes:
mydata:Q6: 无法访问容器中的服务
检查清单:
# 1. 确认容器正在运行 docker ps # 2. 检查端口映射是否正确 docker port 容器名 # 3. 检查容器内服务是否启动 docker logs 容器名 # 4. 进入容器检查 docker exec -it 容器名 /bin/sh # 在容器内测试: curl localhost:端口 # 5. 检查防火墙设置 # Linux sudo ufw status # macOS # 系统偏好设置 → 安全性与隐私 → 防火墙 # 6. 确认使用正确的访问地址 # localhost 或 127.0.0.1 或 宿主机IP
Q7: Docker占用磁盘空间过大
清理方案:
# 1. 查看磁盘占用 docker system df # 2. 删除停止的容器 docker container prune # 3. 删除未使用的镜像 docker image prune -a # 4. 删除未使用的数据卷 docker volume prune # 5. 删除未使用的网络 docker network prune # 6. 一键清理所有未使用资源 docker system prune -a --volumes # 警告:这会删除所有停止的容器、未使用的镜像和数据卷 # 7. 定期清理构建缓存 docker builder prune
Q8: 如何进入正在运行的容器
方法汇总:
# 方法1: 使用bash(推荐) docker exec -it 容器名 /bin/bash # 方法2: 使用sh(alpine镜像) docker exec -it 容器名 /bin/sh # 方法3: 直接执行命令 docker exec 容器名 ls -la /app # 方法4: 以root用户进入 docker exec -it -u root 容器名 /bin/bash # 退出容器但不停止 按 Ctrl+P 然后 Ctrl+Q
Q9: 容器时区不正确
解决方案:
# 方法1: 运行时设置环境变量 docker run -e TZ=Asia/Shanghai nginx # 方法2: 在Dockerfile中设置 FROM nginx ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 方法3: 挂载主机时区文件 docker run -v /etc/localtime:/etc/localtime:ro nginx
Q10: 容器与宿主机网络不通
排查步骤:
# 1. 检查Docker网络模式 docker inspect 容器名 | grep NetworkMode # 2. 测试容器访问外网 docker exec 容器名 ping 8.8.8.8 # 3. 测试容器访问宿主机 # 使用特殊DNS名称访问宿主机 docker exec 容器名 ping host.docker.internal # 4. 使用host网络模式(谨慎使用) docker run --network host nginx # 5. 检查iptables规则(Linux) sudo iptables -L -n
快速参考:常用排查命令
# 查看容器详细信息 docker inspect 容器名 # 查看容器日志(实时) docker logs -f 容器名 # 查看容器资源使用 docker stats 容器名 # 查看容器进程 docker top 容器名 # 复制文件到/从容器 docker cp 容器名:/path/file ./ docker cp ./file 容器名:/path/ # 查看Docker系统信息 docker info # 查看Docker版本 docker version
总结
Docker核心工作流程:
- 编写Dockerfile定义镜像
- 使用
docker build构建镜像 - 使用
docker run运行容器 - 使用
docker-compose管理多容器应用
掌握这些基础知识,你就可以开始使用Docker进行应用容器化部署了。
到此这篇关于Docker容器化部署入门全面指南的文章就介绍到这了,更多相关docker容器化部署内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
