Today I'll be covering how to host a Laravel app on AWS EC2. I'll cover everything from creating the EC2 instance, configuring the server, connecting to MySQL and more. I'll be assuming that you already have an AWS account, and that you already have a Laravel app that you'd like to host. If you don't, and would still like to follow along, you can clone my project's source code on my GitHub.
First things first, we need to create our EC2 instance. Go to the EC2 section of AWS, and press 'Launch instances'. You should now be on a page that looks similar to below.
Name the instance something relevant to your application, or however you'd like.
For Application Image, select Ubuntu 22.04 (64-bit x86).
We'll choose t2.micro to remain within the free tier.
Create a key pair and store it in an easily accessible location.
Create a new security group and allow SSH and HTTP from the internet.
The settings for storage and Advanced details can be left blank. Double-check your configuration and then press 'Launch instance'.
Now, to connect to your instance, return the the 'Instances' page of the EC2 section and find the instance you just created. Select it and press 'Connect'.
Select 'EC2 Instance Connect' and leave the username as the default, press 'Connect'.
You should now be connected, and see a page like this.
Now we're ready to start installing some stuff. Paste the commands below into your terminal, in order. They should all work, as long as you've selected Ubuntu as your AMI. You can copy the command, and then right-click to paste into the AWS Instance Connect terminal.
Install Nginx
sudo apt update
sudo apt install nginx
systemctl status nginx (If you see 'active (running)', it's working correctly)
sudo systemctl restart nginx
sudo nginx -t
Install PHP
sudo apt update
sudo apt install --no-install-recommends php8.1
sudo apt-get install php8.1-cli php8.1-common php8.1-mysql php8.1-zip php8.1-gd php8.1-mbstring php8.1-curl php8.1-xml php8.1-bcmath php8.1-fpm
Install Composer
- curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
- HASH=`curl -sS https://composer.github.io/installer.sig`
echo $HASH
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
composer
Install MySQL
sudo apt update
sudo apt install mysql-server
sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your password';
Make sure to change 'your password' to your actual password, and save it securely. We'll need it later on.
You can type \q or exit to quit mysql mode.
sudo systemctl restart nginx
sudo systemctl restart php8.1-fpm
Set Permissions for the web server directory
sudo mkdir -p /var/www/html/
sudo chown -R ubuntu:ubuntu /var/www/
Okay! Now we're ready to clone our project onto our server. Let's do so in the home directory by using:
cd ~
sudo git clone https://github.com/kevindarbydev/LaravelBlog.git
or clone the repo for the project you had in mind
From now on I will reference the project folder by 'YourAppName'. Replace YourAppName with the name of your folder.
sudo mv YourAppName /var/www/YourAppName
cd /var/www/
dir
You should now see this (Calling 'dir' in the var/www/ directory should return your project folder):
Now we need to set permissions for some laravel-specific folders(cache + storage).
sudo chown -R www-data.www-data /var/www/YourAppName/storage
sudo chown -R www-data.www-data /var/www/YourAppName/bootstrap/cache
sudo chmod -R ugo+rw /var/www/YourAppName/storage/logs
adds read/write permissions for the owner, group, and others to all files and directories within the storage/logs directory
- mkdir -p /var/www/YourAppName/storage/framework/{sessions,views,cache}
creates three directories (sessions, views, and cache) inside the framework directory
- sudo chmod -R ugo+rw /var/www/YourAppName/storage/framework
adds read/write permissions for the owner, group, and others to all files and directories within the storage/framework
Server Configuration
Now our project files are ready to go. We just need to configure a Nginx server block to serve our files. We'll create a config file in the etc/nginx/sites-available
directory.
Remember to change 'YourAppName' where appropriate.
- sudo nano /etc/nginx/sites-available/YourAppName
Paste the following into the nano interface. server_domain_or_IP
can be replaced by the public IPv4 address of your EC2 instance. This can easily be found on the Instance summary in AWS.
server {
listen 80;
server_name server_domain_or_IP;
root /var/www/YourAppName/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
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_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Once you've pasted it, you can do Ctrl+S to save, and then Ctrl+X to exit.
Now to activate our configuration, simply run this command:
- sudo ln -s /etc/nginx/sites-available/YourAppName /etc/nginx/sites-enabled/
While we're at it, let's remove the default configuration:
- sudo rm -f /etc/nginx/sites-enabled/default
You can double check everything is working and ready to go with:
- sudo nginx -t
Apply changes:
- sudo systemctl reload nginx
Visit your project directory on the server and run:
sudo cp .env.example .env
sudo nano .env
Here you can fine tune any required settings for your app. If you've cloned LaravelBlogApp, you'll need to generate an app key:
composer update
php artisan key:generate
If you get an error about permissions, try this command:
- sudo chown -R ubuntu:ubuntu /var/www/YourAppName
Connect to MySQL
sudo mysql -u root -p
CREATE DATABASE your_db_name;
After creating the database, we'll need to update our .env
.
- sudo nano /var/www/YourAppName/.env
Replace DB_DATABASE
with the name you entered and replace DB_PASSWORD
with the password you used when installing MySQL. Afterwards, run these commands:
- php artisan migrate
php artisan db:seed
sudo service nginx restart
Visit the public IP of your instance:
http://YOUR_IP
Make sure it's http, as some browsers will default to https.
Afterwards, if everything went well, your app should be up and running!
Here are some resources I referred to often while writing this article. Hopefully they can help you too if you get stuck.
Digital Ocean - https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-laravel-with-lemp-on-ubuntu-18-04
Deploying Laravel to AWS - https://www.linkedin.com/pulse/organized-steps-deploy-laravel-app-ec2-instance-2204-selvanantham/
Top comments (0)