skip to Main Content

My project is defined in a docker-compose file, but I’m not too familiar with docker-compose definitions.

When I try to docker-compose up -d in a fresh setup, the following error occurred during the build of a docker image.

This is after composer install, under post-autoload-dump. Laravel tries to auto discover packages (php artisan package:discover).

Generating optimized autoload files
> IlluminateFoundationComposerScripts::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

The reason it cannot connect to my_redis:6379 is because my_redis is another service in the same docker-compose.yml file. So I assume the domain is not ready yet, since docker-compose wants to first build my images before hosting containers.


EDIT I just found this GitHub issue linking to my problem: https://github.com/laravel/telescope/issues/620. It seems that the problem is related to Telescope trying to use the Cache driver. The difference is I’m not using Docker just for CI/CD, but for my local development.


How can I resolve this problem? Is there a way to force Redis container to up first before building my_app? Or is there a Laravel way to prevent any domain discovery? Or is there a way to specify the building of an image depends on another service to be available?


If you want to see my 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

3

Answers


  1. Chosen as BEST ANSWER

    I currently mitigated this by adding --no-scripts to Dockerfile and added a start.sh. Since it is Laravel's package discovery script that binds to post-autoload-dump that wants to access Redis.

    Dockerfile excerpt

    #...
    # 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"]
    

    start.sh

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

  2. There is a way to force a service to wait another service in docker compose depends_on, but it only wait until the container is up not the service, and to fix that you have to customize redis image by using command to execute a bash script that check for redis container and redis daemon availability check startup-order on how to set it up.

    Login or Signup to reply.
  3. I’m sure you’ve resolve this yourself by now but for anyone else coming across this question later, there are two solutions I have found:

    1. Ensure Redis is up and running before your App

    In your redis service in docker-compose.yml add this…

    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
    

    …then in your my_app service in docker-compose.yml add…

    depends_on:
      redis:
        condition: service_healthy
    

    2. Use separate docker compose setups for local development and CI/CD pipelines

    Even better in my opinion is to create a new docker-compose.test.yml In here you can omit the redis service entirely and just use the CACHE_DRIVER=array. You could set this either directly in your the environment property of your my_app service or create a .env.testing. (make sure to set APP_ENV=testing too).

    I like this approach because as your application grows there may be more and more packages which you want to enable/disable or configure differently in your testing environment and using .env.testing in conjunction with a docker-compose.testing.yml is a great way to manage that.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search