Database connection fails during composer install with eloquent query in service provider boot method

I’m having trouble with my Laravel service provider. I put a database query in the boot method to share some data with all views, but now composer commands are breaking.

Here’s my service provider code:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\View;

class MyServiceProvider extends ServiceProvider
{
    public function register()
    {
        //
    }

    public function boot()
    {
        Paginator::useBootstrap();
        
        // This line causes the problem
        View::share('menuItems', \App\Models\MenuItem::orderBy('position', 'desc')->get());
    }
}

When I run composer install, I get this database error:

@php artisan package:discover --ansi

Illuminate\Database\QueryException

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for mysql failed: Temporary failure in name resolution (SQL: select * from `menu_items` order by `position` desc)

at vendor/laravel/framework/src/Illuminate/Database/Connection.php:759

The weird thing is that my website works perfectly fine when I access it through the browser. The database connection works and data loads correctly. This error only happens when running composer commands.

If I comment out the View::share line, composer works without issues. But I need that data available in all my views.

My database config:

DB_CONNECTION=mysql
DB_HOST=mysql  
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=sail
DB_PASSWORD=secret

I noticed something strange. When I change DB_HOST to 127.0.0.1, the composer command works but then my website can’t connect to the database anymore. This makes sense because I’m using Docker and the mysql service is named ‘mysql’.

Why does composer try to run database queries during package discovery? Is there a better way to share this data with views that won’t cause issues during composer operations?

Hmm, interesting - are you running composer inside your Docker container or on your host machine? If it’s on the host, that’d explain why it can’t reach the ‘mysql’ hostname. What if you wrap that query in a try-catch or check if the app’s in console mode first?

yeah, had this issue too! you can solve it by adding if (!app()->runningInConsole()) around your View::share line. this way, composer won’t hit the db but your views will still load fine!

The problem is your service provider’s boot method runs during composer operations, including package discovery. Your database query fires every time the app bootstraps - even during composer commands. The hostname fails because composer runs outside your Docker environment where ‘mysql’ doesn’t exist. Don’t put the query directly in boot(). Use a view composer for the specific views that need this data instead. Create a view composer class and register it like View::composer(['layouts.app', 'partials.menu'], MenuComposer::class). This way the query only runs when those views actually render, not on every bootstrap. Alternatively, check if you’re in console mode with app()->runningInConsole() to skip the query during console operations.