单容器部署Apache Airflow遇PostgreSQL连接拒绝问题求助
单容器部署Apache Airflow + PostgreSQL的解决方案
问题根源
你遇到的连接拒绝错误,核心原因有两个:
- PostgreSQL启动后需要一定时间完成初始化,直接紧接着执行
airflow db init时数据库还未就绪 - Docker容器默认只运行一个前台进程,用
service postgresql start是后台启动,容器无法持续托管该进程,且Airflow进程启动后可能PostgreSQL已退出
解决步骤
1. 安装依赖与配置PostgreSQL
在Dockerfile中完成Airflow、PostgreSQL的安装,同时配置PostgreSQL允许本地连接:
- 创建Airflow专用的PostgreSQL用户和数据库
- 修改
pg_hba.conf允许本地信任连接 - 修改
postgresql.conf监听本地地址
2. 等待PostgreSQL就绪脚本
编写脚本等待PostgreSQL完全启动后再执行Airflow初始化,避免连接失败:
#!/bin/bash set -e # 启动PostgreSQL后台进程 pg_ctlcluster 14 main start # 轮询等待PostgreSQL就绪 until pg_isready -U airflow; do echo "Waiting for PostgreSQL to start..." sleep 2 done # 初始化Airflow数据库 airflow db init # 创建Airflow管理员用户(可选) airflow users create \ --username admin \ --firstname Admin \ --lastname User \ --role Admin \ --email admin@example.com \ --password admin
3. 使用Supervisord管理多进程
单容器需要同时运行PostgreSQL、Airflow Webserver、Airflow Scheduler三个进程,必须用进程管理器supervisord托管,避免容器因单个进程退出而终止。
完整Dockerfile示例
# 基础镜像选择Python官方镜像 FROM python:3.10-slim-bookworm # 设置环境变量 ENV AIRFLOW_HOME=/opt/airflow ENV AIRFLOW_VERSION=2.8.3 ENV PYTHON_VERSION=3.10 ENV CONSTRAINT_URL="https://raw.githubusercontent.com/apache/airflow/constraints-${AIRFLOW_VERSION}/constraints-${PYTHON_VERSION}.txt" # 安装系统依赖 RUN apt-get update && apt-get install -y --no-install-recommends \ postgresql-14 \ postgresql-client-14 \ supervisor \ && rm -rf /var/lib/apt/lists/* # 创建Airflow目录与专用用户 RUN mkdir -p ${AIRFLOW_HOME} \ && useradd -ms /bin/bash airflow \ && chown -R airflow:airflow ${AIRFLOW_HOME} # 切换到postgres用户初始化数据库配置 USER postgres RUN initdb -D /var/lib/postgresql/14/main \ && echo "host all all 127.0.0.1/32 trust" >> /var/lib/postgresql/14/main/pg_hba.conf \ && echo "listen_addresses='localhost'" >> /var/lib/postgresql/14/main/postgresql.conf \ && createdb airflow \ && createuser airflow # 切换回root用户安装Airflow USER root RUN pip install --no-cache-dir "apache-airflow==${AIRFLOW_VERSION}" --constraint "${CONSTRAINT_URL}" \ && pip install psycopg2-binary # 复制supervisord配置文件 COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf # 复制启动脚本并设置权限 COPY start-airflow.sh ${AIRFLOW_HOME}/start-airflow.sh RUN chmod +x ${AIRFLOW_HOME}/start-airflow.sh \ && chown airflow:airflow ${AIRFLOW_HOME}/start-airflow.sh # 暴露Airflow webserver端口 EXPOSE 8080 # 启动supervisord托管所有进程 CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
supervisord.conf配置示例
[supervisord] nodaemon=true user=root [program:postgresql] command=/usr/bin/pg_ctlcluster 14 main start -w autorestart=true stdout_logfile=/var/log/supervisor/postgres.log stderr_logfile=/var/log/supervisor/postgres.err [program:airflow-init] command=/opt/airflow/start-airflow.sh directory=/opt/airflow user=airflow autorestart=false stdout_logfile=/var/log/supervisor/airflow-init.log stderr_logfile=/var/log/supervisor/airflow-init.err [program:airflow-webserver] command=airflow webserver -p 8080 directory=/opt/airflow user=airflow autorestart=true stdout_logfile=/var/log/supervisor/airflow-webserver.log stderr_logfile=/var/log/supervisor/airflow-webserver.err startsecs=15 [program:airflow-scheduler] command=airflow scheduler directory=/opt/airflow user=airflow autorestart=true stdout_logfile=/var/log/supervisor/airflow-scheduler.log stderr_logfile=/var/log/supervisor/airflow-scheduler.err startsecs=15
关键注意事项
- 确保Airflow配置文件
airflow.cfg中的数据库连接字符串正确:sql_alchemy_conn = postgresql+psycopg2://airflow@localhost/airflow - 若使用其他版本的PostgreSQL,需调整
pg_ctlcluster后的版本号(比如15) - 构建镜像时需将
start-airflow.sh和supervisord.conf放在Dockerfile同目录下
内容的提问来源于stack exchange,提问作者Shishir Hossain
相关产品推荐
相关产品推荐

