# Ultimate Guide to Setting Up a Web Development Environment on Linux Ubuntu 24 LTS

Last week, I encountered issues with my existing Ubuntu setup. It was slow and lagging, and I couldn't resolve the problem. Then, I remembered that my laptop had two operating systems installed: Windows and Linux on separate partitions. Suspecting a bug in CrowdStrike, I checked the Windows partition but realized I hadn't used Windows in a long time and didn't need it.

Since I was having problems with my Ubuntu setup, I decided to download the latest version of Ubuntu from the official website. I created a bootable flash disk, backed up my important files, and restarted my laptop. I deleted all partitions for a clean install and installed Ubuntu 24 LTS.

It had been a long time since I set up my web development environment from scratch, so I decided to document the process.

You can find the entire setup process below:

#### Requirements for Web Development with PHP, Nginx, and MySQL

* Latest PHP (8.3 at the time of writing this)
    
* Composer (to install PHP dependencies)
    
* Nginx
    
* MySQL
    
* NodeJS (to install NPM packages)
    
* PNPM (I decided to use this for my new setup)
    
* Git Client
    

## Before installation

I always update my OS before installing anything to ensure all dependencies are up-to-date. Here are the commands I used:

```plaintext
sudo apt update # Update OS packages
sudo apt upgrade # Upgrade OS packages if any needed
sudo apt autoremove # Remove any unnecessary packages
sudo apt autoclean # Clean any broken, or already removed packages
```

## Install PHP

It's straightforward to install PHP on Ubuntu. The following command installs PHP and the required extensions:

Since current up to date PHP version is 8.3, it will install it and all dependencies automatically.

We also need **unzip** and **curl** extensions since we will download something from internet, unzip it to install.

```plaintext
sudo apt install php-cli unzip curl
```

## Install Composer

Composer is a package management tool for PHP and we can install all dependent packages with it easily without spending a lots of time.

So, I decided to install it globally to my system thus I don't need to run it with **root** user which is not **suggested** by composer itself too.

First of all I needed to download it, so I run following command.

```plaintext
curl -sS https://getcomposer.org/installer -o composer-setup.php
```

Then, I needed to verify if downloaded setup file is correct one so I run following commands to verify it which is also officially documented in the composer's website.

```plaintext
HASH=`curl -sS https://composer.github.io/installer.sig`
php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
```

After I've been sure that it's valid file, I run following command to install it globally so every user in the system can use it, not only **root.**

```plaintext
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
```

Installation done, and I just check if it's really works with my normal user by running following command. Of course I had to open a new terminal otherwise it doesn't work :)

```plaintext
composer --version
```

## Install Nginx

I really like the simplicity and event-driven architecture of Nginx so, I prefer it over Apache to run my PHP projects.

Event-driven architecture makes it much performant reverse-proxy than Apache and you can feel the advantages of it on big projects.

I run following command to install it on my machine.

```plaintext
sudo apt install nginx
```

After installation completed I run following commands to make sure it's running.

Also following **enable** command make it as systemd program so whenever computer is restarted nginx automatically starts to run.

```plaintext
sudo systemctl start nginx
sudo systemctl enable nginx # enables it to run as default program
```

## Install MySQL

MySQL is always my go to database whenever I start new project however nowadays I am thinking to go with SQLite as a first-hand database.

But, I'll be think about that on other projects :)

To install MySQL I run following command.

```plaintext
sudo apt install mysql-server
```

After it's installed I needed to put a password for my **root** user in database, so I run following command to do that.

It asks many easy to followup questions and I fill them up according to my setup however you can select the ones most fits you.

```plaintext
sudo mysql_secure_installation
```

Sometimes that doesn't work enough, and I always try to change password after I connect to database as a **root** Linux user, so I run following command to connect it.

```plaintext
sudo mysql
```

After I connected to the MySQL database via terminal, I run following commands to change the **root** user password.

```plaintext
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'my_lovely_password';
FLUSH PRIVILEGES;
```

At this point, MySQL is running and I changed the password of **root** user for database so I could go to next step to install **NodeJS** which I'll be use alongside PHP.

## Install NodeJS

It's actually becomes so much easier to install NodeJS than 2-3 years ago. So, I just run following commands to install it.

This commands are in the official documentation of NodeJS, so you can read about them at following link;

[https://nodejs.org/en/download/package-manager](https://nodejs.org/en/download/package-manager)

```plaintext
# installs nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# download and install Node.js (you may need to restart the terminal)
nvm install 20

# verifies the right Node.js version is in the environment
node -v # should print `v20.15.1`

# verifies the right npm version is in the environment
npm -v # should print `10.7.0`
```

At this point in my Linux environment I've had NodeJS + NPM running but I decided to try something else instead of **npm** because I've seen that packages that I install with **npm** really takes a lot of size on my disk.

So, I found that **pnpm** works a little bit different than **npm**, which essentially installs all **packages** into the storage but if another project requires the same package then it doesn't install it again, instead uses **symbolic link** to run it through project.

So, I installed globally with following command.

```plaintext
npm install -g pnpm
```

And from now on, I started to use **pnpm install** command instead of **npm install** and I am really happy with that :)

I almost completed all setup, except **git client** which is very important for me because I really like to use **GitHub** and **GitLab** to keep different versions of my projects by creating different branches, making pull requests, writing good comments and pushing to my production server via single line of command **git pull**

So, I needed to install **git**.

## Install Git Client

It's actually very straight forward to install **git** on Linux, I just had to run following command to install **client**.

```plaintext
sudo apt install git
```

Then I setup my **global** git user information with following commands.

```plaintext
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
```

After that point, I just needed one more thing to install **PHP-FPM**.

I need to install it because Nginx requires PHP-FPM to load configuration files for the PHP projects.

## Install PHP-FPM

I just run following command to install it.

```plaintext
sudo systemctl restart php8.3-fpm
```

That installed PHP-FPM for PHP8.3 however if you have different version of PHP on your computer you needed to install right version.

And finally I completed my setup :)

## Follow Me :)

You can follow me on X/Twitter at; [https://x.com/codewitholgun](https://x.com/codewitholgun)

#### Domains

I have some domains that I don't use anymore and want to sell them. You can find the domains list in following link.

[List Here](https://dan.com/domain-seller/domain-seller-799eece2-55fa-4ba5-8d70-7ff99c8d2e5c?&results=50&order_by=relevance)  
  
You can reach out me If you interested with one.
