From 7c93222bd36ba61c5e8c5ad962497951667f2cba Mon Sep 17 00:00:00 2001 From: vipg Date: Fri, 10 Oct 2025 16:43:40 +0800 Subject: [PATCH] add --- build_compose.py | 170 ++++-------------- .../api/api_delete/docker-compose.delete.yaml | 3 +- .../api_gateway/docker-compose.gateway.yaml | 3 +- .../api/api_login/docker-compose.login.yaml | 3 +- .../api_register/docker-compose.register.yaml | 3 +- .../docker-compose.update.account.yaml | 3 +- .../docker-compose.update.password.yaml | 3 +- deploy/docker-compose.yaml | 30 ++++ 8 files changed, 71 insertions(+), 147 deletions(-) diff --git a/build_compose.py b/build_compose.py index 550f7a7..210c957 100644 --- a/build_compose.py +++ b/build_compose.py @@ -1,93 +1,34 @@ import os import yaml -import subprocess +import shutil from typing import Dict, Any -def run_shell_command(command: str, cwd: str = None) -> bool: - """执行shell命令并返回执行结果""" - try: - print(f"执行命令: {command} (工作目录: {cwd or os.getcwd()})") - result = subprocess.run( - command, - cwd=cwd, - shell=True, - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True - ) - print(f"命令输出: {result.stdout}") - return True - except subprocess.CalledProcessError as e: - print(f"命令执行失败: {e.stderr}") - return False - -def cleanup_dangling_images() -> bool: - """清除docker虚悬镜像(dangling images)""" - print("开始清除虚悬镜像...") - # 清除所有:的虚悬镜像,xargs -r确保无镜像时不执行删除命令 - return run_shell_command('sudo docker images -f "dangling=true" -q | xargs -r sudo docker rmi') - -def execute_release_scripts(root_dir: str) -> bool: - """遍历所有api_目录并执行release.sh脚本(排除api_template)""" - print("开始执行所有api_目录下的release.sh脚本...") - - for dir_name in os.listdir(root_dir): - # 排除api_template文件夹 - if dir_name == "api_template": - print(f"跳过模板目录: {dir_name}") - continue - - dir_path = os.path.join(root_dir, dir_name) - if os.path.isdir(dir_path) and dir_name.startswith('api_'): - release_script = os.path.join(dir_path, 'release.sh') - if os.path.exists(release_script): - print(f"处理目录: {dir_path}") - - # 添加执行权限 - if not run_shell_command(f"chmod +x {release_script}", dir_path): - print(f"为 {release_script} 添加权限失败,跳过执行") - continue - - # 执行release.sh - if not run_shell_command(f"./release.sh", dir_path): - print(f"{release_script} 执行失败,跳过后续步骤") - return False - else: - print(f"{dir_path} 中未找到release.sh,跳过") - - print("所有release.sh脚本执行完成") - return True - def merge_yaml_files(root_dir: str) -> Dict[str, Any]: - """合并所有 docker-compose 相关 YAML 文件内容(排除api_template)""" + """合并所有 docker-compose 相关 YAML 文件内容""" + # 初始化合并后的结构 merged = { 'services': {}, 'networks': {}, 'volumes': {} } - # 查找所有 docker-compose 相关 YAML 文件 yaml_files = [] - # 1. 根目录下的 docker-compose.*.yaml + # 1. 收集根目录下的 docker-compose.*.yaml(排除目标输出文件) for file in os.listdir(root_dir): - if file.startswith('docker-compose.') and file.endswith('.yaml'): - if file == 'docker-compose.yaml': # 跳过目标文件本身 - continue + if (file.startswith('docker-compose.') and + file.endswith('.yaml') and + file != 'docker-compose.yaml'): yaml_files.append(os.path.join(root_dir, file)) - # 2. api_ 目录下的 docker-compose.*.yaml(排除api_template) - for dir_name in os.listdir(root_dir): - # 排除api_template文件夹 - if dir_name == "api_template": - print(f"跳过模板目录的yaml文件: {dir_name}") - continue - - dir_path = os.path.join(root_dir, dir_name) - if os.path.isdir(dir_path) and dir_name.startswith('api_'): - for file in os.listdir(dir_path): - if file.startswith('docker-compose.') and file.endswith('.yaml'): - yaml_files.append(os.path.join(dir_path, file)) + # 2. 收集 deploy/api 目录下的所有 docker-compose.*.yaml + api_root = os.path.join(root_dir, 'deploy', 'api') + if os.path.exists(api_root): + for dir_name in os.listdir(api_root): + dir_path = os.path.join(api_root, dir_name) + if os.path.isdir(dir_path): + for file in os.listdir(dir_path): + if file.startswith('docker-compose.') and file.endswith('.yaml'): + yaml_files.append(os.path.join(dir_path, file)) # 合并所有 YAML 文件内容 for file_path in yaml_files: @@ -98,15 +39,15 @@ def merge_yaml_files(root_dir: str) -> Dict[str, Any]: if not data: continue - # 合并 services + # 合并 services 配置 if 'services' in data: merged['services'].update(data['services']) - # 合并 networks + # 合并 networks 配置 if 'networks' in data: merged['networks'].update(data['networks']) - # 合并 volumes + # 合并 volumes 配置 if 'volumes' in data: merged['volumes'].update(data['volumes']) @@ -116,71 +57,30 @@ def merge_yaml_files(root_dir: str) -> Dict[str, Any]: return merged -def stop_docker_compose(root_dir: str) -> bool: - """停止docker-compose""" - print("开始停止docker-compose...") - compose_file = os.path.join(root_dir, 'docker-compose.yaml') - if not os.path.exists(compose_file): - print(f"未找到docker-compose文件: {compose_file}") - return False - - return run_shell_command(f"sudo docker-compose -f {compose_file} down", root_dir) - -def start_docker_compose(root_dir: str) -> bool: - """启动docker-compose""" - print("开始启动docker-compose...") - compose_file = os.path.join(root_dir, 'docker-compose.yaml') - if not os.path.exists(compose_file): - print(f"未找到docker-compose文件: {compose_file}") - return False - - return run_shell_command(f"sudo docker-compose -f {compose_file} up -d", root_dir) - -def main(): - # 先执行清除虚悬镜像操作 - print("部署流程开始,先执行清除虚悬镜像操作...") - if not cleanup_dangling_images(): - print("清除虚悬镜像失败(非致命错误,继续部署流程)") - else: - print("虚悬镜像清除完成") - - # 获取项目根目录(deploy.py 所在目录) - root_dir = os.path.dirname(os.path.abspath(__file__)) - print(f"项目根目录: {root_dir}") - - # 1. 执行所有api_目录下的release.sh脚本 - if not execute_release_scripts(root_dir): - print("执行release脚本失败,终止部署流程") - return - - # 2. 合并所有YAML文件 +def process_yaml(root_dir: str): + """处理 YAML 文件的主函数:合并并输出到目标路径""" + # 合并 YAML 文件 merged_data = merge_yaml_files(root_dir) - # 输出到根目录的docker-compose.yaml - output_path = os.path.join(root_dir, 'docker-compose.yaml') - with open(output_path, 'w', encoding='utf-8') as f: + # 输出到临时文件 + temp_output = os.path.join(root_dir, 'docker-compose.temp.yaml') + with open(temp_output, 'w', encoding='utf-8') as f: yaml.dump( merged_data, f, sort_keys=False, # 保持键的顺序 allow_unicode=True, # 支持中文 - default_flow_style=False # 使用块样式 + default_flow_style=False # 使用块样式而非流式样式 ) - print(f"已生成合并后的 docker-compose.yaml: {output_path}") + print(f"已生成合并后的临时文件: {temp_output}") - # 3. 启动docker-compose - stop_docker_compose(root_dir) - if not start_docker_compose(root_dir): - print("启动docker-compose失败") - return - - print("部署流程完成") - print("\n===== 清理虚悬镜像 =====") - if not cleanup_dangling_images(): - print("清除虚悬镜像失败(非致命错误,继续部署流程)") - else: - print("虚悬镜像清除完成") + # 复制到部署目录并替换目标文件 + deploy_dir = os.path.join(root_dir, 'deploy') + target_output = os.path.join(deploy_dir, 'docker-compose.yaml') + shutil.move(temp_output, target_output) + print(f"已将合并后的文件复制到: {target_output}") if __name__ == "__main__": - # 需要安装 pyyaml 库: pip install pyyaml - main() \ No newline at end of file + # 示例:从当前脚本所在目录作为根目录处理 + root_dir = os.path.dirname(os.path.abspath(__file__)) + process_yaml(root_dir) \ No newline at end of file diff --git a/deploy/api/api_delete/docker-compose.delete.yaml b/deploy/api/api_delete/docker-compose.delete.yaml index 892ea99..e5c0722 100644 --- a/deploy/api/api_delete/docker-compose.delete.yaml +++ b/deploy/api/api_delete/docker-compose.delete.yaml @@ -13,5 +13,4 @@ services: DB_USER: ${DB_USER} # 引用.env变量 DB_PASSWORD: ${DB_PASSWORD} # 引用.env变量 DB_NAME: ${DB_NAME} - TZ: ${TZ} # 引用.env变量 - command: ["/bin/sh", "-c", "until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; sleep 2; done; 启动你的应用命令"] \ No newline at end of file + TZ: ${TZ} # 引用.env变量 \ No newline at end of file diff --git a/deploy/api/api_gateway/docker-compose.gateway.yaml b/deploy/api/api_gateway/docker-compose.gateway.yaml index f481b88..a9c5a64 100644 --- a/deploy/api/api_gateway/docker-compose.gateway.yaml +++ b/deploy/api/api_gateway/docker-compose.gateway.yaml @@ -8,5 +8,4 @@ services: networks: - user-network environment: - GATEWAY_PORT: ${GATEWAY_PORT} # 引用.env变量 - command: ["/bin/sh", "-c", "until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; sleep 2; done; 启动你的应用命令"] \ No newline at end of file + GATEWAY_PORT: ${GATEWAY_PORT} # 引用.env变量 \ No newline at end of file diff --git a/deploy/api/api_login/docker-compose.login.yaml b/deploy/api/api_login/docker-compose.login.yaml index f51f734..690f81c 100644 --- a/deploy/api/api_login/docker-compose.login.yaml +++ b/deploy/api/api_login/docker-compose.login.yaml @@ -13,5 +13,4 @@ services: DB_USER: ${DB_USER} # 引用.env变量 DB_PASSWORD: ${DB_PASSWORD} # 引用.env变量 DB_NAME: ${DB_NAME} - TZ: ${TZ} # 引用.env变量 - command: ["/bin/sh", "-c", "until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; sleep 2; done; 启动你的应用命令"] \ No newline at end of file + TZ: ${TZ} # 引用.env变量 \ No newline at end of file diff --git a/deploy/api/api_register/docker-compose.register.yaml b/deploy/api/api_register/docker-compose.register.yaml index 8ca8afb..712b371 100644 --- a/deploy/api/api_register/docker-compose.register.yaml +++ b/deploy/api/api_register/docker-compose.register.yaml @@ -13,5 +13,4 @@ services: DB_USER: ${DB_USER} # 引用.env变量 DB_PASSWORD: ${DB_PASSWORD} # 引用.env变量 DB_NAME: ${DB_NAME} - TZ: ${TZ} # 引用.env变量 - command: ["/bin/sh", "-c", "until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; sleep 2; done; 启动你的应用命令"] \ No newline at end of file + TZ: ${TZ} # 引用.env变量 \ No newline at end of file diff --git a/deploy/api/api_update_account/docker-compose.update.account.yaml b/deploy/api/api_update_account/docker-compose.update.account.yaml index d0d0c55..fd9063f 100644 --- a/deploy/api/api_update_account/docker-compose.update.account.yaml +++ b/deploy/api/api_update_account/docker-compose.update.account.yaml @@ -13,5 +13,4 @@ services: DB_USER: ${DB_USER} # 引用.env变量 DB_PASSWORD: ${DB_PASSWORD} # 引用.env变量 DB_NAME: ${DB_NAME} - TZ: ${TZ} # 引用.env变量 - command: ["/bin/sh", "-c", "until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; sleep 2; done; 启动你的应用命令"] \ No newline at end of file + TZ: ${TZ} # 引用.env变量 \ No newline at end of file diff --git a/deploy/api/api_update_password/docker-compose.update.password.yaml b/deploy/api/api_update_password/docker-compose.update.password.yaml index f6bb7ff..a668c79 100644 --- a/deploy/api/api_update_password/docker-compose.update.password.yaml +++ b/deploy/api/api_update_password/docker-compose.update.password.yaml @@ -13,5 +13,4 @@ services: DB_USER: ${DB_USER} # 引用.env变量 DB_PASSWORD: ${DB_PASSWORD} # 引用.env变量 DB_NAME: ${DB_NAME} - TZ: ${TZ} # 引用.env变量 - command: ["/bin/sh", "-c", "until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; sleep 2; done; 启动你的应用命令"] \ No newline at end of file + TZ: ${TZ} # 引用.env变量 \ No newline at end of file diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml index d963c70..ea6c375 100644 --- a/deploy/docker-compose.yaml +++ b/deploy/docker-compose.yaml @@ -46,6 +46,11 @@ services: DB_PASSWORD: ${DB_PASSWORD} DB_NAME: ${DB_NAME} TZ: ${TZ} + command: + - /bin/sh + - -c + - until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; + sleep 2; done; 启动你的应用命令 user_update_account: image: user-update-account-api:1.0.0 container_name: api_user_update_account @@ -61,6 +66,11 @@ services: DB_PASSWORD: ${DB_PASSWORD} DB_NAME: ${DB_NAME} TZ: ${TZ} + command: + - /bin/sh + - -c + - until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; + sleep 2; done; 启动你的应用命令 user_gateway: image: user-gateway-api:1.0.0 container_name: api_user_gateway @@ -71,6 +81,11 @@ services: - user-network environment: GATEWAY_PORT: ${GATEWAY_PORT} + command: + - /bin/sh + - -c + - until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; + sleep 2; done; 启动你的应用命令 user_update_password: image: user-update-password-api:1.0.0 container_name: api_user_update_password @@ -86,6 +101,11 @@ services: DB_PASSWORD: ${DB_PASSWORD} DB_NAME: ${DB_NAME} TZ: ${TZ} + command: + - /bin/sh + - -c + - until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; + sleep 2; done; 启动你的应用命令 user_register: image: user-register-api:1.0.0 container_name: api_user_register @@ -101,6 +121,11 @@ services: DB_PASSWORD: ${DB_PASSWORD} DB_NAME: ${DB_NAME} TZ: ${TZ} + command: + - /bin/sh + - -c + - until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; + sleep 2; done; 启动你的应用命令 user_delete: image: user-delete-api:1.0.0 container_name: api_user_delete @@ -116,6 +141,11 @@ services: DB_PASSWORD: ${DB_PASSWORD} DB_NAME: ${DB_NAME} TZ: ${TZ} + command: + - /bin/sh + - -c + - until pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER; do echo '等待数据库就绪...'; + sleep 2; done; 启动你的应用命令 networks: user-network: driver: bridge