首页 > 解决方案 > Dockerfile 构建 Laravel Telescope 试图连接到 Redis 服务尚未“启动”

问题描述

我的项目是在 docker-compose 文件中定义的,但我对 docker-compose 定义不太熟悉。

当我尝试进行docker-compose up -d全新设置时,在构建 docker 映像期间发生以下错误。

这是之后composer install,下post-autoload-dump。Laravel 尝试自动发现包 ( php artisan package:discover)。

Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   RedisException  : php_network_getaddresses: getaddrinfo failed: Name or service not known

  at [internal]:0
    1|

  Exception trace:

  1   ErrorException::("Redis::connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known")
      /var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php:126

  2   Redis::connect("my_redis", "6379")
      /var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php:126

  Please use the argument -v to see more details.
Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1
ERROR: Service 'my_app' failed to build: The command '/bin/sh -c composer global require hirak/prestissimo && composer install' returned a non-zero code: 1

它无法连接的my_redis:6379原因my_redis是同一docker-compose.yml文件中的另一个服务。所以我假设域还没有准备好,因为 docker-compose 想在托管容器之前先构建我的图像。


编辑我刚刚发现这个 GitHub 问题链接到我的问题:https ://github.com/laravel/telescope/issues/620 。似乎该问题与 Telescope 尝试使用缓存驱动程序有关。不同之处在于我不只是将 Docker 用于 CI/CD,而是用于我的本地开发。


我该如何解决这个问题?有没有办法在构建之前强制 Redis 容器先启动my_app?或者有没有一种 Laravel 方法来阻止任何域发现?或者有没有办法指定图像的构建取决于另一个可用的服务?


如果你想看我的docker-compose.yml

version: '3.6'
services:

  # Redis Service
  my_redis:
    image: redis:5.0-alpine
    container_name: my_redis
    restart: unless-stopped
    tty: true
    ports:
      - "6379:6379"
    volumes:
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
      - redisdata:/data
    networks:
      - app-network

  # Postgres Service
  my_db:
    image: postgres:12-alpine
    container_name: my_db
    restart: unless-stopped
    tty: true
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: my
      POSTGRES_PASSWORD: admin
      SERVICE_TAGS: dev
      SERVICE_NAME: postgres
    volumes:
      - dbdata:/var/lib/postgresql
      - ./postgres/init:/docker-entrypoint-initdb.d
    networks:
      - app-network

  # PHP Service
  my_app:
    build:
      context: .
      dockerfile: Dockerfile
    image: my/php
    container_name: my_app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: my_app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - /tmp:/tmp #For CS Fixer
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
      - fsdata:/my
    networks:
      - app-network

  # Nginx Service
  my_webserver:
    image: nginx:alpine
    container_name: my_webserver
    restart: unless-stopped
    tty: true
    ports:
      - "8080:80"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network

# Docker Networks
networks:
  app-network:
    driver: bridge

# Volumes
volumes:
  dbdata:
    driver: local
  redisdata:
    driver: local
  fsdata:
    driver: local

标签: phplaraveldockerredisdocker-compose

解决方案


我目前通过添加--no-scripts到 Dockerfile 并添加了一个start.sh. 因为它是绑定到post-autoload-dump想要访问 Redis 的 Laravel 的包发现脚本。

Dockerfile 摘录

#...
# Change current user to www
USER www

# Install packages
RUN composer global require hirak/prestissimo && composer install --no-scripts

RUN chmod +x /var/www/scripts/start.sh

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["/var/www/scripts/start.sh"]

启动.sh

#!/usr/bin/env sh
composer dumpautoload
php-fpm

推荐阅读