AWS (amazon web services) lets developer to setup virtual environment with operating system, programming language, web application platform, datatabase and other necessary services so that application can be scaled, securely maintained and reliable.
In this step by step tutorial, we will setup an aws virtual environment with amazon ec2 instance and deploy our laravel application. Aws account is needed for this which is easy to create with minimal fee for a year. After that this free tier will expire and billing is going to occur on any aws resource usage.
Since this is a long post it is divided into 7 sections with steps mentioned for each of those as follows
1. Step 01 to 12 Setting Up our EC2 Instance
2. Step 13 to 16 Introduction to ssh with Putty
3. Step 18 to 19 Setting up nginx
4. Step 20 to 25 Setting up PHP
5. Step 26 to 31 Setting up amazon RDS instance
6. Step 32 to 36 Setting Up MySQL Database with MySQL Commands
7. Step 37 to 43 Setting Up Laravel Project in EC2 with FileZilla
8. Step 44 to 51 Setting up Laravel Project in EC2 with git
Now, let's dive in our post.
Step 01: After aws account creation and billing setup we can go to top menu search box beside services and type ec2 to see the link to go into it like below

Step 02: Now after clicking that we come to ec2 dashboard. There are various options but we will focus on creating instance. To do that, we need to click the orange button "launch Instance" inside launch instance box.


Step 04: Then we need to select operating system and we will be choosing ubuntu 22.04 LTS for our purpose.

Step 05: Next we are choosing free tier instance type t2.micro with 1 vcpu and 1 gb ram.

Step 06: Then we come to "Key pair" section. It is necessary later to access our instance with ssh command prompt. So, if we click to create key we will be prompted to popup. We need to give key pair name, type and also format. We will be choosing ppk file for format so that later we can use putty ( ssh client ) to access our instance from our computer.


Step 08: Next for storage we are keeping 8gb ( free tier )

Step 09: Now we can confirm instance setup in the right and click on the orange button again to launch instance. We can ignore advanced details section for the moment.

Step 10: Now after some time instance will be created


Step 11: Aws will give us public IP so that we can use that along with ppk file ( which we downloaded in step 6 during key pair creation ) to log into our ssh instance with putty. We need to go to ec2 list page to get the ip.
Step 12: Now we need to use putty to access the instance using ssh in port 22. Putty is a free ssh client which can be downloaded and installed (for windows).
Step 13: After installation we need to add IP address under "HOST NAME or IP address" box in putty home screen. After that we need to click on Auth->Credential screen under SSH tree in the left panel. here we need pick and choose the ppk file that we got earlier.


Step 14: Now, we will be prompted to accept ssh access then we just need to click it.
Step 15: Now inside ssh client we will be prompted in command line to provide login username. Here we need to input "ubuntu" and press enter.

Step 16: Then after authenticating with private ppk file and showing some startup messages inside command prompt cursor will come up. It means we have successfully entered into ec2 instance with ssh access. From now on we can play with linux commands to get our desired output.

Step 17: Now we need to prepare our ubuntu server with linux commands first by changing the user privileges to root and then updating the server.
sudo su - apt-get update && apt-get upgradeAfter root privileges username in command prompt will turn into root@private-ip-of-instance from ubuntu@private-ip-of-instance. With update command required packages will be downloaded and installed by the apt ( advanced packaging tool ) manager. If sometime prompted with yes or no option will need to be clicked on yes to keep the update process going.
Then service restart prompt will come up. Need to keep the installation process going by pressing tab and space button. Then after some time latest updates installation process will finish in no time.
Step 18: It is time now to setup web server and we will use nginx. To install it and check it if server is running we need to use following commands
apt-get install nginx systemctl status nginx

Step 19: Now after installation we can check the server using public IP provided by aws EC2 with http protocol port like http://<our-public-ec2-ip>. Then we will see happy message "Welcome to nginx!" .
We have not activated service for https port. So, secure server access will not work.

