Skip to content

Instantly share code, notes, and snippets.

@ercanertan
Forked from markshust/README.md
Created March 17, 2025 08:49
Show Gist options
  • Save ercanertan/58820bbfa2ffd66b38e9d7f51e604e40 to your computer and use it in GitHub Desktop.
Save ercanertan/58820bbfa2ffd66b38e9d7f51e604e40 to your computer and use it in GitHub Desktop.
GitHub Action to deploy Laravel app

Set up GitHub Actions to handle deployments for your Laravel application. This has similar functionality to Laravel Forge without the recurring cost. GitHub Actions can be used to automate your deployment process on every push to your repository.

Prerequisites

  1. Server Access: Ensure you have SSH access to your server where the Laravel app will be deployed.
  2. Secrets: Store sensitive information such as your server's IP address, SSH username, and private SSH key in GitHub Secrets. Go to your GitHub repository, navigate to "Settings" > "Secrets and variables" > "Actions", and add the following secrets:
    • DEPLOY_SERVER_IP: Your server's IP address.
    • DEPLOY_SERVER_USER: Your SSH username.
    • DEPLOY_SERVER_KEY: Your private SSH key. Make sure this key is authorized to access your server (~/.ssh/authorized_keys).
    • DEPLOY_SERVER_DIR: The directory where you'd like to deploy your app, relative to /var/www/. Ex: example.com

Setting Up GitHub Actions

  1. Create a Workflow File: In your repository, create a new directory called .github/workflows if it doesn't already exist. Inside, create a file called deploy.yml.

Set up server

On your server, set up the www-data user so GitHub will have access to this user account for deploying code.

# Ensure npm directory is set up with proper permissions
sudo mkdir -p /var/www/.npm
sudo chown -R www-data:www-data /var/www/.npm

# Set up SSH directory with correct permissions, as root
mkdir -p /var/www/.ssh
chown -R www-data:www-data /var/www/.ssh
chmod 700 /var/www/.ssh

# Switch to www-data user
sudo su - www-data

# Give www-data a valid shell
sudo chsh -s /bin/bash www-data

# Generate new key pair
ssh-keygen -t ed25519 -C "your-server-name"

# Create/update authorized keys
touch /var/www/.ssh/authorized_keys
chmod 600 /var/www/.ssh/authorized_keys

# Copy the public key to authorized_keys
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

# Display the private key to copy to GitHub Secrets
cat ~/.ssh/id_ed25519

# Copy public key to GitHub as the deploy key at Settings -> Deploy Keys:
cat /var/www/.ssh/id_ed25519.pub

# Create or append GitHub's SSH key to known_hosts
ssh-keyscan github.com >> ~/.ssh/known_hosts

# Set proper permissions
chmod 644 ~/.ssh/known_hosts

Explanation

  • Trigger: The workflow is triggered on every push to the main branch. You can change this to any branch you prefer.
  • SSH Setup: The webfactory/ssh-agent action is used to set up SSH authentication.
  • Deploy Command: The deployment is handled by running an SSH command to pull the latest changes, install dependencies, and run necessary Artisan commands on your server.

Considerations

  • Backup and Rollback: Ensure you have a backup strategy and a rollback mechanism in place in case something goes wrong during deployment.
  • Environment Variables: Environment variables should be managed on your server (e.g., using an .env file).
  • Database Migrations: Running php artisan migrate --force automatically during a deployment can be risky. Ensure your database changes are backward-compatible or add checks to run migrations manually if needed.
name: Deploy Laravel App
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.DEPLOY_SERVER_KEY }}
- name: Deploy to server
run: |
ssh -o StrictHostKeyChecking=no ${{ secrets.DEPLOY_SERVER_USER }}@${{ secrets.DEPLOY_SERVER_IP }} "
cd /var/www/${{ secrets.DEPLOY_SERVER_DIR }} &&
git reset --hard HEAD && git clean -df &&
git pull origin main &&
composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader &&
npm ci &&
npm run build &&
php artisan migrate --force &&
php artisan optimize:clear &&
php artisan config:cache &&
php artisan route:cache
"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment