Alright, I know the title is a bit cliche đ but you're about to find out why!
I've been a Laravel Developer for 3 years now, I've built some projects to test my skills during these times but lately I have this need to showcase other people what I've been up to and also have some projects on My Portfolio. Since these projects may get updates regularly and I definately do not want to always re-upload to my Namecheap Server every single time I make a change, I found a way to make Laravel Deployment to Namecheap work as seamlessly as VueJs to Vercel.
You may ask why I chose Namecheap and not other Hosting providers like Hostinger or Server Managemment tools like Laravel Forge and Plio.io that already have this functionality baked in, well, simple answer, "I'm broke đ„Č", and I do what broke people do, find the cheapest alternative. Enough about me, let's dive in!
Step One - Set Up Git On Namecheap Server.
In order for this post not to get too long, i'll assume you already:
- Registered a Namecheap Account.
- Bought a Hosting Account (I use shared hosting).
- Have a domain setup on the hosting account, you can follow (this guide), if you have an existing hosting server, you can check out this guide to add a domain as an addon to a server.
- Have a Github Account.
- Have a Laravel Project you want to host.
With all these set up, we're good to go.
Log into your Namecheap Hosting Server and visit the "Terminal" tab.
You can also search for it.
If for some reason you do not have the Terminal Tab, go to the Manage Shell Tab and make sure the enable ssh access is toggled on.
Haven done that, you can now visit the terminal tab.
Git is already installed on all Namecheap Hosting Servers but to confirm you can run this command.
git --version
Make sure your Git version is at least 2.28 before proceeding. Update Git if it isn't.
Now it's time link your Github account to your Namecheap Server. You should first set up your local profile.
git config --global user.name "Your Name"
git config --global user.email "yourname@example.com"
replace with your name and the email address you use for Github
If you use private GitHub email address, the second command will look something like this:
git config --global user.email "123456789+franklin@users.noreply.github.com" # Remember to use your own private GitHub email here.
GitHub recently changed the default branch on new repositories from master to main. Change the default branch for Git using this command:
git config --global init.defaultBranch main
To enable colorful output with git, type
git config --global color.ui auto
Youâll also likely want to set your default branch reconciliation behavior to merging.
git config --global pull.rebase false
To verify that things are working properly, enter these commands and verify whether the output matches your name and email address.
git config --get user.name
git config --get user.email
Create an SSH Key
An SSH key is a cryptographically secure identifier. Itâs like a really long password used to identify your machine. GitHub uses SSH keys to allow you to upload to your repository without having to type in your username and password every time.
First, we need to see if you have an Ed25519 algorithm SSH key already installed. Type this into the terminal and check the output with the information below:
ls ~/.ssh/id_ed25519.pub
If a message appears in the console containing the text âNo such file or directoryâ, then you do not yet have an Ed25519 SSH key, and you will need to create one. If no such message has appeared in the console output, you can skip the next step.
To create a new SSH key, run the following command inside your terminal.
ssh-keygen -t ed25519
- When it prompts you for a location to save the generated key, just push
Enter
. - Next, it will ask you for a password; enter one if you wish, but itâs not required.
Link your SSH key with GitHub
Now, you need to tell GitHub what your SSH key is so that you can push your code without typing in a password every time.
First, youâll navigate to where GitHub receives our SSH key. Log into GitHub and click on your profile picture in the top right corner. Then, click on Settings
in the drop-down menu.
Next, on the left-hand side, click SSH and GPG keys
. Then, click the green button in the top right corner that says New SSH Key
. Name your key something that is descriptive enough for you to remember what device this SSH key came from, for example Namecheap Server
. Leave this window open while you do the next steps.
Now you need to copy your public SSH key. To do this, weâre going to use a command called cat
to read the file to the console. (Note that the .pub
file extension is important in this case.)
cat ~/.ssh/id_ed25519.pub
Highlight and copy the entire output from the command. If you followed the instructions above, the output will likely begin with ssh-ed25519
and end with your username@hostname
.
Now, go back to GitHub in your browser window and paste the key you copied into the key field. Keep the key type as Authentication Key
and then, click Add SSH key
. Youâre done! Youâve successfully added your SSH key!
Testing you key
Follow the GitHub directions for testing your SSH connection. Make sure the fingerprint output in the terminal matches one of the four GitHubâs public fingerprints. (Donât forget to omit the $
when you copy and paste the code!).
You should see this response in your terminal: Hi username! Youâve successfully authenticated, but GitHub does not provide shell access. Donât let GitHubâs lack of providing shell access trouble you. If you see this message, youâve successfully added your SSH key and you can move on. If the output doesnât correctly match up, then try going through these steps again.
Step Two - Clone Laravel Project To Your Namecheap Server.
Search for "SSH Access" on your cPanel and click on the first result. Click on Manage SSH Keys
.
Find the SSH key you just generated (it should the only one for you, or last one), click and manage
, and Authorize
.
Now, search for Git version control
and open the first option. Click on Create
.
Set the clone Repo URL and set the Repository Path (directory to clone your Github Repo).
Set the Repository Name and click create.
Remember that the directory you are cloning to must be empty, else you would get an error.
If everything goes well you should have something like this:
Now you can easily go to your terminal, cd
into your project directory and run composer install
and all those other Laravel commands but where's the fun in that đ
Final Step - Set Up Deploy On Push.
This is the topping on the ice, for this we'll use Github Webhooks and good ole' .htaccess
file. Let's see how.
Laravel has a thing where it use the public directory as the root directory, this way, sensitive files and directory are secured, database management tools like Laravel Forge does this for you automatically but we'll have to it ourselves.
To get your project up and ready, you should create a
.env
file on the root of your project directory and setup Application Key and every other thing you would normally do in a typical Laravel app.
Now, you should create a .htaccess
file on the root directory. Then paste the following code:
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Ensure Authorization header is passed to PHP
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect to the public folder
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ /public/$1 [L]
</IfModule>
# Deny access to .env file
<Files .env>
Order allow,deny
Deny from all
</Files>
# Deny access to composer.json and composer.lock
<FilesMatch "^composer\.(json|lock)$">
Order allow,deny
Deny from all
</FilesMatch>
# Deny access to artisan
<Files artisan>
Order allow,deny
Deny from all
</Files>
# Deny access to anything starting with a dot
<Files ~ "^\.">
Order allow,deny
Deny from all
</Files>
# Prevent directory listing
Options -Indexes
This piece of code sets the public directory as the root directory and enables other security checks.
The next thing we want is a public route that is accessible to the internet, however we do not want everyone to have access to this file, rather we want only the Github IP to access it, since we will be receiving events from there. We can also use a .htaccess
file for this.
Go to the public
directory, create a file to store our deployment script, I would call mine deployment.php
.
Open the file and paste the following code:
<?php
// Your secret key for verification
$secret = 'webhook password'; // you will use this when creating a webhook
// Get the payload from GitHub
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE'];
// Verify the payload signature
list($algo, $hash) = explode('=', $signature, 2);
if ($hash !== hash_hmac($algo, $payload, $secret)) {
header('HTTP/1.1 403 Forbidden');
exit;
}
// Define the project root directory
$projectRoot = '/home/servername/projectdirectory';
// Pull the latest changes from the repository
$output = shell_exec("cd $projectRoot && git pull 2>&1");
echo "<pre>Git Pull Output:\n$output</pre>";
// Run composer install
$output = shell_exec("cd $projectRoot && composer install --no-interaction --prefer-dist --optimize-autoloader 2>&1");
echo "<pre>Composer Install Output:\n$output</pre>";
// Run artisan commands
$output = shell_exec("cd $projectRoot && php artisan optimize:clear 2>&1");
echo "<pre>Artisan Output:\n$output</pre>";
$output = shell_exec("cd $projectRoot && php artisan optimize 2>&1");
echo "<pre>Artisan Output:\n$output</pre>";
$output = shell_exec("cd $projectRoot && php artisan migrate 2>&1");
echo "<pre>Artisan Output:\n$output</pre>";
$output = shell_exec("cd $projectRoot && php artisan storage:link 2>&1");
echo "<pre>Artisan Output:\n$output</pre>";
?>
You can edit the artisan commands to meet your personal needs.
The last thing we need to do before moving over to Github is to protect the deployment.php
file.
There is a .htaccess
file on the public directory, it comes with all Laravel installation. That's where we would do that. Open the file and add the following code:
<Files "deployment.php">
Order allow,deny
Deny from all
Allow from 192.30.252.0/22
Allow from 185.199.108.0/22
Allow from 140.82.112.0/20
</Files>
So the whole file content should look like this:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
<Files "deployment.php">
Order allow,deny
Deny from all
Allow from 192.30.252.0/22
Allow from 185.199.108.0/22
Allow from 140.82.112.0/20
</Files>
Set up Github Webhook
Log into your Github account and open your project repository. Go to Settings
and click on Webhooks
, located on the left side panel, press Add New.
Provide all required informations and proceed to add webhook. The payload type should be application/json and the webhook url should be a link to the deployment script on your server. Here's mine:
That's all! đ„ł
Now, whenever you push to your Github Repository, the code automatically deploys to the server.
If you did everything correctly, the webhook will look like this on your next push.
If you have any issues or questions you can comment below and I'll try to help as best as I can.
You can support by following me on X (formally Twitter). Thank you.
Happy Coding!
Top comments (0)