Note: nginx configuration file is located at /etc/nginx/sites-enabled/default and we can see inside of that file like below command.
nano /etc/nginx/sites-enabled/default Step 20: Now time to install php and composer with following command apt-get install --no-install-recommends php8.1 php8.1-{bcmath,cli,common,curl,fpm,gd,mbstring,mysql,xml,zip} openssl composer
Above, --no-install-recommends flag means we do not want other recommeneded packages other than mentioned ones. Step 21: After installation process completed we can check php and composer version with command.
php -v composer --version php -i | grep enabled // Also to check enabled php modules
Step 22: Now we can check php is working under nginx default /var/www/html directory
nano php-ver.php -> <?php phpinfo() ?>Then inside /etc/nginx/sites-enabled/default -> after location / {...} we need to put following code to add PHP FPM to execute php code for nginx to return proper response
location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; }
Step 23: To check if nginx config file is fine we can use command below
nginx -t
Step 24: To make this change in effect we need to restart the nginx server
systemctl restart nginx
Step 25: Now if we go to our public ip http://<our-public-ec2-ip>/php-ver.php we see php info page is showing correctly. 
Step 26: Now we move to creating database for our application. For this we will use RDS of aws. This can be browsed like below.

Step 27: Here we need to click on orange button "Create Database"

Step 28: Now we need to setup configuration of rds database like screenshots below






Step 29: One thing to keep in mind we need to select Connect to an EC2 compute resource under connectivity box so that our db gets created in our private instance we created earlier.

So, after everything setup we can press create database. In option of password we have checked the auto generate password which will be created after database installation is complete. We need to save that access for later use.

Step 30: Now, database creation process will get started and it will take some time.

Step 31: After database successfully created and running we need to take endpoint value from database detail page

