This guide explains how to set up the required environment variables (GitHub Secrets) for the Laravel deployment GitHub Actions workflow.
The deployment script uses GitHub Secrets to securely store sensitive information like SSH keys and server details. These secrets are referenced in the workflow using the ${{ secrets.SECRET_NAME }}
syntax.
Description: The private SSH key used to authenticate with your deployment server.
How to generate:
# On your local machine, generate a new SSH key pair
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/github_deploy_key
# Copy the public key to your server
ssh-copy-id -i ~/.ssh/github_deploy_key.pub your-user@your-server-ip
# Or manually add it to the server's authorized_keys
cat ~/.ssh/github_deploy_key.pub | ssh your-user@your-server-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
What to store: Copy the entire contents of the private key file (~/.ssh/github_deploy_key
), including the -----BEGIN OPENSSH PRIVATE KEY-----
and -----END OPENSSH PRIVATE KEY-----
lines.
Description: The username for SSH connection to your deployment server.
Example values:
deploy
ubuntu
ec2-user
root
(not recommended for security)
Best practice: Create a dedicated deployment user with limited permissions:
# On your server
sudo adduser deploy
sudo usermod -aG www-data deploy
Description: The IP address or hostname of your deployment server.
Example values:
192.168.1.100
your-server.example.com
deploy.myapp.com
Description: The directory name where your Laravel application is deployed on the server.
Example values:
myapp
laravel-app
production
Note: This will be used as part of the path /var/www/{DEPLOY_SERVER_DIR}/
. The script expects the following directory structure on your server:
/var/www/{DEPLOY_SERVER_DIR}/
├── current/ # Symlink to active release
└── releases/ # Directory containing timestamped releases
├── 20240115-143052/
├── 20240115-151230/
└── 20240115-160845/
- Navigate to your GitHub repository
- Click on Settings (in the repository navigation)
- In the left sidebar, click Secrets and variables → Actions
- Click New repository secret
- For each secret:
- Enter the secret name (e.g.,
DEPLOY_SERVER_KEY
) - Enter the secret value
- Click Add secret
- Enter the secret name (e.g.,
Before using this deployment script, ensure your server has:
-
Required software installed:
- PHP 8.4 with FPM
- Composer
- Node.js 20.x and npm
- Git
- Supervisor (for Horizon)
-
Directory structure created:
sudo mkdir -p /var/www/{your-app-name}/releases sudo chown -R {deploy-user}:www-data /var/www/{your-app-name} sudo chmod -R 755 /var/www/{your-app-name}
-
Initial deployment:
- The script expects a
current
symlink to exist - For first deployment, manually clone and set up your app:
cd /var/www/{your-app-name}/releases git clone https://github.com/your-username/your-repo.git $(date +%Y%m%d-%H%M%S) cd {timestamp-directory} composer install npm install npm run build # Configure .env file php artisan key:generate php artisan migrate ln -s /var/www/{your-app-name}/releases/{timestamp-directory} /var/www/{your-app-name}/current
- The script expects a
-
Sudo permissions for the deploy user: Add to
/etc/sudoers
(usevisudo
):deploy ALL=(ALL) NOPASSWD: /usr/bin/supervisorctl start horizon deploy ALL=(ALL) NOPASSWD: /bin/systemctl reload php8.4-fpm
- Use a dedicated deploy user instead of root
- Restrict SSH key usage by adding command restrictions in
authorized_keys
:command="cd /var/www/* && $SSH_ORIGINAL_COMMAND",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAAC3...
- Use strong SSH keys (Ed25519 recommended)
- Rotate secrets regularly
- Limit GitHub Actions to specific branches (already configured for
main
branch only)
- Verify the SSH key is correctly formatted (no extra spaces or line breaks)
- Check server SSH configuration allows key-based authentication
- Ensure the deploy user has the correct permissions
- Verify the deploy user owns the application directory
- Check that the deploy user is in the
www-data
group - Ensure proper sudo permissions are configured
- Check Node.js and PHP versions match your local development environment
- Verify all required PHP extensions are installed on the server
- Ensure sufficient disk space for builds and releases
Here's a complete example for a Laravel app called "myapp":
-
Create secrets in GitHub:
DEPLOY_SERVER_KEY
: (your private SSH key content)DEPLOY_SERVER_USER
:deploy
DEPLOY_SERVER_IP
:203.0.113.10
DEPLOY_SERVER_DIR
:myapp
-
Server directory structure:
/var/www/myapp/ ├── current -> /var/www/myapp/releases/20240115-160845 └── releases/ └── 20240115-160845/ ├── app/ ├── bootstrap/ ├── config/ ├── ... └── .env
-
Deployment flow:
- Push to
main
branch triggers the workflow - Script creates a new timestamped release directory
- Copies current release, pulls latest code
- Installs dependencies only if changed
- Builds assets only if needed
- Runs migrations and caching
- Atomically switches the
current
symlink - Reloads services
- Cleans up old releases (keeps last 3)
- Push to