How to Deploy a Laravel Application on AWS: EC2 - Ubuntu, S3, Nginx, PHP, MySQL, Adminer, Composer, and SSL

How to Deploy a Laravel Application on AWS: EC2 - Ubuntu, S3, Nginx, PHP, MySQL, Adminer, Composer, and SSL

This guide covers all the necessary steps to set up a Laravel application on an AWS EC2 instance, using Nginx, MySQL, and S3 for file storage. We’ll also install Adminer for database management, Composer for dependency management, and Certbot for SSL certificates. This guide assumes you're familiar with basic Linux commands and have an AWS account.


Step 1: Setting Up AWS EC2 Instance

1.1 Create an EC2 Instance

  1. Sign in to the AWS Management Console and navigate to the EC2 dashboard.

  2. Launch a new instance:

    • Select Ubuntu Server 22.04 LTS (or the latest Ubuntu version) for the AMI (Amazon Machine Image).

    • Choose the t2.micro instance type (if using the free tier).

    • Configure the instance details:

      • Ensure Auto-assign Public IP is enabled.
    • Add storage (20 GB recommended).

    • Configure security group:

      • Add rules for SSH (port 22), HTTP (port 80), and HTTPS (port 443).
    • Launch the instance and download the .pem key file for SSH access.

1.2 Connecting to Your EC2 Instance

  1. Open your terminal (or use PuTTY for Windows) and run the following command:

     ssh -i "path/to/your_key.pem" ubuntu@your_public_ip
    
  2. You should now be connected to your EC2 instance.


Step 2: Setting Up Route 53 for Domain DNS

  1. Open AWS Route 53 and create a new hosted zone for your domain.

  2. Copy the nameservers (NS records) provided and update the nameserver settings with your domain registrar (e.g., GoDaddy, Namecheap).

  3. Create an A Record to map your domain to the public IP of the EC2 instance:

    • Set the record type to A (IPv4 address).

    • Enter the public IP address of your EC2 instance.


Step 3: Setting Up the Ubuntu Server

3.1 Update the System

Before installing any software, ensure your system is up to date:

sudo apt update && sudo apt upgrade -y

Step 4: Installing Nginx

  1. Install Nginx:

     sudo apt install nginx -y
    
  2. Enable and start Nginx:

     sudo systemctl enable nginx
     sudo systemctl start nginx
    
  3. Check the Nginx status to ensure it's running:

     sudo systemctl status nginx
    

Step 5: Installing PHP (Latest Version)

To run Laravel, we need PHP and its required extensions.

  1. Install necessary PHP packages:

     sudo apt install software-properties-common ca-certificates lsb-release apt-transport-https curl git -y
     sudo add-apt-repository ppa:ondrej/php
     sudo apt update
     sudo apt install php8.1 php8.1-fpm php8.1-mysql php8.1-xml php8.1-mbstring php8.1-curl -y
    
  2. Check the PHP version:

     php -v
    

Step 6: Installing MySQL

  1. Install MySQL server and client:

     sudo apt install mysql-server mysql-client -y
    
  2. Run the MySQL secure installation script:

     sudo mysql_secure_installation
    
  3. Create a new MySQL database and user for your Laravel application:

     sudo mysql -u root -p
    

    Inside the MySQL prompt:

     CREATE DATABASE laravel_db;
     CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'your_password';
     GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
     FLUSH PRIVILEGES;
     exit;
    

Step 7: Configuring Nginx for Laravel

  1. Remove the default Nginx configuration:

     sudo rm /etc/nginx/sites-enabled/default
    
  2. Create a new Nginx configuration for your Laravel project:

     sudo nano /etc/nginx/sites-available/laravel
    
  3. Add the following configuration:

     server {
         listen 80;
         server_name your_domain.com www.your_domain.com;
    
         root /var/www/laravel/public;
         index index.php index.html index.htm;
    
         location / {
             try_files $uri $uri/ /index.php?$query_string;
         }
    
         location ~ \.php$ {
             include snippets/fastcgi-php.conf;
             fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             include fastcgi_params;
         }
    
         location ~ /\.ht {
             deny all;
         }
     }
    
  4. Enable the new site:

     sudo ln -s /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/
    
  5. Test the configuration and reload Nginx:

     sudo nginx -t
     sudo systemctl reload nginx
    