Step 32: Now we need to install mysql client in our previously created instance. So inside putty we need to provide following command
apt-get install mysql-client
Step 33: After this in order to connect to mysql instance we need to execute following command
mysql -h <database-endpoint> -u admin -p
Step 34: After executing that we need to input our previously copied password. Then we will be prompted into mysql instance
Step 35: Now we can use mysql commands here. So, they are listed below with their corresponding effect
// to create database
CREATE DATABASE lara_rds_aws;
// to delete database DROP DATABASE lara_rds_aws;
// to list all databases SHOW DATABASES;
// to select current working database USE lara_rds_aws;
// to create table with field id and type int CREATE TABLE users (id int);
// to check list of tables in database SHOW TABLES;
// to delete table DROP TABLE users;
// to create a new dbuser with preferred password CREATE USER '<our_preferred_username>'@'%' IDENTIFIED BY '<our_preferred_password>';
// to list all users in database SELECT user FROM mysql.user;
// to check permission for a user SHOW GRANTS for lara_user;
// to grant all access on database for a user GRANT ALL PRIVILEGES ON lara_rds_aws.* TO '<our_preferred_username>'@'%';
// to force update privileges without restarting the server FLUSH PRIVILEGES;
Step 36: since we have created a user we can login with that now with created password
mysql -u <our-preferred-user> -p -h <rds-endpoint>
As we have prepared our ec2 instance with nginx, php, mysql and so on. Now, It is time to install the Laravel project itself step by step.
Step 37: We need to create different project folder "laravelproject" under /var/www/html directory like below.
cd /var/www/html mkdir laravelproject
Step 38: Now we can change default user and group "www-data" to "larauser" for php fpm pool so that services can be used by other user than default system user "www-data". It can be achieved like below.
// adding larauser
adduser larauser
// assigning larauser under group www-data
usermod -aG www-data larauser
// to check which group laravel user belongs to. It needs to belong under 'www-data' group groups larauser
// in order to change user and group to larauser
// instead of default www-data
// that is used by php fpm pool to process php pages under www section nano /etc/php/8.1/fpm/pool.d/www.conf user = larauser group = larauser
// restarting php-fpm systemctl restart php8.1-fpm
Now our server is ready for using Laravel project.
Step 39: One last thing we would need is setting up nginx configuration for Laravel project like below
with command line nano /etc/nginx/sites-enabled/default
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html/laravelproject/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; server_name _; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
// after saving and existing editor we need to execute following command in terminal systemctl restart nginx
Now, in this part of tutorial, we will use filezilla to upload the both database and local copy of laravel project to "laravelproject" folder so that it can be used with putty client ssh.
For filezilla connection we need to use ec2 hostname as IP, user ubuntu and ppk file as ssh key which we created earlier during ec2 instance creation.
Step 40: Now if we have local copy of database we need to import that to amazon rds that we setup earlier with database name lara_rds_aws again with command line
mysql -h <rds-endpoint> -u <preferred-username> -p <created-rds-database> < <local-database>.sql
Above we have used mysql command to import our desired database to amazon rds database having created rds database endpoint, hostname, rds database username and password previously.
We need to be in root or sudo level account to be able use this command. In case mysql does not work that means mysql server needs to be installed. It can be done with apt install mysql-server
Step 41: To proceed with laravelproject setup, we are going to need the "laravelproject" folder to be writable so that we can upload any file to this folder. Following command can achieve that.
chmod -R 777 laravelprojectStep 42: Now after making archive of one of our Laravel local project we can upload it using filezilla again into our "laravelproject" folder. After uploading we need to unzip the folder and we zip unzip package for this. We can install this package and later unzip the project archive like below.
apt install zip unzip unzip foldername.zip
Step 43: Now as database is imported and project archive is unzipped inside "laravelproject" folder of amazon instance we can focus on configuring Laravel project. So, with nano .env we need to change project database config like below
DB_HOST=<rds-endpoint> DB_PORT=3306 DB_DATABASE=<preferred-database> DB_USERNAME=<preferred-username> DB_PASSWORD=<preferred-password>
In some cases, we might need to change APP_URL also inside of .env file. It can be done like below
APP_URL=<our-ec2-public-ip>
Here we go, after all these steps, now if we refresh the browser on the given public IP of amazon instance we will be able to see our project running.
Another way we can setup our laravel project to ec2 instance is with the use of git. In this part of tutorial we will do that like below.
Step 44: Cloning a git project in the "laravelproject" directory
git clone https://github.com/mahfoman/laravel-vue3-movie-listing-crud.git .
Step 45: Inside laravelproject folder creating .env file from example one
// to create .env file from existing sample one cp .env.example .env
Step 46: Installing dependency packages with composer
//to install laravel dependency packages composer install
Step 47: Generating new artisan key for the project
// to generate a new key for the project php artisan key:generate
Step 48: We are also going to need the "storage" folder to be writable so that laravel can create and save necessary cache related files in this folder. Following command can achieve that.
chmod -R 777 storage
Now the git repo we are cloning requires npm to install JS dependencies. So we need to install nvm and nodejs first to get suitable version of npm compatible vite which is a asset bundling tool for laravel.
Step 49: We can setup nvm, nodejs mentioned above like below
//To install or update nvm, we need to run the install script curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash // configuring nvm in bash shell source ~/.bashrc //installing latest nodejs with nvm nvm install node // installing js dependencies with npm npm install //asset bundling in vite with npm for production site npm run build
Step 50: Like step 43, Now instead of imported database we will use laravel schema migration attached inside the git repo that we cloned. So, with nano .env we need to change project database config like it is already mentioned in that step.
Step 51: Now last step would be running artisan migrate command (attached inside cloned git repo) to seed some dummy data like below.
php artisan migrate:fresh --seed
Here we go again, with git cloning, composer, npm installing and data seeding if refresh the browser on the given public IP of amazon instance we will be able to see our project running.
That's it, now we can pat on our back as by following this long post above we are able to successfully setup our Laravel project into amazon instance with database association.