Deploy Quasar + Laravel + MySQL on AWS EC2 (Default VPC)

AWS EC2 Laravel Quasar / Vue.js MySQL

A complete, step-by-step guide to deploying a full-stack application — Quasar (Vue.js) frontend, Laravel API backend, and MySQL database — on a single EC2 instance using the default VPC.

ARCHITECTURE OVERVIEW
Quasar SPA
:80 /
Nginx
reverse proxy
Laravel API
:8000 /api
MySQL 8
:3306

All running on a single EC2 instance (Ubuntu 22.04) inside the default VPC


STEP 01

Prerequisites

Before starting, make sure you have:

  • An AWS account with access to the EC2 dashboard
  • A domain name pointed to your server (optional, but needed for SSL)
  • Your Quasar + Laravel project pushed to a Git repository
  • A local SSH key pair
ℹ️ This guide assumes a single-server deployment. For production at scale, consider separating the database (RDS) and using S3 + CloudFront for the frontend.

STEP 02

Launch EC2 Instance

2.1 Choose Your Instance

Go to EC2 DashboardLaunch Instance:

  • AMI: Ubuntu Server 22.04 LTS (HVM)
  • Instance type: t2.small or t3.medium
  • Key pair: Create or select existing
  • VPC: Default VPC

2.2 Security Group Rules

TypePortSourcePurpose
SSH22Your IPServer access
HTTP800.0.0.0/0Web traffic
HTTPS4430.0.0.0/0Secure traffic

2.3 Connect to Your Instance

# Set permissions on your key
chmod 400 your-key.pem

# SSH into the instance
ssh -i "your-key.pem" ubuntu@<your-ec2-public-ip>

STEP 03

Install Dependencies

# Update system packages
sudo apt update && sudo apt upgrade -y

# Install Nginx, Git, Curl, Unzip
sudo apt install -y nginx git curl unzip software-properties-common

# Add PHP 8.2 repository
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

# Install PHP 8.2 + extensions for Laravel
sudo apt install -y php8.2-fpm php8.2-mysql php8.2-mbstring \
  php8.2-xml php8.2-curl php8.2-zip php8.2-bcmath php8.2-gd

# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Install Node.js 20 (for building Quasar)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y nodejs
✅ Verify installations: php -v, composer --version, node -v, nginx -v

STEP 04

Set Up MySQL

# Install MySQL 8
sudo apt install -y mysql-server

# Secure the installation
sudo mysql_secure_installation

# Create database and user
sudo mysql

CREATE DATABASE myapp_db;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
⚠️ Replace StrongPassword123! with an actual secure password. Never use this in production!

STEP 05

Deploy Laravel Backend

# Clone your project
cd /var/www
sudo git clone https://github.com/you/your-project.git myapp
cd myapp/backend

# Set ownership
sudo chown -R www-data:www-data /var/www/myapp
sudo chmod -R 775 storage bootstrap/cache

# Install dependencies
composer install --no-dev --optimize-autoloader

# Configure environment
cp .env.example .env
nano .env

5.1 Configure .env

APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp_db
DB_USERNAME=myapp_user
DB_PASSWORD=StrongPassword123!
# Generate app key and run migrations
php artisan key:generate
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache

STEP 06

Deploy Quasar Frontend

# Navigate to frontend directory
cd /var/www/myapp/frontend

# Install dependencies
npm install

# Build for production (SPA mode)
npx quasar build

# Build output → dist/spa/
# Nginx will serve this
💡 Make sure your Quasar app's API base URL points to /api (relative) so Nginx can proxy it to Laravel.

STEP 07

Configure Nginx

This is the crucial part — Nginx serves the Quasar SPA and proxies API requests to Laravel via PHP-FPM:

server {
    listen 80;
    server_name yourdomain.com;

    # Quasar SPA (frontend)
    root /var/www/myapp/frontend/dist/spa;
    index index.html;

    # SPA fallback
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Laravel API
    location /api {
        alias /var/www/myapp/backend/public;
        try_files $uri $uri/ @laravel;

        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
        }
    }

    location @laravel {
        rewrite /api/(.*)$ /api/index.php?/$1 last;
    }

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
}
# Enable the site
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/

# Remove default site
sudo rm /etc/nginx/sites-enabled/default

# Test config and reload
sudo nginx -t
sudo systemctl reload nginx

STEP 08

SSL with Let's Encrypt

# Install Certbot
sudo apt install -y certbot python3-certbot-nginx

# Get SSL certificate
sudo certbot --nginx -d yourdomain.com

# Test auto-renewal
sudo certbot renew --dry-run

STEP 09

Troubleshooting

500 Internal Server Error

Check Laravel logs: tail -f storage/logs/laravel.log — usually missing .env, wrong permissions, or missing PHP extensions.

403 Forbidden

Fix ownership: sudo chown -R www-data:www-data /var/www/myapp

API returns 404

Check Nginx config — make sure the /api location block is correct and nginx -t passes.

Quasar routes show blank page

Ensure try_files falls back to /index.html for SPA routing.

Database connection refused

Verify MySQL: sudo systemctl status mysql. Check .env credentials match Step 4.

🚀 You're live! Visit your EC2 public IP or domain. Quasar frontend loads, API calls to /api/* hit Laravel.

Found this helpful?

Follow me for more DevOps and cloud engineering guides.

Comments

Popular posts from this blog

Nginx Load Balancing Lab on AWS EC2

EC2 Fundamentals