I will walk you through setting up automated deployment for your Laravel application using GitHub Actions. We’ll cover everything from setting up your server to configuring GitHub Actions.
Prerequisites:
Before we begin, ensure you have:
- A Laravel application hosted on GitHub
- A server with LEMP/LAMP stack installed (Follow LEMP Stack Installation Guide for Ubuntu)
- GitHub account with administrative access to your repository
Step 1: Generate SSH Keys
First, we need to generate SSH keys for secure communication between GitHub Actions and your server.
Note: Do not set a passphrase while generating the SSH key for automation purposes. Ensure the private key is stored securely as a GitHub secret to prevent unauthorized access.
# On your local machine
ssh-keygen -t rsa -b 4096 -C "[email protected]"
This will create:
- Private key:
~/.ssh/id_rsa
- Public key:
~/.ssh/id_rsa.pub
Copy the public key content (id_rsa.pub) to your server:
# On your server, add it to authorized_keys
nano ~/.ssh/authorized_keys
Step 2: Configure GitHub Secrets
Add the following secrets to your GitHub repository (Settings > Secrets and variables > Actions):
SERVER_IP
: Your server’s IP addressSERVER_SSH_USER
: SSH username (usually root or ubuntu)SERVER_SSH_KEY
: The contents of your private key file (~/.ssh/id_rsa)SERVER_PATH
: Your Laravel project path (e.g., /var/www/html)
Step 3: Create GitHub Actions Workflow
Create .github/workflows/deploy.yml
in your repository with the deployment script.
name: Deploy to Server with Maintenance Mode
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Remove Old Files
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_SSH_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd ${{ secrets.SERVER_PATH }}
find . -mindepth 1 -not -name 'phpmyadmin' -not -name '.env' -not -name 'storage' -exec rm -rf {} +
- name: Deploy to Server
uses: easingthemes/[email protected]
env:
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
REMOTE_HOST: ${{ secrets.SERVER_IP }}
REMOTE_USER: ${{ secrets.SERVER_SSH_USER }}
TARGET: ${{ secrets.SERVER_PATH }}
EXCLUDE: "/storage"
- name: Run Essential Commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_SSH_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd ${{ secrets.SERVER_PATH }}
export COMPOSER_ALLOW_SUPERUSER=1; composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan migrate --force
php artisan route:cache
php artisan view:cache
php artisan event:cache
php artisan queue:restart
npm ci
npm run build
touch /var/www/html/storage/logs/laravel.log
chown -R www-data:www-data ${{ secrets.SERVER_PATH }}
systemctl restart nginx
systemctl restart php8.3-fpm
php artisan optimize:clear
- name: Verify Deployment
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_SSH_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd ${{ secrets.SERVER_PATH }}
if php artisan --version; then
echo "Deployment successful"
else
echo "Deployment failed"
exit 1
fi
Remember to replace placeholder values (your-domain.com, [email protected]) with your actual values.
If you found this article helpful, feel free to share it with others in the Laravel community. Happy coding!