Skip to content

[8.x] Local dev server spawns a new server on port number + 1 when environment reloaded #34121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
vaughany opened this issue Sep 3, 2020 · 20 comments

Comments

@vaughany
Copy link
Contributor

vaughany commented Sep 3, 2020

  • Laravel Version: 8.x-dev
  • Jetstream Version: 0.6.0
  • PHP Version: 7.4.9
  • Database Driver & Version: SQLite 3.22

Description:

Development server (run with ./artisan serve) cannot listen on same port after .env file reloaded, and starts another server on one port higher. The existing dev server is not shut down when the .env file is edited and saved, so the port's already in use.

Steps To Reproduce:

  1. Create fresh Laravel project using the new installer: laravel new foo --jet --dev.
  2. Configure the database details in .env, then run migrations with ./artisan migrate:fresh.
  3. Serve the project with ./artisan serve - a local dev server is successfully started on port 8000
  4. Modify the .env file and save - a new local dev server is started on port 8001
  5. http://localhost:8000 and http://localhost:8001 both serve my project.
paul@ubuntu:~/projects/foo$ ./artisan serve
Starting Laravel development server: http://127.0.0.1:8000
[Thu Sep  3 16:56:31 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8000) started
[Thu Sep  3 16:56:45 2020] 127.0.0.1:51424 Accepted
[Thu Sep  3 16:56:45 2020] 127.0.0.1:51424 Closing

# .env file is modified.

Environment modified. Restarting server...
[Thu Sep  3 16:57:42 2020] Failed to listen on 127.0.0.1:8000 (reason: Address already in use)
Starting Laravel development server: http://127.0.0.1:8001
[Thu Sep  3 16:57:42 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8001) started

# .env file is modified again.

Environment modified. Restarting server...
[Thu Sep  3 16:58:25 2020] Failed to listen on 127.0.0.1:8001 (reason: Address already in use)
Starting Laravel development server: http://127.0.0.1:8002
[Thu Sep  3 16:58:25 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8002) started

@driesvints
Copy link
Member

I can't reproduce this. Works fine for me:

master $ a serve                                                                                                                                                                                                                        ~/Sites/test-laravel8
Starting Laravel development server: http://127.0.0.1:8000
[Thu Sep  3 18:25:13 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8000) started
[Thu Sep  3 18:25:15 2020] 127.0.0.1:52735 Accepted
[Thu Sep  3 18:25:15 2020] 127.0.0.1:52735 Closing
[Thu Sep  3 18:25:15 2020] 127.0.0.1:52739 Accepted
[Thu Sep  3 18:25:15 2020] 127.0.0.1:52739 Closing
[Thu Sep  3 18:25:15 2020] 127.0.0.1:52740 Accepted
[Thu Sep  3 18:25:15 2020] 127.0.0.1:52740 Closing
Environment modified. Restarting server...
[Thu Sep  3 18:25:38 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8000) started
[Thu Sep  3 18:25:42 2020] 127.0.0.1:52763 Accepted
[Thu Sep  3 18:25:43 2020] 127.0.0.1:52763 Closing

@Aslam97
Copy link

Aslam97 commented Sep 3, 2020

I've the same problem

Starting Laravel development server: http://127.0.0.1:8000
[Thu Sep  3 23:13:51 2020] Failed to listen on 127.0.0.1:8000 (reason: Address already in use)
Starting Laravel development server: http://127.0.0.1:8001
[Thu Sep  3 23:13:54 2020] 127.0.0.1:48284 [200]: /favicon.ico
[Thu Sep  3 23:13:58 2020] 127.0.0.1:48320 [200]: /favicon.ico
Environment modified. Restarting server...
[Thu Sep  3 23:19:47 2020] Failed to listen on 127.0.0.1:8001 (reason: Address already in use)
Starting Laravel development server: http://127.0.0.1:8002
Environment modified. Restarting server...
[Thu Sep  3 23:47:49 2020] Failed to listen on 127.0.0.1:8002 (reason: Address already in use)
Starting Laravel development server: http://127.0.0.1:8003

@vaughany
Copy link
Contributor Author

vaughany commented Sep 3, 2020

Hi @driesvints. Is there anything else I can do, or any information I can provide that would assist?

I've just tried this again, with an even simpler setup (no --jet), and no db setup or migrations, not even changed the .env file from the default (and all I did to force reload of the environment is to add an extra 'l' to APP_NAME in the .env file:

