Blog / Strategy / GitHub Actions for…
Strategy Jun 30, 2026

GitHub Actions for PHP Deployment: A Practical CI/CD Setup for Small Teams

A straightforward GitHub Actions workflow for deploying PHP applications automatically over SSH, plus the pitfalls that trip up most first-time setups.

F
Faraz Ahmed
Founder · Lead developer
GitHub Actions for PHP Deployment: A Practical CI/CD Setup for Small Teams

Manually uploading PHP files over FTP after every change works right up until it doesn't — a forgotten file, a deployed feature that wasn't ready, no clean record of what shipped when. A basic GitHub Actions deployment pipeline solves this without needing a full DevOps setup, and for a small team or solo developer, it can be running in an afternoon.

The Core Idea

Every time code is pushed to your main branch, GitHub Actions runs a workflow that connects to your server over SSH and pulls the latest code, runs any necessary build steps, and restarts services if needed. No manual file transfers, and a clear log of every deployment in GitHub's own interface.

A Minimal Working Example

This is a simplified version of a workflow that deploys on every push to main:

name: Deploy
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy over SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            cd /var/www/your-app
            git pull origin main
            composer install --no-dev --optimize-autoloader
            php artisan migrate --force
            php artisan config:cache

Setting Up the Pieces

  1. Generate a dedicated SSH key pair specifically for deployment — never reuse a personal key. Add the public key to the server's authorized keys.
  2. Add the private key, server host, and server username as encrypted secrets in your GitHub repository settings, not hardcoded anywhere in the workflow file.
  3. Confirm the deploy user on your server has exactly the permissions needed — write access to the app directory, ability to run composer and artisan — and nothing broader than that.
  4. Test against a staging branch or staging server first before pointing the workflow at production.

Pitfalls That Trip Up Most First Attempts

  • Committing secrets directly into the workflow file instead of using GitHub's encrypted secrets — this exposes credentials in your repository history permanently, even if removed later.
  • Using an overly privileged deploy user with full root access, which turns a compromised CI pipeline into a compromised server.
  • No rollback plan — if a deploy ships broken code, the workflow should make it fast to revert, not require manually reconstructing the previous state.
  • Skipping a staging environment entirely, which means the first real test of the pipeline happens against production.
  • Forgetting to clear cached config after deployment in frameworks like Laravel, which can leave the app running against stale cached configuration after a deploy.

This setup scales from a single solo project to a small team without much modification — the main additions as you grow are usually a staging environment and a notification step so the team knows when a deploy completes or fails.

Alfa Dev sets up GitHub Actions deployment pipelines as part of every custom build, using dedicated deploy keys and clean Nginx configuration. Get in touch if your deployment process is still manual.

F

Ready to redesign?

Free 20-min consultation. Custom WordPress redesigns $750–$1,500. Training included. 7–14 day delivery.

Book a call