Docker容器内Lumen服务无法自调用的问题求助
问题
我搭建了docker-compose环境,在Lumen服务容器内尝试通过CURL请求自身服务时遇到两个问题:
- 使用
localhost:8000请求,Laravel控制器返回错误:Failed to connect to localhost port 8000 after 0 ms: Connection refused - 使用服务名
lumen:8000请求时,请求无限加载(并非无限循环)
本地主机可正常访问Lumen服务,但容器内自调用功能无法实现,这是项目必需功能。
提供的配置文件
docker-compose.yml
version: "3.5" services: lumen: expose: - "8000" ports: - "8000:8000" volumes: - ./server:/var/www/html - ./server/vendor:/var/www/html/vendor/ build: context: server dockerfile: Dockerfile command: php -S lumen:8000 -t public restart: always privileged: true depends_on: - database networks: - database frontend: build: context: client dockerfile: Dockerfile volumes: - ./client/src:/app/src ports: - 3000:3000 stdin_open: true #restart: always networks: - database # Database Service (Mysql) database: image: mysql:latest container_name: blogmoda_mysql environment: MYSQL_DATABASE: blogmoda-app MYSQL_USER: root MYSQL_PASSWORD: root MYSQL_ROOT_PASSWORD: root command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci','--default-authentication-plugin=mysql_native_password'] ports: - "127.0.0.1:3306:3306" volumes: - db-data:/var/lib/mysql networks: - database phpmyadmin: image: phpmyadmin/phpmyadmin container_name: dev_phpmyadmin links: - database environment: PMA_HOST: database PMA_PORT: 3306 PMA_ARBITRARY: 1 restart: always depends_on: - database ports: - 9001:80 networks: - database volumes: db-data: # Networks to be created to facilitate communication between containers networks: database:
Server Dockerfile
FROM php:8.1-fpm-alpine RUN apk update && apk add bash RUN apk add chromium RUN apk add --no-cache zip libzip-dev RUN docker-php-ext-configure zip RUN docker-php-ext-install zip RUN docker-php-ext-install pdo pdo_mysql RUN docker-php-ext-install pdo_mysql RUN docker-php-ext-install opcache WORKDIR /var/www/html/ RUN php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer COPY . . RUN composer install --ignore-platform-req=ext-zip --ignore-platform-reqs
解决方案
问题原因拆解
localhost:8000连接被拒绝:
容器内的localhost指向自身回环接口,但你启动PHP内置服务器的命令是php -S lumen:8000 -t public,这意味着服务器只监听了容器内对应lumen主机名的网卡,没有监听回环接口127.0.0.1,所以用localhost访问会被拒绝。lumen:8000无限加载:
PHP内置服务器是单进程的,当你在请求处理中发起另一个对自身的请求时,新请求会被挂起等待当前请求完成,但当前请求又在等新请求的响应,形成死锁,导致无限加载。
具体解决办法
方案一:修改内置服务器监听地址(解决localhost访问问题,但死锁仍存在)
把lumen服务的启动命令改成监听所有接口,这样容器内用localhost:8000或lumen:8000都能访问,但单进程死锁问题还是会导致自请求无限加载:
command: php -S 0.0.0.0:8000 -t public
方案二:切换多进程HTTP服务器(彻底解决问题,推荐)
放弃PHP内置服务器,改用多进程服务器,比如php-fpm + nginx组合,或者RoadRunner这类高性能服务器。多进程可以同时处理多个请求,避免单进程死锁。
方案三:绕过网络请求(最优应急方案)
如果只是需要调用内部业务逻辑,没必要发起HTTP请求,直接调用控制器方法或业务类即可,跳过HTTP层既解决了问题,还提升了性能。
内容的提问来源于stack exchange,提问作者helth
相关产品推荐
相关产品推荐

