Sometimes, especially when you're at the beginning of your career, it can seem that you're following the instructions and getting nowhere - while everyone else seems to find it terribly easy.
It can be pretty disheartening, and I want to describe a couple of ways I experience exactly the same thing even after, well, decades. So here I am, trying to detail the stumbles and bumbles I make trying to get things to work. This is my first post on the subject, but I hope to make more.
Let's learn Laravel.
Laravel strives to provide an amazing developer experience [...]
Whether you are new to PHP web frameworks or have years of experience [...]
Laravel is touted as being the "developers' framework, at least in PHP circles, because it's more bare-bones than the others and it takes simple yet strict architecture decisions. I've done a few other PHP frameworks - Drupal 7, Drupal 8+, Symfony, WordPress, Concrete5, PrestaShop, CodeIgniter off the top of my head - so I'm not going into this unprepared.
I'll start from a barebones laptop and see how far I get.
Installing prerequisites (tldr; issues: zero, confidence: supreme)
Before creating your first Laravel application, make sure that your local machine has PHP, Composer, and the Laravel installer installed. In addition, you should install either Node and NPM or Bun so that you can compile your application's frontend assets.
OK. Not a problem. I'll apt install
myself some of that PHP, get composer from... getcomposer.org, and figure out how to install the "Laravel installer" next. Aparently my distro has Node 22 out the box, or it installed when I set something else up earlier, so that should be covered.
$ composer global require laravel/installer
Boom. Done. No problems yet, we're off to a good start and confidence is at an all-time high.
Setting up a new Laravel project (tldr; issues: some, confidence: high)
$ laravel new example-app
zsh: command not found: laravel
Oh. Maybe I have to revisit that supreme confidence thing.
So it seems that composer doesn't install anything into regular binary paths and the composer installer doesn't do anything to add itself to the system path either. I've never really had to face that before, since I've directly run composer-installed binaries from whatever path they appear in. For example, with Drupal, there's vendor/drush/drush/drush
or vendor/bin/drush
depending on which version you're running. Do I need to add myself a symlink or alias or find the laravel binary wherever composer added it, "globally"?
I don't know, so I have to search for this.
I find some clues on a Stack Overflow answer: you can find the composer binary directory with composer global config bin-dir --absolute
, and apparently in modern versions of composer everything with an executable command gets it put into that directory rather than losing itself to the hierarchy.
Good. I can add something to my startup script to put that in my path... except that command produces more than just the path...
$ composer global config bin-dir --absolute
Changed current directory to /home/moopet/.config/composer
/home/moopet/.config/composer/vendor/bin
... and I can't use that whole string as a directory. Maybe I'll need to use tail
to get the last line, or something. Wait, no there's another comment on this SO answer which includes the --quiet
flag. What does that do? I'll try composer --help
:
Usage:
list [options] [--] [<namespace>]
Well, uh, turns out that running --help
on a bare composer
command actually gives help for the list
subcommand rather than composer itself. That had me stumped for a minute.
-q --quiet Do not output any message
Hmm, that doesn't sound useful! We want some output. What else is there?
--raw To output raw command list
--format=FORMAT The output format (txt, xml, json, or md) [default: "txt"]
Maybe it's one of these?
The "--raw" option does not exist.
The "--format" option does not exist.
Nope. Like I thought, these are options to list
and not general use flags.
Let's run it with --quiet
anyway, just for poops and funsies:
$ composer global config bin-dir --absolute --quiet
/home/moopet/.config/composer/vendor/bin
Well, what do you know, it worked. It's just badly documented.
I'll pop that into my shell startup script with a little guard code and we can continue:
if command -v composer >/dev/null; then
export PATH=$(composer global config bin-dir --absolute --quiet):$PATH
fi
Setting up a new Laravel project, take 2 (tldr; issues: some, confidence: wavering)
This time laravel new example-app
launches, and prompts me for a few things. I accept the defaults, since I haven't read far enough in the documentation to know the difference, except for the starter kit. I choose, "Breeze" because that's how it is in the documentation.
It starts the installation process and all looks good until:
- Root composer.json requires laravel/pint ^1.0 -> satisfiable by laravel/pint[v1.0.0, v1.1.0, v1.1.1].
- laravel/pint[v1.0.0, ..., v1.1.1] require ext-xml * -> it is missing from your system. Install or enable PHP's xml extension.
Wait, PHP needs the XML extension? That was never listed as a requirement! OK, I'll do a quick apt install php-xml
.
Good, all installed. I'll run the setup again.
laravel new example-app
In NewCommand.php line 789:
Application already exists!
Oh.
So the installer got part way through, failed because it hadn't verified its dependencies, and has left the app in a broken state. That's not a good sign. Laravel's on, what, version 11?
Surely they'd have basic up-front requirements checking by now? Oh well. I'll just rm -r example-app
and start again, nothing lost because I haven't really started yet.
Long story short1 the next missing dependency was the the DOM extension, or maybe the XML extension. Or maybe the cURL extension.
- phpunit/phpunit[11.0.1, ..., 11.4.3] require ext-dom * -> it is missing from your system. Install or enable PHP's dom extension.
- Root composer.json requires phpunit/phpunit ^11.0.1 -> satisfiable by phpunit/phpunit[11.0.1, ..., 11.4.3].
So I need to install php-dom
? No. Try some others. Stack Overflow again. Turns out I need to install php-curl
. Riiiight.
Onward. rm -r
the directory and run through the setup wizard again.
Setting up a new Laravel project, take 3 (tldr; issues: hngg, confidence: still wavering but bolstered by recent problem-solving success)
It prompts me for which database server to use. All of them say, "Missing PDO extension" next to them.
Sigh.
I break out of the installer, delete the whole directory again, apt install php8.3-mysql
because there's no direct php-pdo
package and no alias for php-mysql
that works either, so I've done some tiresome apt search
ing.
Illuminate\Database\QueryException
SQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select exists (select 1 from information_schema.tables where table_schema = 'laravel_example_app' and table_name = 'migrations' and table_type in ('BASE TABLE', 'SYSTEM VERSIONED')) as 'exists')
What the what now? At no point has this installer asked me for connection details for a database. And it's trying to run SQL commands against... something. Who knows?
As it happens, I have a MySQL server running on another host in my LAN and was prepared to use that (even though I'll note that bringing your own database was not listed as a requirement for Laravel). I guess I should have installed SQLite, maybe that would have worked, since it won't need any credentials.
sudo apt install php8.3-sqlite
Try again.
rm -r example-app
laravel new example-app
...
Great success. Hacker voice "I'm in". For the win. Success kid.
Conclusion
I made it? I think.
But if someone had asked me how long this might take, then based off the enthusiastic documentation and reputation, I'd have said 20 minutes. If I was doing it for work, my project manager would have doubled or quadrupled that based on experience of developer estimates.
How long did it really take me? An hour or so one evening and an hour or so the next day. I wasn't rushing, but it wasn't straightforward.
And you know what? I'm not happy with it. It's not using MySQL, because that part of the installer appears to be completely broken. I'm using SQLite and that's one step further from what would be going on in a real production environment. So there're definitely some things left on the TODO list before I can get going with the actual tutorials.
But it runs. The build steps claim they went without a hitch.
I'm ready for the next phase: fixing the JsonException
, Syntax error
and ProcessTimedOutException
that appear in the console as soon as I open the demo page in my browser.
Uh-oh.
If only things worked out the box, eh.
EDIT:
I'd like to remind anyone that while I'm grateful for any comments, I'm not looking for solutions to the problems I found in this post. It's about the journey, and how it's difficult for everyone sometimes. I plan on making more posts with the same general aim. There are a lot of good tutorials and questions where people are asking for help already on DEV, and they might be a better place to help out!
-
Chorus: too late ↩
Top comments (22)
I love Laravel, but in their endless quest to make things "simpler" I feel they ended up making things way more complicated and confusing ...
Apart from "the Laravel installer" we have Valet, we have Herd, we have Sail, and I probably forgot a couple of others ...
When you want to add signup/login/authentication to your app, you're faced with literally half a dozen alternatives - there's Breeze, there's JetStream, there's Fortify, there's Sanctum, there's Passport, there's Socialite, and I probably forgot half a dozen other options - I found it a nightmare to make a choice.
Most funny thing IMO is that with Laravel 11 they tried to "simplify" even more by sweeping a lot of options which there out in the open in previous versions under the rug, hiding them behind a simplistic interface - nice for noobs, not so nice for people who already know Laravel and are now wondering "where did all my settings go ... ?"
But, I love Laravel, I really do - it's elegant and powerful - but it does NOT promote the principle "there's one and only one way to do something" - with Laravel there are always more ways to achieve something, and it can be pretty confusing at times ...
As someone who’s been through similar struggles with setting up Laravel, this post hits home. The detailed recount of troubleshooting is so relatable. Honestly, after experiences like these, moving to a platform like Cloudways was a game-changer for me. Their managed hosting takes care of PHP extensions, Composer, and database setups out of the box. I was able to spin up Laravel apps in minutes without these headaches. Definitely worth considering for anyone tired of the manual setup grind!
nice 👏
Another way of preparing your pc is to use Laravel specific solutions like herd or sail or docker wrappers like ddev or lando.
I use a docker solution, or just plain docker, because that will match the closest with the server. And you can save the config in the codebase, so other people can use the same setup.
From the documentation,
So that doesn't help if you can't get Laravel running, right?
And Herd appears to be Windows and Mac only, which isn't much use.
I have also run Laravel in docker but the point of this post was to show how things aren't straightforward if you just try to follow the instructions as they're given.
If there are no errors with the artisan command, you can run
artisan sail:install
.I wasn't aware Herd is not available on linux. I guess not enough developers use a linux only pc.
I understand your point. The problems you encountered are more composer related problems than Laravel related problems. When I look at the composer files of the packages the php dependencies are added. Is it possible you ignored the warnings during the composer installation? And that is why you didn't add the php extensions?
It's been a long time I have set up a machine from scratch. But I think composer gives you a warning.
Ok, to answer these points in order:
artisan
isn't a dependency, isn't mentioned in their installation instructions, and isn't installed along with PHP or composer. It's not installed to the global composer store as part of the laravel installer; it's part of a laravel project itself. The laravel project needs to be successfully installed before you can run it. In my post, the point where artisan is available to run as a command is the end, where I mark my great success.The rationale for Herd not being on Linux (from the official page) is that Linux users are probably capable of doing all this themselves anyway - which is probably fair enough but I'm trying to demonstrate that following instructions isn't as simple as it appears :)
Composer doesn't list any warnings or errors when installing laravel. None on the things I had to install manually are in the composer.json file of the laravel installer or the laravel example project. They're presumably dependencies of dependencies, which don't get resolved until the installer's actually running.
After reading your message I regrouped my thoughts and read the post again. You would have had less problems if you checked the server requirements before you started to install LaraveL.
That is take 2 and 3 of your post
The sections before take 2 are about composer. I think we can agree that is outside the scope of Laravel documentation.
My conclusion from the start was that this post is blaming the wrong one for the problems you experienced. I took a detour by suggesting to use php specific containers. And moved it even further from the solution with my second reply. That is my mistake.
Possibly, possibly, however the info about server requirements is under a section called "deployment" and comes after the documentation about "getting started" and "installation". I'm literally devoting this experience to following the instructions as given.
I agree there should be a link to the requirements before the installation process. You can create a pull request on the documentation repository
Try php.new and the follow laravel.build
PHP.new is nice!
For me it's not "nice" at all - as Ben pointed out, it bypasses your OS's package manager ... also pointed out by Ben - which extensions will it install? Pointed out by me - does it include Xdebug? Which PHP version? What about upgrading your PHP version?
Apart from that, PHP is just one thing I'd want to install - there's Apache or Nginx, there's MySQL or PostgreSQL, and so on ... why would I want "ad hoc" custom scripts to install all that? I just want to use my OS's package manager to properly manage it!
So no, not seeing how an "ad hoc" script from a website somewhere is a good solution at all.
I get your point, and I agree with it. But sometimes it's needed to build something that works great for one use case. And that could be a good inspiration if the value proposition works out.
There are lots of examples out there with a script-like solution to get something working. If there's a need for something, and there's nothing else available built-in, then someone will build it. I see it more like an opportunity, than a thread.
I get what you mean - it's just a tool, use it when it's the right tool for the job!
As others have said for Linux
/bin/bash -c "$(curl -fsSL php.new/install/linux)"
However it’s never a bad thing to highlight how installations are never as simple as first expected and this can sometimes be a barrier to entry for a beginner
I think you're missing the point here - I'm detailing what happens if someone with general knowledge follows the instructions, I'm not looking for a solution.
But to respond to the php.new chat, I don't think that's a great way to install software.
You're installing binaries which possibly shadow ones already on your system, by bypassing your existing package manager. This means it's more manual steps to remove once you discover you need a different version of PHP, say. The code also waves a couple of red flags regarding things like useless use of
touch
, or the way that it downloads the laravel installer instead of using composer to install it, presumably because it doesn't install composer fully.The implication is also that either the php.new version of the PHP binary comes with extras baked in or it's irrelevant to the problems I was finding. The only thing that script can do for me is to put
composer
into myPATH
, in a particularly sledgehammer approach.If I was going to do this myself, I'd probably use Ddev :)
Well, nowadays we have php.new to install all needed packages, it simplifies a lot this process
I just took a look at that. It doesn't solve the problem of global composer binaries not being in the path; it's just a special case for laravel really... and you don't get to choose your version or have any of the control you'd have if you installed through your regular package manager.
Oh, and the script is a great example of how not to use the
touch
command which doesn't fill me with confidence :)Completely agree, 100% an "ad hoc" fix and in no way a complete or well thought-out solution - do use it of you want to paint yourself into a corner ;-)
Try Laravel herd follow it’s steps. It was what worked for me.
I was installing this on Linux following the instructions; Herd is for Windows and Mac, so it's not going to help in this case.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.