docker
Docker 介绍
Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口,与虚拟机相似,但是占用资源更少。一台主机一般只能运行几十台虚拟机,但是可以同时运行几百上千个容器。
什么是容器?(Container)
容器就是将应用程序及其依赖,打包在一个文件系统中,包含了一切运行所需的东西,如代码、运行时、系统工具、系统库等,保证应用在任何环境下都能运行。容器是独立于平台的,可以在开发环境、测试环境、生产环境中运行。
为什么使用 Docker?
在没有容器之前,开发人员在开发环境中编写代码,然后将代码部署到测试环境,最后再部署到生产环境。这种方式存在很多问题,如环境不一致、部署麻烦、开发环境和生产环境不一致等。Docker 的出现解决了这些问题,使得开发、测试、生产环境一致,提高了开发效率。
Docker 的优势
- 快速交付:Docker 可以快速部署,可以在几秒或者几十秒内启动或停止容器。
- 一致运行环境:Docker 可以保证开发环境、测试环境、生产环境一致。
- 高效利用系统资源:Docker 可以在一台主机上运行多个容器,提高资源利用率。
- 轻量级:Docker 利用容器共享主机内核,不需要运行完整的操作系统,因此比虚拟机更轻量级。
- 易于维护:Docker 可以快速部署、快速启动、快速停止,维护成本低。
- 可移植性:Docker 可以在任何平台上运行。
- 开源:Docker 是开源的,社区活跃,有大量的镜像可以使用。
- 安全:Docker 使用沙箱机制,相互之间不会有任何接口,提高了安全性。
- 生态丰富:Docker 生态丰富,有大量的工具可以使用。
- 持续集成:Docker 可以与持续集成工具结合,实现持续集成。
- 快速扩展:Docker 可以快速扩展,可以根据需求快速增加或减少容器。
常用 Docker 命令
描述 | 命令 |
---|---|
查看 Docker 版本 | docker --version |
查看 Docker 信息 | docker info |
查看 Docker 镜像 | docker images |
查看 Docker 容器 | docker ps 或 docker ps -a |
拉取镜像 | docker pull 镜像名称 |
运行容器 | docker run -it 镜像名称 |
启动容器 | docker start 容器ID |
停止容器 | docker stop 容器ID |
重启容器 | docker restart 容器ID |
进入容器 | docker exec -it 容器ID /bin/bash |
删除容器 | docker rm 容器ID |
删除镜像 | docker rmi 镜像ID |
查看容器日志 | docker logs -f 容器ID |
Dockerfile
相关信息
Dockerfile 是一个用来构建 Docker 镜像的文本文件,其中包含了一系列构建镜像所需的指令和参数。通过 Dockerfile,你可以定义镜像的基础环境、安装软件、配置系统参数、添加应用程序代码等步骤,从而自动化镜像的创建过程。
主要作用
- 自动化构建:避免手动配置环境,确保每次构建的镜像都相同。
- 版本控制:Dockerfile 可以纳入版本控制系统,便于团队协作和问题追踪。
- 可重复性:相同的 Dockerfile 多次构建结果一致。
基本结构
一个简单的 Dockerfile 通常包含以下部分:
# 指定基础镜像
FROM ubuntu:20.04
# 设置工作目录
WORKDIR /app
# 安装依赖
RUN apt-get update && apt-get install -y \
python3 \
python3-pip
# 复制应用代码
COPY . .
# 安装应用依赖
RUN pip3 install -r requirements.txt
# 暴露端口
EXPOSE 8000
# 定义启动命令
CMD ["python3", "app.py"]
常用指令
- FROM:指定基础镜像。
- RUN:执行命令(如安装软件)。
- COPY/ADD:复制文件或目录到镜像中。
- WORKDIR:设置工作目录。
- ENV:设置环境变量。
- CMD:定义容器启动时执行的命令。
- ENTRYPOINT:配置容器启动时的执行命令(与 CMD 配合使用)。
- EXPOSE:声明容器运行时监听的端口。
构建与使用
使用以下命令构建镜像:
docker build -t my-app .
其中:
-t my-app
:指定镜像标签为my-app
.
:表示使用当前目录的 Dockerfile
构建完成后,可以使用以下命令运行容器:
docker run -p 8000:8000 my-app
Docker Compose
简介
Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一个 YAML 文件(docker-compose.yml
)配置应用服务,只需一个命令即可创建并启动所有服务。
核心概念
- 服务(Service):一个容器化的应用实例,定义了容器如何运行(如镜像、端口、依赖等)。
- 项目(Project):由多个服务组成的完整应用,通过
docker-compose.yml
配置。
支持的字段
以下是 Docker Compose YAML 配置文件中常用字段的整理表格,涵盖版本 3.x 的核心语法:
1. 顶级字段
字段名 | 描述 | 示例 |
---|---|---|
services | 定义应用的服务(容器) | services:\n web:\n ... |
networks | 定义自定义网络 | networks:\n backend:\n ... |
volumes | 定义数据卷 | volumes:\n data:\n ... |
secrets | 定义敏感数据(如密码、证书) | secrets:\n db_password:\n ... |
configs | 定义配置文件 | configs:\n nginx_conf:\n ... |
2. services
字段
字段名 | 描述 | 示例 |
---|---|---|
image | 指定服务使用的镜像 | image: redis:alpine |
build | 构建镜像的配置(路径或上下文) | build: ./app 或 build:\n context: .\n dockerfile: Dockerfile.dev |
command | 覆盖容器启动时默认执行的命令 | command: ["python", "app.py"] |
environment | 设置环境变量(列表或字典形式) | environment:\n - DEBUG=1\n - DB_HOST=db 或 environment:\n DEBUG: 1\n DB_HOST: db |
env_file | 从文件加载环境变量 | env_file:\n - .env.production |
ports | 端口映射(宿主机:容器) | ports:\n - "8080:80" |
expose | 暴露端口(仅内部网络可见) | expose:\n - "3000" |
volumes | 挂载数据卷或目录 | volumes:\n - ./data:/app/data\n - cache:/tmp/cache |
networks | 指定服务连接的网络 | networks:\n - frontend\n - backend |
depends_on | 定义服务依赖关系(控制启动顺序) | depends_on:\n - db\n - redis |
links | 链接到其他服务(仅用于 legacy 网络) | links:\n - db:database |
restart | 重启策略 | restart: always 或 restart: unless-stopped |
deploy | 部署配置(仅在 Swarm 模式下生效) | deploy:\n replicas: 3\n resources:\n limits:\n cpus: '0.50'\n memory: 512M |
healthcheck | 容器健康检查配置 | healthcheck:\n test: ["CMD", "curl", "-f", "http://localhost"]\n interval: 30s\n timeout: 10s |
secrets | 挂载敏感数据 | secrets:\n - db_password |
configs | 挂载配置文件 | configs:\n - source: my_config\n target: /etc/config |
stop_grace_period | 优雅停止容器的等待时间 | stop_grace_period: 1m30s |
3. networks
字段
字段名 | 描述 | 示例 |
---|---|---|
driver | 指定网络驱动类型(如 bridge , overlay ) | driver: bridge |
driver_opts | 驱动程序选项 | driver_opts:\n com.docker.network.driver.mtu: 1400 |
attachable | 允许非 swarm 容器连接到网络 | attachable: true |
external | 使用已存在的网络 | external: true |
4. volumes
字段
字段名 | 描述 | 示例 |
---|---|---|
driver | 指定卷驱动类型(如 local ) | driver: local |
driver_opts | 驱动程序选项 | driver_opts:\n type: 'nfs'\n o: 'addr=10.40.0.199,rw'\n device: ':/docker/volumes/mysql' |
external | 使用已存在的数据卷 | external: true |
name | 指定卷名称(覆盖默认生成的名称) | name: my-app-data |
5. secrets
字段
字段名 | 描述 | 示例 |
---|---|---|
file | 从文件读取 secret 内容 | file: ./mysecret.txt |
external | 使用已存在的 secret | external: true |
6. configs
字段
字段名 | 描述 | 示例 |
---|---|---|
file | 从文件读取配置内容 | file: ./nginx.conf |
external | 使用已存在的配置 | external: true |
7. 其他常用字段
字段名 | 描述 | 示例 |
---|---|---|
extends | 继承另一个服务的配置 | extends:\n file: common.yml\n service: web |
scale | 指定服务启动的容器数量 | scale: 3 |
hostname | 设置容器的主机名 | hostname: myservice |
user | 指定运行容器的用户/UID | user: node 或 user: 1000:1000 |
working_dir | 设置容器内的工作目录 | working_dir: /app |
stdin_open | 保持标准输入打开 | stdin_open: true |
tty | 分配伪终端 | tty: true |
注意事项
- 版本兼容性:某些字段(如
deploy
)仅在特定版本或 Swarm 模式下可用。 - 缩进要求:YAML 对缩进敏感,建议使用 2 个空格缩进。
- 环境变量:可使用
${VARIABLE}
引用环境变量(如端口、密码)。 - 注释:使用
#
添加注释,提高配置文件可读性。
docker-compose.yml
文件例子
一个简单的 Web 应用示例:
services:
web:
build: . # 使用当前目录的 Dockerfile 构建镜像
ports:
- "5000:5000" # 映射容器端口到宿主机
volumes:
- .:/code # 挂载当前目录到容器内的 /code
depends_on:
- redis # 依赖 redis 服务
environment:
- FLASK_ENV=development # 设置环境变量
redis:
image: "redis:alpine" # 使用官方 Redis 镜像
volumes:
- redis-data:/data # 挂载数据卷
volumes:
redis-data: # 定义数据卷
常用命令
启动服务
# 在前台启动,显示日志
docker-compose up
# 在后台启动
docker-compose up -d
# 只启动特定服务
docker-compose up web
停止服务
# 停止并移除容器、网络
docker-compose down
# 停止并移除容器、网络、数据卷
docker-compose down -v
# 停止服务(保留容器)
docker-compose stop
查看状态
# 查看运行中的容器
docker-compose ps
# 查看服务日志
docker-compose logs
# 查看特定服务日志
docker-compose logs web
管理容器
# 进入容器内部
docker-compose exec web bash
# 构建或重建服务镜像
docker-compose build
# 重启服务
docker-compose restart
# 扩展服务实例
docker-compose up -d --scale web=3 # 启动 3 个 web 容器
环境变量与配置
使用 .env
文件
在项目根目录创建 .env
文件:
DB_HOST=localhost
DB_USER=admin
DB_PASSWORD=secret
在 docker-compose.yml
中引用:
services:
db:
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
多环境配置
使用 docker-compose.override.yml
覆盖默认配置:
# docker-compose.override.yml
services:
web:
ports:
- "80:5000" # 生产环境使用 80 端口
environment:
- FLASK_ENV=production
网络与数据卷
网络
Compose 自动创建默认网络,服务间可通过服务名互相访问(如 web
可访问 redis
)。
数据卷
volumes:
- data-volume:/var/lib/mysql # 命名卷
- ./data:/var/lib/mysql # 绑定挂载
实战示例
部署 WordPress
version: '3'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
db:
image: mysql:5.7
volumes:
- db:/var/lib/mysql
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
wordpress:
db:
注意
- 服务拆分:每个服务专注单一功能(如 Web、数据库、缓存分离)。
- 使用
.dockerignore
:排除不必要的文件,加快镜像构建。 - 避免硬编码:通过环境变量配置敏感信息。
- 版本控制:将
docker-compose.yml
纳入版本控制,但忽略数据卷。