Docker环境下Laravel集成Redis遇PDOException驱动缺失问题求助
嘿,我来帮你捋清楚这个问题——虽然你一开始怀疑是Redis容器的访问问题,但这个PDOException: could not find driver错误其实和数据库连接直接相关,咱们一步步来修复:
1. 定位错误根源:PHP-Worker容器缺少PDO MySQL驱动
Laravel Horizon运行在你的php-worker容器里,而这个容器的PHP环境没有安装MySQL的PDO扩展。从你的docker-compose.yml里的php-worker配置来看,你只指定了INSTALL_PGSQL=false,但没开启MySQL的PDO支持,当Horizon需要访问数据库(比如存储队列任务的监控数据、或者队列任务本身要操作数据库)时,就会抛出这个驱动找不到的错误。
2. 修复步骤
第一步:给PHP-Worker添加PDO MySQL驱动
打开你的./docker/php-worker目录下的Dockerfile,添加安装PDO MySQL扩展的命令。如果你的基础镜像是官方PHP镜像(比如php:7.2-fpm),可以加上这一行:
RUN docker-php-ext-install pdo_mysql
如果是基于其他定制镜像,对应改成你镜像的扩展安装方式(比如用apt-get安装php7.2-mysql)。
第二步:优化Docker Compose配置(替换过时的links,确保容器互通)
links指令已经被Docker官方弃用了,推荐用自定义网络来让容器互相访问,同时要确保php-worker能连接到MariaDB和Redis:
更新你的docker-compose.yml,添加自定义网络,并让所有服务加入这个网络:
# Web server nginx: image: nginx:latest restart: always ports: - "3000:3001" - "8081:80" volumes: - ./api:/var/www/api - ./docker/nginx/conf.d/:/etc/nginx/conf.d - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf depends_on: - php networks: - app-network # PHP php: build: ./docker/php-fpm volumes: - ./api:/var/www/api depends_on: - mariadb networks: - app-network # Redis redis: image: redis:latest expose: - "6379" networks: - app-network # Database mariadb: image: mariadb:latest restart: always ports: - "3306:3306" volumes: - ./database/mariadb/:/var/lib/mysql networks: - app-network # PHP workers php-worker: build: context: ./docker/php-worker args: - PHP_VERSION=7.2 - INSTALL_PGSQL=false volumes: - ./:/var/www - ./docker/php-worker/supervisor.d:/etc/supervisor.d extra_hosts: - "dockerhost:10.0.75.1" depends_on: - redis - mariadb # 新增:让worker依赖数据库,确保启动顺序 networks: - app-network # 新增自定义网络 networks: app-network: driver: bridge
第三步:确认Laravel环境变量配置
检查你的Laravel项目.env文件,确保数据库和Redis的主机名是Docker服务名:
DB_HOST=mariadb REDIS_HOST=redis
第四步:重建容器并重启服务
执行以下命令重新构建php-worker容器,然后重启所有服务:
docker-compose build php-worker docker-compose up -d
3. 额外说明
你之前误以为是Redis容器的问题,是因为错误出现在Horizon里,但Horizon本身不仅依赖Redis做队列存储,还需要连接数据库来保存任务的执行记录、监控数据等——所以核心问题是worker容器缺少数据库驱动,而不是Redis的访问问题。
内容的提问来源于stack exchange,提问作者Oliver