Step 8: Installing Composer

Composer is necessary for managing Laravel’s dependencies.

  1. Download and install Composer:

     sudo apt install wget php-cli php-zip unzip -y
     wget https://getcomposer.org/installer -O composer-setup.php
     sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
    
  2. Verify the Composer installation:

     composer --version
    

Step 9: Deploying Your Laravel Application

  1. Clone your Laravel application from GitHub or another repository:

     cd /var/www
     sudo git clone https://github.com/your_username/your_laravel_repo.git laravel
    
  2. Set file permissions:

     sudo chown -R www-data:www-data /var/www/laravel
     sudo chmod -R 755 /var/www/laravel
     sudo chmod -R 775 /var/www/laravel/storage /var/www/laravel/bootstrap/cache
    
  3. Install Laravel dependencies:

     cd /var/www/laravel
     composer install
    
  4. Copy the .env file and set up your environment:

     cp .env.example .env
     php artisan key:generate
    
  5. Configure MySQL in .env:

     DB_CONNECTION=mysql
     DB_HOST=127.0.0.1
     DB_PORT=3306
     DB_DATABASE=laravel_db
     DB_USERNAME=laravel_user
     DB_PASSWORD=your_password
    
  6. Run migrations:

     php artisan migrate
    

Step 10: Setting Up Adminer for Database Management

Adminer is a lightweight alternative to phpMyAdmin for managing your MySQL database.

  1. Create a directory for Adminer:

     sudo mkdir /var/www/adminer
    
  2. Download the latest Adminer version:

     sudo wget "https://www.adminer.org/latest.php" -O /var/www/adminer/index.php
    
  3. Create an Nginx configuration for Adminer:

     sudo nano /etc/nginx/sites-available/adminer
    
  4. Add the following configuration:

     server {
         listen 80;
         server_name adminer.your_domain.com;
    
         root /var/www/adminer;
         index index.php;
    
         location / {
             try_files $uri $uri/ =404;
         }
    
         location ~ \.php$ {
             include snippets/fastcgi-php.conf;
             fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             include fastcgi_params;
         }
    
         location ~ /\.ht {
             deny all;
         }
     }
    
  5. Enable the Adminer site:

     sudo ln -s /etc/nginx/sites-available/adminer /etc/nginx/sites-enabled/
     sudo systemctl reload nginx
    
  6. Visit http://adminer.your_domain.com to access Adminer.


Step 11: Setting Up SSL with Let’s Encrypt

  1. Install Certbot and the Nginx plugin:

     sudo apt install certbot python3-certbot-nginx -y
    

2

. Obtain an SSL certificate:

sudo certbot --nginx -d your_domain.com -d www.your_domain.com
  1. Certbot will automatically configure your SSL settings in Nginx.

  2. Verify the SSL certificate renewal process:

     sudo certbot renew --dry-run
    

Step 12: Using Amazon S3 for File Storage

  1. Install the AWS SDK for PHP in your Laravel project:

     composer require aws/aws-sdk-php
    
  2. Set up the S3 disk in your Laravel project’s config/filesystems.php:

     's3' => [
         'driver' => 's3',
         'key' => env('AWS_ACCESS_KEY_ID'),
         'secret' => env('AWS_SECRET_ACCESS_KEY'),
         'region' => env('AWS_DEFAULT_REGION'),
         'bucket' => env('AWS_BUCKET'),
     ],
    
  3. Update your .env file with S3 credentials:

     AWS_ACCESS_KEY_ID=your_access_key
     AWS_SECRET_ACCESS_KEY=your_secret_key
     AWS_DEFAULT_REGION=your_region
     AWS_BUCKET=your_bucket
    

Step 13: Finalizing and Testing

  1. Restart Nginx to apply all changes:

     sudo systemctl restart nginx
    
  2. Test your Laravel application by visiting http://your_domain.com.


Conclusion

By following these steps, you've successfully set up a complete environment for hosting a Laravel application on AWS EC2, with S3 for file storage, Nginx as the web server, MySQL as the database, and SSL for security. Additionally, Adminer and Composer are set up to facilitate database and dependency management.

This robust setup provides a secure, scalable, and efficient platform for deploying Laravel applications in the cloud.