Are you tired of manually uploading your Laravel project to a production server every time you push new updates? In this guide, you'll learn how to automate your Laravel deployment process using GitHub Actions — the DevOps-friendly, CI/CD tool built into GitHub.
Let’s streamline your workflow and deploy your Laravel app to your Hostinger VPS (or any SSH-accessible server) with a single git push.
Laravel GitHub Actions Deploy: Full Auto
Using GitHub Actions allows you to:
- Automate your production deployment after every push.
- Avoid using insecure FTP tools.
- Save time and reduce human error.
- Build a proper CI/CD pipeline as a Laravel developer.
🧠 Prerequisites
Before starting, make sure you have:
- A Laravel project hosted on GitHub.
- A Hostinger VPS or Web Hosting plan with SSH access.
- Access to the terminal/command line.
- Composer installed on your server.
🛠️ Step 1: Generate SSH Key and Upload to Hostinger
- Generate SSH Key on your local machine:
ssh-keygen -t rsa -b 4096 -C "[email protected]"
It will generate two files:
~/.ssh/colorpark_hostinger(private key)~/.ssh/colorpark_hostinger.pub(public key)
- Add the public key to Hostinger:
Go to Hostinger → Advanced → SSH Access → SSH Keys
Click Add SSH Key, paste the public key content from:
cat ~/.ssh/colorpark_hostinger.pub
- Save the private key content to be added as a GitHub Secret later:
cat ~/.ssh/colorpark_hostinger
🔐 Step 2: Add GitHub Secrets
In your GitHub repository:
Go to: Settings → Secrets and variables → Actions → New repository secret
Add the following secrets:
HOSTINGER_SSH_HOST='145.223.89.199' # Your server IP
HOSTINGER_SSH_PORT='65002' # Your SSH port
HOSTINGER_SSH_USER='u597250090' # Your SSH username
HOSTINGER_SSH_KEY='(paste your PRIVATE key content)'
DEPLOY_PATH='/home/u597250090/domains/example.com/public_html'
📁 Step 3: Create GitHub Actions Workflow
Inside your Laravel project, create the following file:
mkdir -p .github/workflows
touch .github/workflows/deploy.yml
Paste the following complete deploy.yml config:
name: 🚀 Deploy to Hostinger
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up SSH key
run: |
mkdir -p ~/.ssh
echo "${ { secrets.HOSTINGER_SSH_KEY } }" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -p ${ { secrets.HOSTINGER_SSH_PORT } } ${ { secrets.HOSTINGER_SSH_HOST } } >> ~/.ssh/known_hosts
- name: Deploy via rsync
run: |
rsync -avz --delete \
--exclude=".env" \
--exclude=".gitignore" \
-e "ssh -p ${ { secrets.HOSTINGER_SSH_PORT } }" \
./ ${ { secrets.HOSTINGER_SSH_USER } }@${ { secrets.HOSTINGER_SSH_HOST } }:${ { secrets.DEPLOY_PATH } }
- name: Laravel post-deploy commands
uses: appleboy/ssh-action@master
with:
host: ${ { secrets.HOSTINGER_SSH_HOST } }
username: ${ { secrets.HOSTINGER_SSH_USER } }
key: ${ { secrets.HOSTINGER_SSH_KEY } }
port: ${ { secrets.HOSTINGER_SSH_PORT } }
script: |
cd ${ { secrets.DEPLOY_PATH } }
composer install --no-dev --prefer-dist --no-interaction
php artisan optimize:clear
🚀 Step 4: Push Your Code to Trigger Deployment
Once everything is set up, just push your Laravel project to the main branch:
git add .
git commit -m "🔧 Configure GitHub Actions for auto deployment"
git push origin main
GitHub will automatically trigger the deployment. You can view the logs under the "Actions" tab of your GitHub repo.
✅ Bonus Tips
- Make sure your server has proper file permissions.
- Always back up your
.envand database before runningphp artisan migrate --force. - If using shared hosting, confirm if it supports SSH key login and composer.
📌 Final Thoughts
By integrating GitHub Actions into your Laravel deployment process, you’re not just saving time — you’re building a professional workflow that scales.
No more manual uploads, no more FTP. Just push and deploy. 🔥
Want to build more automation like this?
👉 Follow for more Laravel DevOps tricks and full-stack developer tutorials.
The Secrets and Safety Rails
Every credential in this pipeline lives in GitHub Actions secrets — SSH keys, server hosts, environment tokens — and nothing sensitive ever appears in the workflow file itself. Use a dedicated deploy key restricted to the one repository, and a server user whose permissions cover the release directory and nothing else. Then add the two safety rails that separate hobby pipelines from production ones: run the test suite as a required step before any deploy step executes, and make the deployment atomic — build into a fresh directory and switch a symlink, so a failed rsync never leaves production half-updated.
Rollbacks and the Zero-Downtime Detail
Symlink-based releases give you rollback for free: keep the last three release directories, and reverting is pointing the symlink back and reloading PHP-FPM — under ten seconds, no rebuild. Wire migrations carefully into this: run them after the new code is live only when they're additive, and schedule breaking schema changes as their own deliberate releases. The uncomfortable truth about automated deploys is that they multiply whatever discipline you already have — great tests and additive migrations make the pipeline a superpower, while a weak test suite just ships bugs faster.
Watching the First Ten Deploys
Trust arrives through repetition. For the first ten automated deploys, watch the Actions log end to end and tail the server logs after each switch — you're learning the pipeline's normal rhythm so anomalies stand out later. Add a notification step that posts success or failure to your team channel with the commit message; visibility is what makes teammates stop asking "did it deploy?" and start trusting the green check. After that break-in period, the pipeline fades into infrastructure: code merges, production updates, and nobody thinks about it — which was the entire point.
When Not to Auto-Deploy
Automation earns exceptions. Schema changes that lock big tables, dependency major-version bumps, and anything touching payment flows deserve a human on the button — use a manual approval environment in Actions for those paths. The pipeline's job isn't removing judgment; it's reserving judgment for the deploys that need it while the routine ninety percent ship themselves.
The Workflow File as Documentation
A nice side effect nobody mentions: the workflow YAML becomes the canonical answer to "how does this app deploy?" — readable by every teammate, versioned with the code it ships, and impossible to lose. When a new developer asks about the release process, the answer is a file path. Keep it clean enough to serve that role: name steps in plain English, comment the non-obvious lines, and resist clever shell one-liners that only their author can read.
Start This Weekend
The full setup — workflow file, secrets, server user, first green deploy — fits in a Saturday morning, and the payback begins with the very next change you ship. Start with the test-then-deploy skeleton, get one boring deploy through it, and add the atomic-release upgrade the following week. Pipelines are like servers: the best one is the one that exists.
Deploys That Stay Boring
A Laravel GitHub Actions deploy pipeline succeeds when releases stop being events — push, watch green checks, done. Keep secrets in Actions, never in the repo. My CodeDeploy on EC2 and (this guide) go deeper.
If you want zero-touch Laravel deploys set up, that's work I take on through Ramlit.