why couldn't he install pcntl extension?
Issues working between Linux and Windows environments
I'm working on a hobby project with a friend from work. I'm working in Linux and he's on Windows. We're using my repo as the base. When he cloned the repo and went to run npm install and composer install, it ran successfully, but then when he tried to run composer dev he gets an error regarding pcntl. The error says "The [pcntl] extension is required to run Pail". Temporarily, I told him to update composer.json to remove the dev requirement for Pail and remove it from the "dev" command. This isn't a long-term solution since Pail is the logging framework lol. We're looking for a more long-term solution so that he doesn't have to remove those lines.
Lastly, after doing that, we started running into an issue when running composer dev, the local server couldn't bind to 8006, 8007, 8008, 8009, and 8010, then the processes in the dev command exit with code 1.
Is there a fix for these issues so we can seamlessly dev between Windows and Linux? I don't have a Windows environment to develop, and my friend won't do well in Linux :D
I'm not entirely sure. From Googling the error it seems to be an issue with Windows. It should have been fixed in a newer version of Pail that we are using (since this is a new project, it should be using the latest version with the fix), but he gets the error when running composer dev saying that extension is required to run Pail. Is there anything we can check to ensure it's actually installed on his machine? I did not have these issues on Linux. I ran the commands from the Laravel documentation to install composer, php and the Laravel installer and was off to the races.
There is no pcntl extension on Windows. So, it is unable to use Pail on Windows.
Luckily, latest Laravel installer deliberately removes php artisan pail --timeout=0 from composer.json dev script when running in Windows:
...
"scripts": {
"dev": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
],
and it becomes this:
"npx concurrently -c \"#93c5fd,#c4b5fd,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"npm run dev\" --names='server,queue,vite'"
It happens when you set up new project with laravel new project-name and doesn't happen if you act old way like this: composer create-project laravel/laravel project-name
So, remove php artisan pail --timeout=0 from composer.json / scripts / dev and after that you will be able to run composer dev on Windows.
So then what does Windows use for logging if not Pail? This should work and is what we did, but then we got the other port error described where it could not bind to the other ports. Any ideas about that?
Pail is not for logging. Pail is for viewing logs. Your logs will still be logged without it, just use something else to view them on Windows. I personally use Notepad++ with "monitoring" mode (like tail -f).
Your error about ports 8000, 8001 etc is not about Pail at all, it's about php artisan serve can't use already used port. I think this error will be gone after reboot.
Another reason is you messed up your composer.json, can you show it and the error?
Ah, my mistake.
So after reboot he should be good. That's good to hear and confirms what I thought would fix the port issue too. I also thought it could be Herd since I had him try installing that the other day too since he was having some other issues with npm before lol.
This should be what his composer.json looks like. I walked through making these changes this morning. The changes should just be:
- Removing
laravel/pailfromrequire-dev - Removing
php artisan pailfrom thedevcommand
{
"$schema": "https://getcomposer.org/schema.json",
"name": "laravel/vue-starter-kit",
"type": "project",
"description": "The skeleton application for the Laravel framework.",
"keywords": [
"laravel",
"framework"
],
"license": "MIT",
"require": {
"php": "^8.2",
"inertiajs/inertia-laravel": "^2.0",
"laravel/fortify": "^1.30",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1",
"laravel/wayfinder": "^0.1.9"
},
"require-dev": {
"fakerphp/faker": "^1.23",
"laravel/boost": "^1.8",
"laravel/pint": "^1.24",
"laravel/sail": "^1.41",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.6",
"pestphp/pest": "^4.1",
"pestphp/pest-plugin-laravel": "^4.0"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"setup": [
"composer install",
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
"@php artisan key:generate",
"@php artisan migrate --force",
"npm install",
"npm run build"
],
"dev": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#93c5fd,#c4b5fd,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
],
"dev:ssr": [
"npm run build:ssr",
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"php artisan inertia:start-ssr\" --names=server,queue,logs,ssr --kill-others"
],
"test": [
"@php artisan config:clear --ansi",
"@php artisan test"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force",
"@php artisan boost:update --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi",
"@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
"@php artisan migrate --graceful --ansi"
],
"pre-package-uninstall": [
"Illuminate\\Foundation\\ComposerScripts::prePackageUninstall"
]
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true,
"php-http/discovery": true
}
},
"minimum-stability": "stable",
"prefer-stable": true
}
Also remove "server" from names=server,queue,logs,vite. See my message above, I copied command from working composer.json that was tuned by Laravel installer on Windows.
I still recommend to implement dummy php artisan pail command so you can use Pail on Linux. If you remove it from composer.json you don't run Pail as well. Why lose good tool?
And don't remove Pail from dev dependencies, why? Handle differences among dev environments in .env file, not in a whole composer.json.
If you'd like to be consistent with your Windows buddy, let him create a dummy php artisan pail command:
php artisan make:command DummyPailCommand --command=pail
With signature:
protected $signature = 'pail {--timeout=0}';
I didn't try but it should work. Maybe you'll have to make this command to run forever and do nothing with infinite loop & sleep.
Update: maybe dedicated command is not the solution as you will lose ability to run Pail on Linix as well. Then register a closure command in routes/console.php with infinite sleep conditionally, based on some .env variable like PAIL_DUMMY_ENABLED which is true for your friend and false for you.
Having this in routes/console.php allows you to use composer run dev on Linux and Windows without changing composer.json at all:
if (class_exists('Laravel\Pail\Console\Commands\PailCommand')) {
$pail_proxy = new class extends Laravel\Pail\Console\Commands\PailCommand {
protected $description = 'Proxy Pail command for Windows environments';
public function handle (ProcessFactory $processFactory): void
{
if (windows_os()) {
$this->warn("Pail doesn't work on Windows, doing nothing until termination...");
while (true) {
Sleep::for(1)->minute();
}
}
parent::handle($processFactory);
}
};
Artisan::registerCommand($pail_proxy);
}
This should be what his composer.json looks like.
his composer.json should be your composer.json. You should both have the same file, installed from your repository.
Hi there @tom-kwon ,
I cannot help you with the current error/issue you are having, but I would like to suggest you to use docker and figure out that environment - it solves everything, as the environment is confined in a container (no issues with windows/linux/macos).
Best regards,
Aleksandar
If you're not using docker to share environment setups, I would strongly recommend that your friend uses WSL.. you'll both be running on Linux then (and pcntl will be available to said friend) and he can keep using his windows box for the IDE etc etc.
Although I use docker to run my apps in (still within WSL), I've not run PHP on windows since 5.1.. it's definitely the best of both worlds (I use windows for PHPStorm and all of the actual dev stuff/code/git etc resides in the WSL side of things).
You can also just install PHP on WSL and run the project there, without Docker. That's what I do.
Yup.. as the Op and friend aren't using docker, this would be the best alternative.
WSL was such a great addition to the windows world IMO. I certainly don't miss dual-booting or heavy VMWare+Vagrant setups and even beyond the application side of things.. just being able to use a linux shell for things was a huge step forward over windows console or cygwin.
@ctrlaltdelme This is why you use something like Docker to create a consistent development environment, no matter who is working on the project or what OS they’re using, instead of relying on everyone working on the project to have the exact same versions of Node and PHP installed, the exact same set of extensions installed, etc.
Please or to participate in this conversation.