Airflow自定义Docker镜像:脚本仅在Worker容器执行的解决方案
问题
我有一个已自定义部分Python包的Airflow Docker镜像,需在启动所有容器前一次性构建并安装一个自定义.whl包。以下是我的Dockerfile和脚本:
FROM apache/airflow:2.3.3 USER root RUN adduser airflow sudo RUN chown -R airflow:sudo /home/airflow RUN chmod 755 /home/airflow USER airflow WORKDIR /home/airflow RUN mkdir -p /home/airflow/unifiedvoc/{config,dist,log} RUN python3 -m venv sample_env # RUN source sample_env/bin/activate RUN python3 -m pip install --user pipx RUN python3 -m pipx ensurepath --force RUN pipx install poetry==1.2.0 COPY ./script.sh /home/airflow RUN cd /home/airflow/ USER root RUN chmod +x /home/airflow/script.sh USER airflow RUN /home/airflow/script.sh ENTRYPOINT ["airflow celery worker"]
#!/bin/bash cd /home/airflow/xxxx poetry build python3 -m pip install /home/airflow/xxxx.py3-none-any.whl
使用RUN命令执行script.sh时,docker-compose up会报错;若将脚本设置为ENTRYPOINT,会在所有容器中执行。我希望该脚本仅在airflow-worker容器中执行,以便在DAG中导入该包,该如何解决?
解决方案
方案1:为worker单独构建镜像(推荐)
这种方式在镜像构建阶段就完成whl包的安装,启动容器时无冗余操作,且仅影响worker容器:
- 创建worker专属Dockerfile(命名为
Dockerfile.worker):FROM apache/airflow:2.3.3 USER root RUN adduser airflow sudo RUN chown -R airflow:sudo /home/airflow RUN chmod 755 /home/airflow USER airflow WORKDIR /home/airflow RUN mkdir -p /home/airflow/unifiedvoc/{config,dist,log} RUN python3 -m pip install --user pipx RUN python3 -m pipx ensurepath --force RUN pipx install poetry==1.2.0 # 复制你的Python包源码目录到镜像中 COPY ./xxxx /home/airflow/xxxx COPY ./script.sh /home/airflow USER root RUN chmod +x /home/airflow/script.sh USER airflow # 构建并安装whl包,镜像构建时一次性完成 RUN /home/airflow/script.sh # 保留Airflow worker默认的启动逻辑,不要硬编码ENTRYPOINT - 修改docker-compose.yml:
在airflow-worker服务中指定使用上述自定义镜像,其他服务(webserver、scheduler等)使用基础镜像:services: airflow-worker: build: context: . dockerfile: Dockerfile.worker # 保留原有worker配置... airflow-webserver: image: apache/airflow:2.3.3 # 保留原有webserver配置... airflow-scheduler: image: apache/airflow:2.3.3 # 保留原有scheduler配置...
方案2:在docker-compose中为worker单独配置启动脚本
适合包内容频繁修改的场景,每次启动worker容器时执行安装:
- 调整script.sh:
确保脚本执行完成后启动worker进程,同时修正whl包的路径(poetry build默认将产物放在项目dist目录):#!/bin/bash cd /home/airflow/xxxx poetry build python3 -m pip install /home/airflow/xxxx/dist/xxxx-*.whl # 启动worker进程 exec airflow celery worker - 修改docker-compose.yml:
仅在airflow-worker服务中设置entrypoint为你的脚本,其他服务保持默认:services: airflow-worker: image: your-base-airflow-image # 你的基础自定义镜像(需包含poetry、脚本和包源码) entrypoint: ["/home/airflow/script.sh"] # 保留原有worker配置... # 其他服务保持原有entrypoint/command不变
原RUN命令报错的排查点
你之前用RUN执行脚本报错,大概率是两个原因:
- 未将Python包源码目录
xxxxCOPY到镜像中,脚本执行cd /home/airflow/xxxx时找不到目录 - 脚本中whl包路径错误,poetry build的产物默认在
xxxx/dist/下,而非根目录
内容的提问来源于stack exchange,提问作者Gaius G D'cruz
相关产品推荐
相关产品推荐