$ laravel new --dev foo
...
$ cd foo
$ php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
[Thu Sep  3 19:24:40 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8000) started
Environment modified. Restarting server...
[Thu Sep  3 19:24:57 2020] Failed to listen on 127.0.0.1:8000 (reason: Address already in use)
Starting Laravel development server: http://127.0.0.1:8001
[Thu Sep  3 19:24:58 2020] PHP 7.4.9 Development Server (http://127.0.0.1:8001) started

Unsure if it matters, but I'm running Ubuntu 18.04.5, Composer 1.10.10, and of course version 4.0.0 of the Laravel installer. Let me know if I can provide any further information.

@AegirLeet
Copy link
Contributor

The old processes are never terminated, leading to a bunch of zombie processes and used up ports.

1
2

@driesvints
Copy link
Member

Is everyone who's experiencing this using Ubuntu? I can't reproduce this on macOS.

@AegirLeet
Copy link
Contributor

Xubuntu in my case.

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.5 LTS
Release:	18.04
Codename:	bionic

@vaughany
Copy link
Contributor Author

vaughany commented Sep 4, 2020

The processes don't 'zombie' for me: if I run php artisan serve then edit .env to force the environment reload, then the site on port 8000 (the 'old' one) as well as the site on port 8001 (the 'new' one) both work, serving up the local dev site as expected.

Also, if I serve the local dev site and force the config to reload 10 times, it spawns sites on ports 8000 to 8010, then cannot create any more (as I think the upper port limit is 8010) then the serve command quits, leaving the 11 websites still being served (and they still work as expected), and I have to kill them via top:

Screenshot from 2020-09-04 09-56-14

@AegirLeet
Copy link
Contributor

@vaughany That's what I meant by "zombie" - they're just left hanging around, even though they should have terminated. They do work, they're just not supposed to exist anymore.

@vaughany
Copy link
Contributor Author

vaughany commented Sep 4, 2020

@AegirLeet Apologies, took you too literally. :)

@vaughany
Copy link
Contributor Author

vaughany commented Sep 4, 2020

@driesvints Some troubleshooting with different Ubuntus:

I used Vagrant to spin up Ubuntu 16.04.5 LTS with PHP 7.4.9, and got the same issue.

I used Vagrant to spin up Ubuntu 20.04 LTS with PHP 7.4, and got the same issue.

I used Vagrant to spin up Debian 10.5 with PHP 7.3.19, and got the same issue.

@taylorotwell
Copy link
Member

Pull requests welcome. I don't use Ubuntu.

@vaughany
Copy link
Contributor Author

vaughany commented Sep 4, 2020

Troubleshooting steps: running ps -ef | grep php when artisan serve is running shows, amongst other cruft:

sh -c '/usr/bin/php7.4' -S 127.0.0.1:8000 '/foo/server.php'
/usr/bin/php7.4 -S 127.0.0.1:8000 /foo/server.php

So the first line is the shell command, and the second is the command the shell command runs. Makes sense so far.

If I reload the .env file, and run ps -ef | grep php again, I now see this:

sh -c '/usr/bin/php7.4' -S 127.0.0.1:8001 '/foo/server.php'
/usr/bin/php7.4 -S 127.0.0.1:8001 /foo/server.php
/usr/bin/php7.4 -S 127.0.0.1:8000 /foo/server.php <-- this should have been killed.

So it seems that the original command sh -c has been successfully terminated, however the command run by sh was not. I'll look into this further as soon as I can.

Edit: stripped the info out, but the command starting /usr/bin/php7.4 is definitely a child process of the command starting sh -c. The PID that $process->getPid() has is that of the parent, but as I said, it seems that the child process is not killed when the parent process is.

@AegirLeet
Copy link
Contributor

AegirLeet commented Sep 4, 2020

symfony/symfony#5030

Prefixing the command at

/**
* Get the full server command.
*
* @return string
*/
protected function serverCommand()
{
return sprintf('%s -S %s:%s %s',
ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)),
$this->host(),
$this->port(),
ProcessUtils::escapeArgument(base_path('server.php'))
);
}
with exec seems to work.

This would break Windows though (not sure about macOS), so it would have to be done conditionally for Linux only.

@vaughany
Copy link
Contributor Author

vaughany commented Sep 4, 2020

Sure enough, forcing Process::isSigchildEnabled() (as mentioned in the Symfony issue @AegirLeet linked to) to return true fixes the issue. So I guess this is primarily a Symfony issue? Unsure how to progress with this.

@AegirLeet
Copy link
Contributor

