Loading .gitignore +3 −0 Original line number Diff line number Diff line Loading @@ -49,3 +49,6 @@ dist/ # Database db.sqlite3 cookies.txt # Tests tests/ README.md +163 −69 Original line number Diff line number Diff line # csst-airflow # Airflow 部署指南 (v3.0.5) # installation 本指南描述如何使用官方 Apache Airflow 3.0.5 镜像部署 CSST Airflow 集群。当前架构包含了 CeleryExecutor、Redis、PostgreSQL,并深度集成了 **Elasticsearch + Kibana** 作为集中的日志采集与展示平台。 ## 前提条件 - 已安装 Docker 和 Docker Compose - Git - Make - Linux 环境(因涉及权限与路径映射) ## 架构升级说明 1. **DAG Factory 模式**: `dags/common/dag_factory.py` 提取了通用的 `DockerOperator` 逻辑,支持数十个流程快速接入。 2. **统一镜像仓库变量**: 引入了 `HARBOR` 环境变量控制镜像前缀,可根据部署环境自动切换仓库。 3. **远程日志收集**: 增加了 Elasticsearch (39200)、Kibana (35601) 和 Filebeat 容器,实现了任务日志的统一索引、可视化和快速检索。 4. **统一调度网关 (API Gateway)**: 针对 10 万级并发与异构 JSON 检索需求,新增了基于 FastAPI 和 Postgres JSONB 的轻量级高性能网关,屏蔽了 Airflow 的复杂 API 和鉴权逻辑。 ## 部署步骤 本系统支持两种部署方式:**基于 Make 的单机/手动部署** 和 **基于 Ansible 的多节点自动化部署**。 ### 方式一:Ansible 多节点一键部署(推荐用于生产环境) 如果您需要在真实的集群(1个 Master 节点 + 多个 Worker 节点)上部署该系统,我们提供了开箱即用的 Ansible Playbooks。由于我们有多个不同的部署环境(如 `p368`, `csu`, `zjlab`),我们为每个环境准备了专属的 Ansible Inventory 文件。 #### 1. 准备工作 - 确保在执行机上已安装 `ansible`。 - 确保执行机配置了到所有目标节点(Master & Workers)的 SSH 免密登录(具有 root 或 sudo 权限)。 #### 2. 配置环境对应的 Inventory 文件 根据您要部署的环境,编辑 `ansible/` 目录下对应的清单文件(例如 `inventory.csu.ini`): ```ini [master] # 替换为您的 Master 节点 IP 192.168.25.18 ansible_user=root [worker] # 添加您所有的 Worker 节点 IP 192.168.25.19 ansible_user=root 192.168.25.20 ansible_user=root [all:vars] # 这里已经预设好了对应的环境名称,无需修改 env_name=csu # 远程服务器上的部署路径 deploy_dir=/opt/csst-airflow ``` #### 3. 配置环境变量 确保对应环境的 `.env` 文件(例如 `envs/.env.csu`)中的 `MASTER_IP` 配置正确,以便 Worker 节点能找到 Master 节点的服务。 #### 4. 一键部署集群 在 `docker-celery-3.0.5` 目录下执行(以 `csu` 环境为例): ```bash # 1. 部署所有节点的基础组件与服务容器 ansible-playbook -i ansible/inventory.csu.ini ansible/deploy.yml # 2. 同步 DAGs 代码到所有节点 (以后每次更新 DAGs 都可以单独执行此命令) ansible-playbook -i ansible/inventory.csu.ini ansible/sync_dags.yml ``` --- ### 方式二:基于 Make 的单机或手动部署 #### 1. 初始化目录与权限 ```bash git clone https://csst-tb.bao.ac.cn/code/csst-cicd/csst-airflow.git cd csst-airflow/docker vim .env make mkdir make up make fix-permission ``` > **注意**: `fix-permission` 会使用 `sudo` 修复 Elasticsearch 数据目录的归属,以防启动时因无权写入数据而失败。 #### 2. 选择部署环境 本系统支持通过 Makefile 动态指定环境变量配置文件。您可以随时通过以下命令查看当前支持的所有环境模板: ```bash make list-envs ``` *(系统将自动读取 `envs/` 目录下的 `.env.*` 文件后缀)* # REST API ```shell # 定义ENDPOINT_URL ENDPOINT_URL="http://localhost:8080" # 空间应用中心 ENDPOINT_URL="http://192.168.25.153:38080" # 之江实验室 ENDPOINT_URL="http://10.200.60.244:38080" # 获取token TOKEN=$(curl -X POST "${ENDPOINT_URL}/auth/token" \ -H "Content-Type: application/json" \ -d '{"username":"csst", "password":"pipeline"}' | jq -r '.access_token') echo $TOKEN # 获取DAG列表 curl -X 'GET' \ "${ENDPOINT_URL}/api/v2/dags" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" # 触发DAG(https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html#operation/trigger_dag_run) curl -X 'POST' \ "${ENDPOINT_URL}/api/v2/dags/csst-msc-l1.conditional-trigger/dagRuns" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d ' { "dag_run_id": null, "logical_date": null, "conf": { "dag_group": "csst-msc-l1.conditional-trigger", "dags": [ "csst-msc-l1-qc0", "csst-msc-l1-mbi", "csst-msc-l1-ast", "csst-msc-l1-sls" ], "dataset": "csst-msc-c9-25sqdeg-v3", "instrument": "MSC", "obs_type": "WIDE", "obs_group": "W2", "obs_id": "10100232366", "detector": "09", "prc_status": "", "qc_status": "", "pmapname": "csst_000094.pmap", "ref_cat": "trilegal_093", "batch_id": "__airflow_default_batch__", "priority": "1", "verbose": true, "submit": false, "force": false, "top_n": -1, "final_prc_status": -2 }, "note": null } ' # 更多API https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html #### 3. 初始化 Airflow 数据库 在首次部署的**主控节点**上执行数据库初始化(假设您使用的是 `csu` 环境): ```bash make init ENV=csu ``` #### 4. 启动核心服务 > **⚠️ 部署强烈建议**: > 系统采用 Master/Worker 分离架构,主节点负责调度与监控网关,子节点负责计算。 ##### 主控节点 (Master Node) 部署: 在作为 Master 的机器上执行,此命令会启动数据库、消息队列、API Gateway、Prometheus/Grafana 监控大盘以及 Airflow 控制平面: ```bash make up-master ENV=csu ``` ##### 计算节点 (Worker Node) 部署: 在提供算力的机器上执行,此命令**仅启动** Celery Worker 和该机器专属的日志采集与监控探针 (Filebeat / cAdvisor / Node Exporter): ```bash make up-worker ENV=csu ``` > **提示**: 探针会自动启动,以供 Master 节点的 Prometheus 和 ES 抓取该 Worker 机器的资源与日志状态。 --- ## Makefile 命令速查 | 命令 | 描述 | |------|------| | `make all` | **一键完整部署**:停止、拉取、建目录、修权限、初始化、启动 | | `make mkdir` | 创建所有必需的挂载目录 | | `make fix-permission` | 修复 `es_data` 目录的属主权限 (UID 1000) | | `make copy-env-*` | 复制对应的预设环境变量文件 | | `make init` | 初始化 Airflow 数据库 | | `make up` | 启动核心调度器、API 网关与基础设施 (不含 Worker) | | `make up-master` | 启动核心组件并附带开启 Flower 监控 | | `make up-worker` | 启动 Celery Worker 以执行具体的 Task | | `make down` | 停止所有服务 | | `make clean` | 停止服务并清理容器 | | `make ps` | 列出运行中的服务 | ## 访问服务与系统端口映射 在完整的分布式或单机部署中,各个组件所占用的宿主机端口如下。**请在部署前确保宿主机的这些防火墙端口已开放且未被占用**。 ### 主控节点 (Master Node) 执行 `make up` 或 `make up-master` 的机器上将暴露以下核心服务端口: | 服务组件 | 宿主机端口 | 用途说明 | 访问地址示例 | | :--- | :--- | :--- | :--- | | **API Gateway** | `38000` | **业务系统唯一对接入口**。提供高并发任务提交与基于 JSONB 的状态检索 | `http://<MASTER_IP>:38000` | | **Airflow Web UI** | `38080` | Airflow 原生控制台与官方 API (账号密码默认: `airflow`/`airflow`) | `http://<MASTER_IP>:38080` | | **Kibana** | `35601` | 集中式日志可视化中心 (直接在 Discover 页面选择 `airflow-*` 视图检索日志) | `http://<MASTER_IP>:35601` | | **Flower** | `35555` | Celery 集群状态监控面板 (**仅在执行 `make up-master` 时启动**) | `http://<MASTER_IP>:35555` | | **Elasticsearch** | `39200` | 存储运行日志的底层搜索引擎 API | `http://<MASTER_IP>:39200` | | **PostgreSQL** | `35432` | 核心元数据库,存储 Airflow 数据及 API Gateway 的 `csst_task_records` 表 | `postgresql://<MASTER_IP>:35432` | | **Redis** | `36379` | Celery 消息队列中间件 | `redis://<MASTER_IP>:36379` | ### 计算节点 (Worker Node) 执行 `make up-worker` 的机器: * **不暴露任何宿主机端口**。 * Worker 节点只需通过 `.env` 中的 `MASTER_IP` 主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。 --- ## DAG 任务的触发与状态查询 为了避免 Airflow 3 升级鉴权体系(强制 JWT)带来的对接复杂性,以及为了解决海量异构任务数据的检索问题,本系统**强力推荐业务方直接对接自定义的 API Gateway**。 外部系统仅需维护一个环境变量 `export AIRFLOW_API_GATEWAY=http://<MASTER_IP>:38000`,即可进行批量任务提交、JSONB 高性能状态检索等操作。 请查阅配套的 **[`api.md`](./api.md)** 获取完整的接口文档和 cURL 调用示例。 ## 故障排除 - 确保 Docker 正在运行 - 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana) - 若 Elasticsearch 启动失败 (Unhealthy),请查看权限问题,再次执行 `make fix-permission` 并 `docker compose restart elasticsearch` - 检查容器日志以了解错误: ```bash docker compose logs -f ``` docker-celery-3.0.5/api.md→api.md +0 −0 File moved. View file docker-celery-3.0.5/Dockerfile 0 → 100644 +5 −0 Original line number Diff line number Diff line FROM apache/airflow:3.0.5 # Install additional python dependencies required for our DAGs # Specifically the docker provider which is heavily used by CSST DAG Factory RUN pip install --no-cache-dir apache-airflow-providers-docker docker-celery-3.0.5/Makefile +21 −19 Original line number Diff line number Diff line # 默认环境(可被传入的 ENV 参数覆盖,例如 make up-master ENV=csu) ENV ?= csu ENV_FILE := envs/.env.$(ENV) list-envs: @echo "Available environments (Usage: make up-master ENV=<name>):" @ls envs/.env.* 2>/dev/null | sed 's|envs/.env.||' | sed 's/^/ - /' || echo " No environment files found." all: down pull mkdir fix-permission init up pull: Loading @@ -14,38 +22,32 @@ rmdir: rm -rf ./volumes init: docker compose up airflow-init docker compose --env-file $(ENV_FILE) up airflow-init up: docker compose up -d up-master: docker compose -f docker-compose.yaml --env-file .env --profile flower up --force-recreate up-worker: docker compose -f docker-compose.yaml --env-file .env up worker --force-recreate docker compose --env-file $(ENV_FILE) up -d copy-env-csu: cp envs/.env.csu .env check-env: @if [ ! -f $(ENV_FILE) ]; then echo "Error: Environment file $(ENV_FILE) does not exist!"; exit 1; fi copy-env-p368: cp envs/.env.p368 .env up-master: check-env docker compose -f docker-compose.yaml --env-file $(ENV_FILE) --profile flower --profile master up -d --force-recreate copy-env-zjlab: cp envs/.env.zjlab .env up-worker: check-env docker compose -f docker-compose.yaml --env-file $(ENV_FILE) --profile worker up -d --force-recreate down: docker compose down docker compose --env-file $(ENV_FILE) down migrate: docker compose run --rm airflow-init airflow db upgrade docker compose --env-file $(ENV_FILE) run --rm airflow-init airflow db upgrade clean: # 停止服务并清理旧数据 docker compose rm -sf docker compose --env-file $(ENV_FILE) rm -sf ps: docker compose ps docker compose --env-file $(ENV_FILE) ps restart: docker compose restart docker compose --env-file $(ENV_FILE) restart Loading
.gitignore +3 −0 Original line number Diff line number Diff line Loading @@ -49,3 +49,6 @@ dist/ # Database db.sqlite3 cookies.txt # Tests tests/
README.md +163 −69 Original line number Diff line number Diff line # csst-airflow # Airflow 部署指南 (v3.0.5) # installation 本指南描述如何使用官方 Apache Airflow 3.0.5 镜像部署 CSST Airflow 集群。当前架构包含了 CeleryExecutor、Redis、PostgreSQL,并深度集成了 **Elasticsearch + Kibana** 作为集中的日志采集与展示平台。 ## 前提条件 - 已安装 Docker 和 Docker Compose - Git - Make - Linux 环境(因涉及权限与路径映射) ## 架构升级说明 1. **DAG Factory 模式**: `dags/common/dag_factory.py` 提取了通用的 `DockerOperator` 逻辑,支持数十个流程快速接入。 2. **统一镜像仓库变量**: 引入了 `HARBOR` 环境变量控制镜像前缀,可根据部署环境自动切换仓库。 3. **远程日志收集**: 增加了 Elasticsearch (39200)、Kibana (35601) 和 Filebeat 容器,实现了任务日志的统一索引、可视化和快速检索。 4. **统一调度网关 (API Gateway)**: 针对 10 万级并发与异构 JSON 检索需求,新增了基于 FastAPI 和 Postgres JSONB 的轻量级高性能网关,屏蔽了 Airflow 的复杂 API 和鉴权逻辑。 ## 部署步骤 本系统支持两种部署方式:**基于 Make 的单机/手动部署** 和 **基于 Ansible 的多节点自动化部署**。 ### 方式一:Ansible 多节点一键部署(推荐用于生产环境) 如果您需要在真实的集群(1个 Master 节点 + 多个 Worker 节点)上部署该系统,我们提供了开箱即用的 Ansible Playbooks。由于我们有多个不同的部署环境(如 `p368`, `csu`, `zjlab`),我们为每个环境准备了专属的 Ansible Inventory 文件。 #### 1. 准备工作 - 确保在执行机上已安装 `ansible`。 - 确保执行机配置了到所有目标节点(Master & Workers)的 SSH 免密登录(具有 root 或 sudo 权限)。 #### 2. 配置环境对应的 Inventory 文件 根据您要部署的环境,编辑 `ansible/` 目录下对应的清单文件(例如 `inventory.csu.ini`): ```ini [master] # 替换为您的 Master 节点 IP 192.168.25.18 ansible_user=root [worker] # 添加您所有的 Worker 节点 IP 192.168.25.19 ansible_user=root 192.168.25.20 ansible_user=root [all:vars] # 这里已经预设好了对应的环境名称,无需修改 env_name=csu # 远程服务器上的部署路径 deploy_dir=/opt/csst-airflow ``` #### 3. 配置环境变量 确保对应环境的 `.env` 文件(例如 `envs/.env.csu`)中的 `MASTER_IP` 配置正确,以便 Worker 节点能找到 Master 节点的服务。 #### 4. 一键部署集群 在 `docker-celery-3.0.5` 目录下执行(以 `csu` 环境为例): ```bash # 1. 部署所有节点的基础组件与服务容器 ansible-playbook -i ansible/inventory.csu.ini ansible/deploy.yml # 2. 同步 DAGs 代码到所有节点 (以后每次更新 DAGs 都可以单独执行此命令) ansible-playbook -i ansible/inventory.csu.ini ansible/sync_dags.yml ``` --- ### 方式二:基于 Make 的单机或手动部署 #### 1. 初始化目录与权限 ```bash git clone https://csst-tb.bao.ac.cn/code/csst-cicd/csst-airflow.git cd csst-airflow/docker vim .env make mkdir make up make fix-permission ``` > **注意**: `fix-permission` 会使用 `sudo` 修复 Elasticsearch 数据目录的归属,以防启动时因无权写入数据而失败。 #### 2. 选择部署环境 本系统支持通过 Makefile 动态指定环境变量配置文件。您可以随时通过以下命令查看当前支持的所有环境模板: ```bash make list-envs ``` *(系统将自动读取 `envs/` 目录下的 `.env.*` 文件后缀)* # REST API ```shell # 定义ENDPOINT_URL ENDPOINT_URL="http://localhost:8080" # 空间应用中心 ENDPOINT_URL="http://192.168.25.153:38080" # 之江实验室 ENDPOINT_URL="http://10.200.60.244:38080" # 获取token TOKEN=$(curl -X POST "${ENDPOINT_URL}/auth/token" \ -H "Content-Type: application/json" \ -d '{"username":"csst", "password":"pipeline"}' | jq -r '.access_token') echo $TOKEN # 获取DAG列表 curl -X 'GET' \ "${ENDPOINT_URL}/api/v2/dags" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" # 触发DAG(https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html#operation/trigger_dag_run) curl -X 'POST' \ "${ENDPOINT_URL}/api/v2/dags/csst-msc-l1.conditional-trigger/dagRuns" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d ' { "dag_run_id": null, "logical_date": null, "conf": { "dag_group": "csst-msc-l1.conditional-trigger", "dags": [ "csst-msc-l1-qc0", "csst-msc-l1-mbi", "csst-msc-l1-ast", "csst-msc-l1-sls" ], "dataset": "csst-msc-c9-25sqdeg-v3", "instrument": "MSC", "obs_type": "WIDE", "obs_group": "W2", "obs_id": "10100232366", "detector": "09", "prc_status": "", "qc_status": "", "pmapname": "csst_000094.pmap", "ref_cat": "trilegal_093", "batch_id": "__airflow_default_batch__", "priority": "1", "verbose": true, "submit": false, "force": false, "top_n": -1, "final_prc_status": -2 }, "note": null } ' # 更多API https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html #### 3. 初始化 Airflow 数据库 在首次部署的**主控节点**上执行数据库初始化(假设您使用的是 `csu` 环境): ```bash make init ENV=csu ``` #### 4. 启动核心服务 > **⚠️ 部署强烈建议**: > 系统采用 Master/Worker 分离架构,主节点负责调度与监控网关,子节点负责计算。 ##### 主控节点 (Master Node) 部署: 在作为 Master 的机器上执行,此命令会启动数据库、消息队列、API Gateway、Prometheus/Grafana 监控大盘以及 Airflow 控制平面: ```bash make up-master ENV=csu ``` ##### 计算节点 (Worker Node) 部署: 在提供算力的机器上执行,此命令**仅启动** Celery Worker 和该机器专属的日志采集与监控探针 (Filebeat / cAdvisor / Node Exporter): ```bash make up-worker ENV=csu ``` > **提示**: 探针会自动启动,以供 Master 节点的 Prometheus 和 ES 抓取该 Worker 机器的资源与日志状态。 --- ## Makefile 命令速查 | 命令 | 描述 | |------|------| | `make all` | **一键完整部署**:停止、拉取、建目录、修权限、初始化、启动 | | `make mkdir` | 创建所有必需的挂载目录 | | `make fix-permission` | 修复 `es_data` 目录的属主权限 (UID 1000) | | `make copy-env-*` | 复制对应的预设环境变量文件 | | `make init` | 初始化 Airflow 数据库 | | `make up` | 启动核心调度器、API 网关与基础设施 (不含 Worker) | | `make up-master` | 启动核心组件并附带开启 Flower 监控 | | `make up-worker` | 启动 Celery Worker 以执行具体的 Task | | `make down` | 停止所有服务 | | `make clean` | 停止服务并清理容器 | | `make ps` | 列出运行中的服务 | ## 访问服务与系统端口映射 在完整的分布式或单机部署中,各个组件所占用的宿主机端口如下。**请在部署前确保宿主机的这些防火墙端口已开放且未被占用**。 ### 主控节点 (Master Node) 执行 `make up` 或 `make up-master` 的机器上将暴露以下核心服务端口: | 服务组件 | 宿主机端口 | 用途说明 | 访问地址示例 | | :--- | :--- | :--- | :--- | | **API Gateway** | `38000` | **业务系统唯一对接入口**。提供高并发任务提交与基于 JSONB 的状态检索 | `http://<MASTER_IP>:38000` | | **Airflow Web UI** | `38080` | Airflow 原生控制台与官方 API (账号密码默认: `airflow`/`airflow`) | `http://<MASTER_IP>:38080` | | **Kibana** | `35601` | 集中式日志可视化中心 (直接在 Discover 页面选择 `airflow-*` 视图检索日志) | `http://<MASTER_IP>:35601` | | **Flower** | `35555` | Celery 集群状态监控面板 (**仅在执行 `make up-master` 时启动**) | `http://<MASTER_IP>:35555` | | **Elasticsearch** | `39200` | 存储运行日志的底层搜索引擎 API | `http://<MASTER_IP>:39200` | | **PostgreSQL** | `35432` | 核心元数据库,存储 Airflow 数据及 API Gateway 的 `csst_task_records` 表 | `postgresql://<MASTER_IP>:35432` | | **Redis** | `36379` | Celery 消息队列中间件 | `redis://<MASTER_IP>:36379` | ### 计算节点 (Worker Node) 执行 `make up-worker` 的机器: * **不暴露任何宿主机端口**。 * Worker 节点只需通过 `.env` 中的 `MASTER_IP` 主动连接到主控节点的 Redis 和 Postgres 即可静默消费任务。 --- ## DAG 任务的触发与状态查询 为了避免 Airflow 3 升级鉴权体系(强制 JWT)带来的对接复杂性,以及为了解决海量异构任务数据的检索问题,本系统**强力推荐业务方直接对接自定义的 API Gateway**。 外部系统仅需维护一个环境变量 `export AIRFLOW_API_GATEWAY=http://<MASTER_IP>:38000`,即可进行批量任务提交、JSONB 高性能状态检索等操作。 请查阅配套的 **[`api.md`](./api.md)** 获取完整的接口文档和 cURL 调用示例。 ## 故障排除 - 确保 Docker 正在运行 - 确保宿主机端口未被占用:`38080` (Airflow), `39200` (ES), `35601` (Kibana) - 若 Elasticsearch 启动失败 (Unhealthy),请查看权限问题,再次执行 `make fix-permission` 并 `docker compose restart elasticsearch` - 检查容器日志以了解错误: ```bash docker compose logs -f ```
docker-celery-3.0.5/Dockerfile 0 → 100644 +5 −0 Original line number Diff line number Diff line FROM apache/airflow:3.0.5 # Install additional python dependencies required for our DAGs # Specifically the docker provider which is heavily used by CSST DAG Factory RUN pip install --no-cache-dir apache-airflow-providers-docker
docker-celery-3.0.5/Makefile +21 −19 Original line number Diff line number Diff line # 默认环境(可被传入的 ENV 参数覆盖,例如 make up-master ENV=csu) ENV ?= csu ENV_FILE := envs/.env.$(ENV) list-envs: @echo "Available environments (Usage: make up-master ENV=<name>):" @ls envs/.env.* 2>/dev/null | sed 's|envs/.env.||' | sed 's/^/ - /' || echo " No environment files found." all: down pull mkdir fix-permission init up pull: Loading @@ -14,38 +22,32 @@ rmdir: rm -rf ./volumes init: docker compose up airflow-init docker compose --env-file $(ENV_FILE) up airflow-init up: docker compose up -d up-master: docker compose -f docker-compose.yaml --env-file .env --profile flower up --force-recreate up-worker: docker compose -f docker-compose.yaml --env-file .env up worker --force-recreate docker compose --env-file $(ENV_FILE) up -d copy-env-csu: cp envs/.env.csu .env check-env: @if [ ! -f $(ENV_FILE) ]; then echo "Error: Environment file $(ENV_FILE) does not exist!"; exit 1; fi copy-env-p368: cp envs/.env.p368 .env up-master: check-env docker compose -f docker-compose.yaml --env-file $(ENV_FILE) --profile flower --profile master up -d --force-recreate copy-env-zjlab: cp envs/.env.zjlab .env up-worker: check-env docker compose -f docker-compose.yaml --env-file $(ENV_FILE) --profile worker up -d --force-recreate down: docker compose down docker compose --env-file $(ENV_FILE) down migrate: docker compose run --rm airflow-init airflow db upgrade docker compose --env-file $(ENV_FILE) run --rm airflow-init airflow db upgrade clean: # 停止服务并清理旧数据 docker compose rm -sf docker compose --env-file $(ENV_FILE) rm -sf ps: docker compose ps docker compose --env-file $(ENV_FILE) ps restart: docker compose restart docker compose --env-file $(ENV_FILE) restart