🐳 Docker 学习笔记
返回首页
技术分享
2025-12-20
🎯 学习目标
通过本笔记掌握Docker的核心概念、常用命令和实际应用场景,提升容器化部署能力。
📖 简介
Docker是一个开源的容器化平台,让开发者能够打包应用及其依赖包到一个可移植的容器中。
🔗 相关链接
🚀 安装配置
基础安装
apt install docker.io
配置镜像加速器
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.imgdb.de",
"https://docker-0.unsee.tech",
"https://docker.hlmirror.com",
"https://docker.1ms.run",
"https://func.ink",
"https://lispy.org",
"https://docker.xiaogenban1993.com"
]
}
EOF
重启Docker服务
systemctl daemon-reload
systemctl restart docker
⚡ 常用命令
📦 镜像相关命令
🔍 查看镜像
docker images
输出说明:
REPOSITORY:镜像名称TAG:镜像标签IMAGE ID:镜像IDCREATED:镜像的创建日期SIZE:镜像大小
🔎 搜索镜像
docker search 镜像名称
输出说明:
NAME:仓库名称DESCRIPTION:镜像描述STARS:下载数量OFFICAL:是否官方AUTOMATED:自动构建
⬇️ 拉取镜像
docker pull 镜像名称
🗑️ 删除镜像
# 删除单个镜像
docker rmi 镜像ID
# 删除所有镜像
docker rmi `docker images -q`
🏗️ 容器相关命令
👀 查看容器
# 查看正在运行的容器
docker ps
# 查看全部容器
docker ps -a
# 查看最后一次运行的容器
docker ps -f status=exited
▶️ 启动容器
docker run [参数] 镜像名:标签 [命令]
常用参数:
-i:表示运行容器-t:表示进入命令行--name:为创建的容器命名-d:守护式容器(后台运行)-p:映射端口
示例:
# 交互式启动容器
docker run -it --name=centos centos:7 /bin/bash
# 守护式启动容器
docker run -di --name=centos centos:7
# 进入守护式容器
docker exec -it 容器名称 /bin/bash
🔄 容器管理
# 停止容器
docker stop 容器名/容器ID
# 启动容器
docker start 容器名/容器ID
# 退出容器
exit
📁 文件传输
# 从主机复制文件到容器
docker cp 文件路径 容器ID/名称:容器内路径
# 从容器复制文件到主机
docker cp 容器ID/名称:容器内路径 主机路径
📂 目录挂载
docker run -di -v 主机目录:容器目录 --name=容器名称 镜像名
示例:
docker run -di -v /usr/local/test:/usr/local/test --name=test centos:7
🗑️ 删除容器
docker rm 容器ID/容器名称
🌐 应用部署实战
🗄️ MySQL部署
# 拉取MySQL镜像
docker pull mysql:5.7
# 启动MySQL容器
docker run -di --name=mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=toor \
mysql:5.7
🌍 Nginx部署
# 拉取Nginx镜像
docker pull nginx
# 启动Nginx容器
docker run -di --name=nginx -p 80:80 nginx
# 带配置文件挂载的Nginx
docker run -di --name=nginx \
-p 80:80 \
-v /usr/local/nginx:/etc/nginx \
nginx
🔴 Redis部署
# 拉取Redis镜像
docker pull redis
# 启动Redis容器
docker run -di --name=redis -p 6379:6379 redis
🐰 RabbitMQ部署
# 拉取RabbitMQ镜像
docker pull rabbitmq:3.7.12
# 启动RabbitMQ容器
docker run -di --name=rabbitmq \
-p 5671:5671 \
-p 5672:5672 \
-p 4369:4369 \
-p 25672:25672 \
-p 15671:15671 \
-p 15672:15672 \
rabbitmq:3.7.12
# 进入容器启用管理插件
docker exec -it rabbitmq /bin/bash
rabbitmq-plugins enable rabbitmq_management
💾 备份与迁移
📦 容器保存为镜像
# 将容器保存为新镜像
docker commit 容器名 新镜像名
# 导出镜像到文件
docker save -o 镜像名.tar 镜像名
# 从文件导入镜像
docker load -i 镜像名.tar
📝 Dockerfile
Dockerfile是一个文本文件,包含了一系列指令,用于自动构建Docker镜像。
🏗️ 基本语法
# 基础镜像
FROM 镜像名:标签
# 维护者信息
MAINTAINER 作者 <邮箱>
# 设置工作目录
WORKDIR /app
# 复制文件
COPY 源路径 目标路径
# 添加文件(支持解压)
ADD 源文件 目标路径
# 运行命令
RUN 命令
# 设置环境变量
ENV 键=值
# 暴露端口
EXPOSE 端口号
# 容器启动命令
CMD ["命令", "参数1", "参数2"]
# 入口点
ENTRYPOINT ["命令", "参数1"]
📋 常用指令详解
FROM - 基础镜像
FROM ubuntu:20.04
FROM node:16-alpine
WORKDIR - 工作目录
WORKDIR /app
# 相当于 cd /app
COPY vs ADD
# COPY - 简单复制文件
COPY ./app.js /app/
COPY ./package*.json ./
# ADD - 支持URL和解压
ADD https://example.com/file.tar.gz /tmp/
ADD app.tar.gz /app/ # 自动解压
RUN - 执行命令
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
RUN npm install
ENV - 环境变量
ENV NODE_ENV=production
ENV APP_VERSION=1.0.0
EXPOSE - 暴露端口
EXPOSE 3000
EXPOSE 8080
CMD vs ENTRYPOINT
# CMD - 可以被docker run覆盖
CMD ["node", "app.js"]
# ENTRYPOINT - 固定入口点
ENTRYPOINT ["node"]
CMD ["app.js"] # 作为ENTRYPOINT的参数
🎯 实战示例
Node.js应用Dockerfile
FROM node:16-alpine
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
# 更改文件所有者
RUN chown -R nodejs:nodejs /app
USER nodejs
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# 启动应用
CMD ["node", "app.js"]
Python应用Dockerfile
FROM python:3.9-slim
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制requirements文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8000
# 启动应用
CMD ["python", "app.py"]
多阶段构建
# 构建阶段
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
# 复制构建结果
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制nginx配置
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
🔧 构建镜像
# 构建镜像
docker build -t 镜像名:标签 .
# 构建时指定Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .
# 构建时传递参数
docker build --build-arg VERSION=1.0.0 -t myapp .
🐙 Docker Compose
Docker Compose用于定义和运行多容器Docker应用程序的工具。
📄 docker-compose.yaml基本结构
version: '3.8' # 版本号
services: # 服务定义
服务名:
build: ./目录 # 构建配置
image: 镜像名:标签 # 使用镜像
ports: # 端口映射
- "主机端口:容器端口"
volumes: # 卷挂载
- 主机路径:容器路径
environment: # 环境变量
- 键=值
depends_on: # 依赖关系
- 其他服务名
networks: # 网络配置
- 网络名
volumes: # 数据卷定义
卷名:
networks: # 网络定义
网络名:
driver: bridge
🎯 常用配置选项
服务配置详解
services:
web:
# 构建配置
build:
context: ./web # 构建上下文
dockerfile: Dockerfile # Dockerfile路径
args: # 构建参数
VERSION: "1.0"
# 镜像配置
image: nginx:alpine
container_name: my-web
# 端口配置
ports:
- "8080:80"
- "443:443"
# 环境变量
environment:
- NODE_ENV=production
- DB_HOST=db
- REDIS_URL=redis://redis:6379
# 环境变量文件
env_file:
- .env
- .env.production
# 卷挂载
volumes:
- ./html:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- static_volume:/var/www/static
# 依赖关系
depends_on:
- db
- redis
# 网络配置
networks:
- frontend
- backend
# 重启策略
restart: unless-stopped
# 健康检查
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
🌐 实战示例
Web应用完整配置
version: '3.8'
services:
# Web服务
web:
build: .
container_name: myapp-web
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=5432
- DB_NAME=myapp
- DB_USER=postgres
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
networks:
- app-network
restart: unless-stopped
# 数据库服务
db:
image: postgres:13
container_name: myapp-db
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secretpassword
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
networks:
- app-network
restart: unless-stopped
# Redis服务
redis:
image: redis:6-alpine
container_name: myapp-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- app-network
restart: unless-stopped
command: redis-server --appendonly yes
# Nginx反向代理
nginx:
image: nginx:alpine
container_name: myapp-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- web
networks:
- app-network
restart: unless-stopped
# 数据卷定义
volumes:
postgres_data:
redis_data:
# 网络定义
networks:
app-network:
driver: bridge
开发环境配置
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
- /app/node_modules # 防止node_modules被覆盖
ports:
- "3000:3000"
- "9229:9229" # Node.js调试端口
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true # 支持热重载
command: npm run dev
depends_on:
- db
- redis
networks:
- dev-network
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=devdb
ports:
- "3306:3306"
volumes:
- mysql_dev_data:/var/lib/mysql
networks:
- dev-network
redis:
image: redis:6-alpine
ports:
- "6379:6379"
networks:
- dev-network
volumes:
mysql_dev_data:
networks:
dev-network:
driver: bridge
⚡ 常用命令
# 启动所有服务(后台运行)
docker-compose up -d
# 启动指定服务
docker-compose up -d web
# 启动并查看日志
docker-compose up
# 停止所有服务
docker-compose down
# 停止并删除数据卷
docker-compose down -v
# 停止并删除镜像
docker-compose down --rmi all
# 重新构建并启动
docker-compose up -d --build
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs
docker-compose logs -f web # 实时查看web服务日志
docker-compose logs --tail=100 # 查看最后100行
# 进入容器
docker-compose exec web bash
docker-compose exec db mysql -u root -p
# 执行命令
docker-compose run web npm run test
# 扩展服务
docker-compose up -d --scale web=3
# 查看资源使用
docker-compose top
🔧 高级配置
环境变量文件
# .env文件
NODE_ENV=production
DB_HOST=db
DB_PORT=5432
DB_NAME=myapp
DB_USER=postgres
DB_PASSWORD=secretpassword
覆盖配置
# docker-compose.override.yml
version: '3.8'
services:
web:
volumes:
- ./src:/app/src # 开发时挂载源码
environment:
- NODE_ENV=development
command: npm run dev
生产环境配置
# docker-compose.prod.yml
version: '3.8'
services:
web:
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
🔒 Docker私有仓库
Docker私有仓库用于存储和管理自定义的Docker镜像。
🏗️ 搭建私有仓库
使用官方Registry镜像
# 拉取Registry镜像
docker pull registry
# 启动私有仓库
docker run -di --name=registry \
-p 5000:5000 \
-v /opt/registry:/var/lib/registry \
registry
# 启动带认证的私有仓库
docker run -di --name=registry-auth \
-p 5000:5000 \
-v /opt/registry:/var/lib/registry \
-v /opt/auth:/auth \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry
配置认证
# 安装htpasswd工具
apt install apache2-utils
# 创建认证文件
htpasswd -Bbn testuser testpass > /opt/auth/htpasswd
🔧 配置Docker客户端
# 修改Docker配置文件
vi /etc/docker/daemon.json
{
"insecure-registries": ["私有仓库IP:5000"]
}
# 重启Docker
systemctl restart docker
📦 推送和拉取镜像
# 标记镜像
docker tag 本地镜像名:标签 私有仓库IP:5000/镜像名:标签
# 推送镜像
docker push 私有仓库IP:5000/镜像名:标签
# 拉取镜像
docker pull 私有仓库IP:5000/镜像名:标签
# 查看仓库中的镜像
curl http://私有仓库IP:5000/v2/_catalog
🔧 Docker Maven插件
Docker Maven插件用于在Maven构建过程中自动构建和推送Docker镜像。
📝 插件配置
pom.xml配置
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<configuration>
<repository>your-registry/${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
Dockerfile示例
FROM openjdk:11-jre-slim
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
⚡ Maven命令
# 构建Docker镜像
mvn dockerfile:build
# 推送镜像到仓库
mvn dockerfile:push
# 构建并推送
mvn dockerfile:build dockerfile:push
# 指定标签
mvn dockerfile:build -Ddockerfile.tag=latest
# 强制重建
mvn dockerfile:build -Ddockerfile.noCache
🎯 高级配置
多环境配置
<profiles>
<profile>
<id>dev</id>
<properties>
<docker.registry>localhost:5000</docker.registry>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<docker.registry>registry.example.com</docker.registry>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<configuration>
<repository>${docker.registry}/${project.artifactId}</repository>
<tag>${project.version}</tag>
</configuration>
</plugin>
</plugins>
</build>