用Docker搭建开发环境,如何方便管理呢?

用Docker作用开发环境,是每个应用都用单独的容器,还是在容器里安装所有再打包成一个Image呢?

另外,比如多个项目对mysql版本要求不一样,想快速切换,哪种更方便呢?例:

项目A是5.7、项目B是8.4等。当处理项目A问题时启动5.7,项目B启动8.4。

要把所有用到的服务+多版本都写在一个docker-compose里吗?依赖比较混乱,怎么做才能更方便启动服务且避免一次启动用不到的呢。

使用了docker-compose

阅读 3.4k
avatarAI BotBETA

回答

使用 Docker 搭建开发环境时,管理多个容器和服务可以通过以下几种方式来实现高效和灵活性:

  1. 每个应用使用单独的容器

    • 推荐做法:每个应用或服务(如前端、后端、数据库等)都运行在单独的 Docker 容器中。这样做的好处是隔离性强,便于管理和扩展。
    • 优点:独立的环境可以避免依赖冲突,易于升级和回滚。
  2. 多版本数据库管理

    • 使用 Docker 镜像标签:为每个项目使用不同版本的 MySQL 镜像。例如,项目 A 使用 mysql:5.7,项目 B 使用 mysql:8.4
    • docker-compose 文件:为每个项目创建单独的 docker-compose.yml 文件,指定所需的 MySQL 版本和其他服务。
    • 动态切换:通过启动不同的 docker-compose 文件来快速切换 MySQL 版本。
  3. docker-compose 的使用

    • 多文件策略:不要将所有服务和多版本都写在一个 docker-compose.yml 文件中。相反,为每个项目或一组相关服务创建一个单独的 docker-compose.yml 文件。
    • 避免不必要的启动:通过命令行参数指定要启动的服务,避免一次性启动所有服务。例如,使用 docker-compose up -d mysql 只启动 MySQL 服务。
    • 环境变量:利用 .env 文件或环境变量来管理不同项目之间的配置差异,如数据库连接字符串等。
  4. 其他管理技巧

    • Docker 网络:使用 Docker 网络来连接不同容器,确保它们之间可以安全通信。
    • Docker Compose 配置文件拆分:利用 docker-compose.override.yml 或其他扩展文件来拆分和管理配置。
    • 文档和版本控制:为 docker-compose.yml 文件和其他 Docker 相关配置编写文档,并将其纳入版本控制系统,以便团队协作和版本追踪。

综上所述,每个应用使用单独的容器是推荐的做法,而多版本数据库管理可以通过使用不同版本的 Docker 镜像和单独的 docker-compose.yml 文件来实现。避免将所有服务和多版本都写在一个 docker-compose.yml 文件中,而是采用多文件策略来管理不同项目的配置和依赖。

2 个回答

1. 创建环境变量文件

创建两个环境变量文件,分别为 projectA.envprojectB.env

projectA.env

MYSQL_VERSION=5.7
MYSQL_ROOT_PASSWORD=exampleA
NGINX_VERSION=latest
REDIS_VERSION=latest

projectB.env

MYSQL_VERSION=8.4
MYSQL_ROOT_PASSWORD=exampleB
NGINX_VERSION=stable
REDIS_VERSION=latest

2. 修改 docker-compose.yml 文件

使用环境变量来配置服务:

version: '3.8'
services:
  mysql:
    image: mysql:${MYSQL_VERSION}
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

  nginx:
    image: nginx:${NGINX_VERSION}
    ports:
      - "8080:80"

  redis:
    image: redis:${REDIS_VERSION}
    ports:
      - "6379:6379"

volumes:
  mysql-data:

3. 创建启动脚本

编写一个shell脚本,根据项目需求启动相应的服务:

#!/bin/bash

if [ "$1" == "projectA" ]; then
  docker-compose --env-file projectA.env up -d
elif [ "$1" == "projectB" ]; then
  docker-compose --env-file projectB.env up -d
else
  echo "Usage: $0 {projectA|projectB}"
fi

将这个脚本保存为 start_project.sh,并赋予执行权限:

chmod +x start_project.sh

4. 启动服务

使用脚本启动相应项目的服务:

./start_project.sh projectA

或者:

./start_project.sh projectB

首先建议独立项目独立的 yml 文件
可以通过自己撰写一个脚本文件或者不同的脚本文件来决定访问哪个 docker compose yml

#!/bin/bash

SELF=$(basename "${0}")
SELF_DIR=$(realpath $(dirname "${0}"))
YML_PATH=$(realpath "${SELF_DIR}"/../yml)

if [ -z "${1}" ]; then
    echo "Usage:"
    echo "/opt/service/bin/myservice GROUP [COMMAND]"
    echo "Example:"
    echo "/opt/service/bin/myservice groupA ps"
    echo "/opt/service/bin/myservice groupB up -d"
    exit 1
fi

YML_NAME="${1}"
PROJECT_NAME=$(echo ${YML_NAME} | sed 's/[^a-zA-Z0-9_-]/_/g')

# 兼顾了 docker compose 和 docker-compose 两种情况
if docker compose version >/dev/null 2>&1; then
    set -x
    docker compose -f ${YML_NAME} -p ${PROJECT_NAME} "${@}"
else
    set -x
    docker-compose -f ${YML_NAME} -p ${PROJECT_NAME} "${@}"
fi

把这个脚本保存为 /opt/service/bin/myservice
yml 位于:/opt/service/yml
运行 /opt/service/bin/myservice groupA ps 相当于对应:docker compose -f /opt/service/yml/groupA.yml -p groupA ps
为了方便实用可以自行把 /opt/service/bin/ 加入你的 PATH 环境变量


如果这个条件不具备,必须要把所有服务放到一个 yml 文件中,你可以考虑 docker compose 的 profile 特性:

https://docs.docker.com/compose/how-tos/profiles/

官网文档有例子:

services:
  frontend:
    image: frontend
    profiles: [frontend]

  phpmyadmin:
    image: phpmyadmin
    depends_on: [db]
    profiles: [debug]

  backend:
    image: backend

  db:
    image: mysql

启动所有 debug 标记的服务(以及它们的依赖):docker compose --profile debug up -d

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