Looks like Symfony's process component actually already has a fix for this in place at https://github.com/symfony/symfony/blob/c2522fa325c36baf278b4390a0d7fd0a339ebc1c/src/Symfony/Component/Process/Process.php#L298-L301, but this isn't used because the commandline isn't supplied as an array (?). Letting the process component handle it through that mechanism would probably be better.

@AegirLeet
Copy link
Contributor

Using new Process(['/path/to/php', '-S', 'hostname:port', '/path/to/server.php'], ...) instead of Process::fromShellCommandline(...) works, at least on Linux. Not sure what other effects that might have though.

@aminjavadi02
Copy link

mine was just another terminal working on 8000 (which was not closed properly and was still running ), so when i killed it, the serve command got back on 8000

@gavalierm
Copy link

gavalierm commented Nov 14, 2024

This happend to me right now on lates Laravel and PHP installed from brave on mac.

   INFO  Server running on [http://127.0.0.1:8000].  

  Press Ctrl+C to stop the server


   INFO  Environment modified. Restarting server...  

  Failed to listen on 127.0.0.1:8000 (reason: Address already in use)

   INFO  Server running on [http://127.0.0.1:8001].  

  Press Ctrl+C to stop the server

And when i stop server using ctrl+c all process are stoped and when i start server again is on 8000 again...

@Zeno97
Copy link

Zeno97 commented Jan 6, 2025

Same here on macos sequoia 15.2 with php 8.4 on fresh laravel 11 project
Is there some news?

This happend to me right now on lates Laravel and PHP installed from brave on mac.

   INFO  Server running on [http://127.0.0.1:8000].  

  Press Ctrl+C to stop the server


   INFO  Environment modified. Restarting server...  

  Failed to listen on 127.0.0.1:8000 (reason: Address already in use)

   INFO  Server running on [http://127.0.0.1:8001].  

  Press Ctrl+C to stop the server

And when i stop server using ctrl+c all process are stoped and when i start server again is on 8000 again...

@TimothyDLewis
Copy link

Encountering a very similar issue, but with static port, not with sequential ports:

  • Mac OS Sequoia 15.1.1
  • PHP 8.3.13
  • Laravel 11.37.0 (and Laravel 10.x, but only Laravel 11.37.0 is affected)

I run multiple Laravel projects, multiple versions, different host/port locally, like so:

hosts:

127.0.0.1	localhost
127.0.0.1 project-a.test
127.0.0.1 project-b.test
127.0.0.1 project-c.test
127.0.0.1 project-d.test
::1             localhost

.zshrc:

# Laravel 10
alias serve_project_a="php artisan serve --host=project-a.test --port=8000"
alias serve_project_b="php artisan serve --host=project-b.test --port=8001"
alias serve_project_c="php artisan serve --host=project-c.test --port=8002"
# Laravel 11
alias serve_project_d="php artisan serve --host=project-d.test --port=8003"

I've got iTerm2 Profiles set up to run these, and they all work initially and expose http://project-X.test:800Y:

Laravel 10 Projects:

cd /path/to/project-a && clear && serve_project_a

INFO  Server running on [http://project-a.test:8000].

Press Ctrl+C to stop the server

2025-01-09 16:11:20 ............................................................................................. ~ 1s
2025-01-09 16:11:21 /css/bootstrap.min.css ...................................................................... ~ 0s
2025-01-09 16:11:21 /css/favicon.png ............................................................................ ~ 0s
2025-01-09 16:11:21 ............................................................................................. ~ 0s

INFO  Environment modified. Restarting server...

INFO  Server running on [http://project-a.test:8000].

Press Ctrl+C to stop the server

As you can see, no issues for projects A (and B and C, again all Laravel 10, being served on different hosts/ports using php artisan serve)

Laravel 11 Project:

cd /path/to/project-d && clear && serve_project_d

INFO  Server running on [http://project-d.test:8003].

Press Ctrl+C to stop the server

2025-01-09 16:13:16 / ...................................................................................... ~ 0.29ms
2025-01-09 16:13:17 /favicon.ico ........................................................................... ~ 0.07ms

INFO  Environment modified. Restarting server...

Failed to listen on project-d.test:8003 (reason: Address already in use)

Running lsof -i :8003 shows 4 processes (although interesting observation, there are 5 processes running before this error is displayed, so something is happening on server restart, but not enough, or not the correct thing).

I can live with a simple kill $(lsof -t -i:8003) when I do encounter this, but it's less than ideal for a project that will have it's .env being changed a lot (local project currently in development), so looking forward to seeing if there's a solution. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants