Docker Compose 从入门到放弃:解读 docker-compose.yml 配置与使用

Docker Compose 是一个非常强大的工具,用于定义和管理多容器 Docker 应用。它使用一个简单的 YAML 文件来配置应用程序的服务,并允许通过一条命令来启动、停止和管理应用。本文将详细讲解 Docker Compose 的核心配置文件 docker-compose.yml,包括其中的各种参数、示例、容器间关联、网络配置、注意事项等,帮助你全面理解和掌握 Docker Compose 的使用。

什么是 docker-compose.yml?

docker-compose.yml 是 Docker Compose 使用的配置文件,通过该文件,我们可以定义一组相关的 Docker 容器服务。文件使用 YAML 格式(缩进非常重要),可以描述服务、网络、卷等内容。我们将从各个主要部分来讲解其功能。

基本结构

一个最基础的 docker-compose.yml 文件大致如下:

version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example

版本 (version)

version 用于指定 docker-compose.yml 文件所遵循的 Compose 文件版本,通常建议使用最新的版本,例如 version: '3'。版本不同,支持的配置参数也可能有所不同。

服务 (services)

services 是整个配置文件的核心,定义了你所使用的各个服务(即容器)。在上面的例子中,我们定义了两个服务:webdb,它们分别运行 nginxmysql

各个字段的详细讲解

image

指定服务所使用的 Docker 镜像,例如:

image: nginx:latest

nginx:latest 表示使用最新版本的 Nginx 镜像。

build

用于指定构建镜像的上下文。它可以指定一个 Dockerfile 或者目录路径:

build:
  context: ./myapp
  dockerfile: Dockerfile.dev
  • context:指定上下文路径,Dockerfile 中的所有路径都是相对于此路径的。
  • dockerfile:指定构建使用的 Dockerfile。
ports

用于将主机和容器之间的端口进行映射:

ports:
  - "8080:80"

这意味着将宿主机的 8080 端口映射到容器内的 80 端口。

environment

可以传递环境变量给容器,例如设置数据库的密码:

environment:
  MYSQL_ROOT_PASSWORD: example

支持直接使用 .env 文件中的环境变量:

env_file:
  - .env
volumes

用于挂载卷,将主机的目录或文件映射到容器内,持久化存储或共享数据:

volumes:
  - ./data:/var/lib/mysql

这意味着将宿主机的 ./data 目录映射到容器内的 /var/lib/mysql 目录。

depends_on

用于定义服务的依赖关系,确保按顺序启动。比如:

depends_on:
  - db

这确保 web 服务在 db 启动之后再启动。

注意depends_on 只控制启动顺序,并不确保依赖服务完全准备好(例如数据库完全启动并能够接受连接)。为确保这一点,可以在应用中实现健康检查机制。

networks

定义容器之间的网络隔离,多个服务可以加入同一个网络进行通信:

networks:
  default:
    driver: bridge

可以指定网络类型(如 bridgeoverlay),bridge 是 Docker 的默认网络驱动。

command

覆盖默认的容器启动命令:

command: ["npm", "start"]

这个示例会覆盖 Dockerfile 中的 CMD 命令。

restart

定义容器的重启策略,比如:

restart: always
  • no:不自动重启(默认)。
  • always:容器停止时总是重启。
  • on-failure:仅在非零状态退出时重启。
  • unless-stopped:除非手动停止,否则会自动重启。
healthcheck

用于定义服务的健康检查,确保容器正确启动并运行:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m
  timeout: 10s
  retries: 3

这会定期检查容器的健康状态,如果失败了,它可以在指定的重试次数后自动重启容器。

logging

配置服务的日志选项:

logging:
  driver: "json-file"
  options:
    max-size: "200k"
    max-file: "10"

通过 max-sizemax-file 限制日志大小。

多容器应用示例

示例 1:WordPress 与 MySQL 的多容器应用
version: '3'
services:
  wordpress:
    image: wordpress
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
    depends_on:
      - db
    volumes:
      - wordpress_data:/var/www/html

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: examplepass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
    volumes:
      - db_data:/var/lib/mysql

volumes:
  wordpress_data:
  db_data:
示例 2:React + Nginx + Node.js 的前后端应用
version: '3'
services:
  frontend:
    build:
      context: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/src:/app/src
    depends_on:
      - backend
    networks:
      - app-network

  backend:
    build:
      context: ./backend
    ports:
      - "5000:5000"
    networks:
      - app-network
    environment:
      DATABASE_URL: mongodb://mongo:27017/mydb

  mongo:
    image: mongo
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
    networks:
      - app-network

volumes:
  mongo-data:

networks:
  app-network:

网络配置与副作用

Docker Compose 默认使用 bridge 网络驱动来连接容器。当多个服务被定义在同一个网络下时,它们可以通过服务名称相互访问,而不需要 IP 地址。例如,在上面的例子中,backend 服务可以通过 mongodb://mongo:27017/mydb 连接到 mongo 容器。

默认网络与自定义网络

如果不显式定义网络,Compose 会创建一个默认的网络,并将所有服务加入其中。自定义网络可以更好地控制容器之间的通信隔离和路由。

网络隔离与副作用

当容器被加入不同的网络时,它们之间是隔离的,无法相互通信。这种隔离机制可以用于提高安全性,防止未经授权的服务访问。

运行与管理

启动应用

使用以下命令启动 Compose 定义的服务:

docker-compose up

使用 -d 参数可以在后台运行服务:

docker-compose up -d
停止应用

使用以下命令停止服务并删除容器:

docker-compose down

如果你想同时删除网络、卷,可以使用 -v 参数:

docker-compose down -v
查看日志

查看某个服务的日志:

docker-compose logs <service_name>

注意事项

  1. 版本选择:尽量使用最新的 Compose 文件版本来获得最新的功能。
  2. 容器间通信:确保服务加入同一个网络,才能够相互通信。
  3. 持久化存储:使用 volumes 挂载本地目录或数据卷,防止数据丢失。
  4. 健康检查:为关键服务定义 healthcheck,确保服务正常运行。
  5. 环境变量管理:尽量使用 .env 文件来管理敏感信息和环境变量。

标签: Docker

相关文章

在1Panel中解决Docker内PHP网络请求超时问题

在1Panel管理面板中,我们可能会遇到在使用Docker运行的PHP环境中发起网络请求时出现的超时问题。最近给博客写了一个远程请求插件,之前还是正常,这两天突然请求500错误了...问题分析当...

编译最新的kkFileView并使用docker打包

kkFileView 是一个开源的文件预览服务,支持多种文件格式的在线预览。本文将详细介绍如何编译 kkFileView 的最新版本,并将其打包成 Docker 镜像。1. 环境准备在开始之前,...

整理一些Docker运维中常用的命令

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。以下是一些在 Docker 运维中常...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件