If you're still deploying PHP apps by FTP-ing files to an EC2 instance, you're one bad deploy away from a production outage. A proper CI/CD pipeline catches errors before they reach production and deploys in under 3 minutes.
What We're Building
A GitHub Actions workflow that: (1) runs PHP syntax checks + unit tests on every push, (2) builds a deployment package on merge to main, (3) SSHs to EC2 and deploys with zero-downtime via symlinks, (4) notifies Slack on success or failure.
Step 1: EC2 Directory Structure for Zero-Downtime
Use a releases/ directory approach: each deploy creates a new folder (e.g., releases/20260322-120000), and a current/ symlink points to the active release. Apache/Nginx document root points to current/public. Rollback = update the symlink.
Step 2: GitHub Actions Workflow File
Create .github/workflows/deploy.yml. The workflow has two jobs: test (runs on every push) and deploy (runs only on push to main after test passes).
Step 3: SSH Deploy Step
Store your EC2 private key as a GitHub Actions Secret (EC2_SSH_KEY). The deploy step SSHs to EC2, pulls from GitHub, runs composer install --no-dev, runs migrations, and updates the symlink.
Step 4: Keeping Only the Last 5 Releases
Add a cleanup step: ls -dt releases/* | tail -n +6 | xargs rm -rf. This keeps the 5 most recent releases for quick rollback while preventing disk space issues.
Step 5: Slack Notification
Use the Slack GitHub Action (slackapi/slack-github-action) to post to a #deploys channel on success and #alerts on failure. Include the commit message, author, and a link to the workflow run.
Get More Like This
AI automation tips and n8n tutorials every 2 weeks. No spam.