Thursday, July 4, 2024

Things that can't play nice. EACCES when installing Angular

Have you ever had one of those experiences when you try and install something on your system and it really feels like absolutely every. single. step takes a lot more effort and hassle than it ought to?  Before long you're exhausted from fighting your machine, you feel more lost than you did when you started, and now you're wondering what it would take to roll your system back to the point before you started so you don't have all the extra junk on your system from the battle you've been having?

Yeah.

It is often the case that we work with technologies that are constantly changing.  Angular, for example, releases a new version every 6 months.  That usually isn't a big problem if you already have it installed and running.  Then, all you have to do is update.

But what happens when you're setting up a new environment?  When something goes wrong, you head on over to Stack Overflow, Baeldung, or whatever your favorite source of advice is and look for the answer.  Simple enough, we do that all the time.  But what happens when there are a dozen different methods of doing what you want, some of which still work on the latest versions, some don't, and there's always a variety of other approaches that will lead you astray because whoever offers that advice is making certain assumptions about your environment that may not be accurate.

I decided I needed to refresh my Angular skills (among others) so I created a new Ubuntu Linux VM on my machine.  I prefer Linux environments to Windows anyway.

"Well you know, ArcticFox, installing Angular on Windows is very easy.  Just do that!"

"Easy" is not the goal.  The goal is to learn something, exercise skills, and avoid giving Microsoft more data to sell. 

So we take our Linux VM, running Ubuntu 24.04 LTS.  What's our first step?

Step 1

Well, first we need our JavaScript framework, Node.js.  It should be at least version 14.20 when installed on Ubuntu 24.04.

After doing the usual sudo apt-get update to be sure all of your packages are up to date...

Your screen should look like this.  Don't get used to it,
 things will not continue going this smoothly for long.

Great, so all of our packages are up to date so we use apt-get to install nodejs and npm.

sudo apt-get install nodejs

Now, some sources will tell you to use the command "apt-get install nodejs npm."  Do not do that.  npm comes with nodejs anyway so there's no need to specify it, and if this is a fresh install then some of the package dependencies won't yet have been installed and you'll get a nasty error that will have you chasing your tail needlessly.  (Is there ever a time when one does need to chase their tail?)

This is what it looks like without errors.  If yours looked
like this on your first try, then pat yourself on the back.

Now we see if the installation went well.  We can do that by seeing what happens when we run node and npm each with a -v.  This proves that the commands are now in our path and shows us what version we just installed.

node -v
npm -v

Hopefully, your screen looks something like that with no 
"Command not found" errors.

Now, if at some point something went wrong and you're getting an error because of missing dependencies when installing nodejs don't panic.  Just go ahead and install them.  This line of code should cover everything you need:

sudo apt install curl gnupg2 gnupg git wget -y

Some of this stuff is probably already on your system but it won't hurt anything to include them in the command.

If you had dependency errors, yours won't look like this because it will have been 
installing the stuff you were missing.   Hopefully.

And now, we install Angular using the Node Package Manager.  Note that we are not using sudo here, because we're letting the Node Package Manager handle everything.  In fact, it would be a BAD idea to use sudo here.

npm install -g @angular/cli

It is at this point that some people, those who were favored by the Universe, will be able to continue.  The rest of us will  have to deal with this hideous error:


The Pain Train has left the station.

The problem with any "permission denied" error in Linux is that it could mean you don't have permissions, but it could also mean the destination file path doesn't exist.

Now, I know that the output there suggests running the command again as root.  (By using sudo).  Do not do it.  I know it's tempting.  It would probably even work to get past this step, but if you do you're asking for headaches down the road.

So the script failed when it tried to do a mkdir on /usr/lib/node_modules.

So first let's make sure the node_modules folder exists.


There it is!

Ok it's there.  Note also the permissions.  The owner is root, and nobody else gets write permissions.

What, if anything, is already in that folder?

Stuff.  Stuff is what's in that folder.

So that folder was indeed created when we installed npm, but we did that with sudo, remember?  So of course the folder is owned by root.  

No, that doesn't mean rerunning the Angular install with sudo.  Chill.


Now WE have the power.

Ok so now you own the folder.  Let's run that install again.

Chooo choooooooo!

Same error!  Wait... no... not the same.  Now we have a problem where it wants to create a symlink in another folder that it doesn't have permissions on.  Namely, /usr/bin.  Now, I'm not really a fan of taking ownership of that folder.  It can have unexpected side effects, especially if anyone else uses that same machine.  So what we can do is give write permissions just for now without changing the owner.

sudo chmod o=rwx /usr/bin

Now the folder will look like this:

Now everybody can write to it...  Hm...

Now we run the install once again.


And you don't even have to use the wrong argument like I did to test.  Neato!

Once you run the install once more, you should see no more errors.  Now when you enter 

ng --version

You'll get a response with the version of Angular that's installed on your machine.

Now, I'm not a fan of leaving critical Linux folders with wonky permissions so let's put /usr/bin back the way it was and test to be sure we're still good.

Presto!

And now we can even check to see what new stuff we have 



And now the @angular folder being present tells us that all is right with the world.  I'm inclined to leave ownership of the node_modules to myself since it isn't a critical Linux folder and since I am the only one who will ever use this VM, but if you're sharing a machine with others you'll want to be sure that folder is accessible to them as well if they're going to be doing any work with npm, since they may have to install modules there as well.
















No comments:

Post a Comment