如何在Airflow的docker-compose.yml配置中覆盖command字段
问题根因
官方Airflow镜像默认设置了ENTRYPOINT为内置的/entrypoint脚本,该脚本会将容器启动时传入的command参数全部作为airflow命令的子命令执行,因此你直接传入sh开头的指令会被拼接为airflow sh /xxx/xxx.sh,自然会报找不到sh子命令的错误。
可行解决方案
方案1:单服务覆盖入口点(适合每个服务需要单独执行配置的场景)
直接为每个Airflow服务覆盖默认入口点,显式用bash执行自定义逻辑后再启动Airflow服务,注意要加exec让Airflow进程成为容器PID1进程,保证能正常接收系统终止信号:
services: airflow-scheduler: <<: *airflow-common entrypoint: /bin/bash command: -c "sh /opt/airflow/my_application/configs/configure_all.sh && exec airflow scheduler" # 原有healthcheck、restart等配置保留不变 airflow-worker: <<: *airflow-common entrypoint: /bin/bash command: -c "sh /opt/airflow/my_application/configs/configure_all.sh && exec airflow celery worker" # 原有healthcheck、restart等配置保留不变
注意事项
建议在configure_all.sh开头添加数据库等待逻辑,避免脚本执行时PostgreSQL还未就绪导致创建连接/变量失败:
# configure_all.sh 头部添加以下代码 until psql "${AIRFLOW__CORE__SQL_ALCHEMY_CONN}" -c '\q' > /dev/null 2>&1; do >&2 echo "PostgreSQL未就绪,等待2秒重试" sleep 2 done >&2 echo "PostgreSQL已就绪,开始执行配置脚本"
方案2:单独初始化服务(更推荐,配置脚本全局只执行一次)
在docker-compose中新增一个独立的初始化服务,专门负责执行配置脚本,所有业务服务等待初始化服务执行成功后再启动,避免每个服务重复执行配置逻辑:
services: # 新增初始化服务 airflow-init-config: <<: *airflow-common entrypoint: /bin/bash command: -c "sh /opt/airflow/my_application/configs/configure_all.sh" depends_on: - postgres - redis airflow-scheduler: <<: *airflow-common command: scheduler # 新增依赖,等待初始化服务执行成功再启动 depends_on: airflow-init-config: condition: service_completed_successfully # 原有healthcheck、restart等配置保留不变 airflow-worker: <<: *airflow-common command: celery worker # 新增依赖,等待初始化服务执行成功再启动 depends_on: airflow-init-config: condition: service_completed_successfully - selenium # 原有healthcheck、restart等配置保留不变
这个方案不需要修改原有业务服务的启动逻辑,也避免了配置脚本重复执行可能带来的重复创建资源问题。
内容的提问来源于stack exchange,提问作者user3595632
相关产品推荐
相关产品推荐

