Automating the deployment process using GitHub Actions for a Laravel application to an AWS EC2 instance can significantly streamline your development workflow. This detailed guide breaks down each step involved in the process, providing a thorough understanding and actionable insights.
Before beginning, ensure you have:
- An active AWS account.
- A Laravel application hosted on GitHub.
- Basic familiarity with AWS EC2, IAM, Nginx, and SSH.
-
Launch an EC2 Instance:
- Navigate to the EC2 Dashboard in the AWS Management Console.
- Click on "Launch Instance" and select an Ubuntu Server image. Ubuntu is recommended for its wide support and ease of use with Laravel and Nginx.
- Choose an instance type.
t2.micro
is sufficient for demonstration purposes. - Configure instance details. Leave the defaults unless you have specific requirements.
- Add storage if needed. The default allocated storage should suffice for a basic Laravel application.
- Tag your instance for easier management. For example, Key: Name, Value: LaravelServer.
- Configure the security group to allow inbound traffic on ports 22 (SSH), 80 (HTTP), and 443 (HTTPS).
- Review and launch the instance, selecting a key pair for SSH access.
-
Security Group Configuration:
- Ensure your security group allows inbound connections on ports 22, 80, and 443 to enable web traffic and SSH access.
-
Generate SSH Key Pair (if not already done):
- On your local machine, use
ssh-keygen
to generate a new SSH key pair. - Follow the prompts, and save your key pair in a secure location.
- On your local machine, use
-
Add SSH Public Key to EC2:
- Navigate to your EC2 instance dashboard.
- Select your instance and use the "Actions" menu to manage SSH keys.
- Add the public key you generated to the
authorized_keys
for the default user (typicallyubuntu
).
-
SSH into Your EC2 Instance:
- Use
ssh -i /path/to/your/private/key.pem ubuntu@your_instance_ip
to connect to your instance.
- Use
-
Install Nginx:
- Update your package lists:
sudo apt-get update
. - Install Nginx:
sudo apt-get install nginx
. - Check Nginx is running:
systemctl status nginx
.
- Update your package lists:
-
Configure Nginx for Laravel:
- Navigate to
/etc/nginx/sites-available/
. - Create a new configuration file for your Laravel application. You can copy the default config:
sudo cp default laravel
. - Edit the
laravel
file, setting theroot
directive to point to your Laravel project'spublic
directory and updating theserver_name
directive to your domain or IP address. - Symbolically link your config file in
sites-enabled
to enable it:sudo ln -s /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/
. - Test Nginx configuration:
sudo nginx -t
. - Reload Nginx to apply changes:
sudo systemctl reload nginx
.
- Navigate to
-
Ensure Composer Dependencies: Verify that
composer.json
andcomposer.lock
are up to date and committed to your repository. -
Environment Configuration: Make sure your
.env
file variables are appropriate for production and exclude the.env
file from source control. Use environment secrets for sensitive information.
- Create an IAM User:
- In the AWS IAM Dashboard, create a new user with programmatic access.
- Attach policies granting necessary permissions for deployment, such as EC2 and S3 access.
ref: https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/
- Record Access Keys:
- Securely store the access key ID and secret access key generated upon creating your IAM user.
-
Define Workflow File:
- In your Laravel project repository, create a new directory
.github/workflows
if it doesn't exist. - Create a YAML file for your workflow, e.g.,
laravel_ci_cd.yml
.
- In your Laravel project repository, create a new directory
-
Workflow Configuration:
- Specify the trigger for your workflow, such as on push to the
main
branch. - Define jobs, including checking out the repository, setting up PHP, installing Composer dependencies, and deploying to EC2 using SSH and
rsync
. - Use actions like
actions/checkout@v2
for checking out code,shivammathur/setup-php@v2
for setting up PHP, and custom run commands for deployment tasks.
- Specify the trigger for your workflow, such as on push to the
-
Store SSH and AWS Credentials in GitHub Secrets:
- Navigate to your repository's Settings > Secrets.
- Add your EC2 instance's SSH private key, AWS access key ID, and secret access key as secrets.
- Navigate to "Settings > Secrets" in your repository and add secrets for
SSH_PRIVATE_KEY
,AWS_ACCESS_KEY_ID
, andAWS_SECRET_ACCESS_KEY
with the values obtained in previous steps.
- Push changes to your repository to trigger the workflow.
- Monitor the workflow run in the "Actions" tab of your GitHub repository to ensure successful execution.
- Access your application via the EC2 instance's public IP or domain name to verify the deployment.
Automating your Laravel application deployment to AWS EC2 using GitHub Actions simplifies the process, reduces the potential for human error, and ensures consistent deployments. This guide has detailed each step required to set up this automation, from preparing your AWS EC2 instance and configuring Nginx to setting up the GitHub Actions workflow and securely storing credentials. With this setup, you can focus more on development and less on the intricacies of deployment.
Remember, this guide serves as a starting point. Depending on your specific project needs, consider customizing the Nginx configuration, adjusting file permissions, or enhancing the GitHub Actions workflow for a more tailored deployment process.
name: Deploy to EC
on:
push:
branches:
- staging
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
extensions: mbstring, intl
- name: Install Dependencies
run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Copy Environment File
run: cp .env.example .env
- name: Generate Application Key
run: php artisan key:generate
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
# - name: Run Tests
# run: php artisan test
# env:
# DB_CONNECTION: sqlite
# DB_DATABASE: database/database.sqlite
- name: Laravel Pint
run: npm install && npm run pint
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Configure SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.EC2_PUBLIC_IP }} >> ~/.ssh/known_hosts
- name: Install PHP and dependencies
run: sudo apt-get update && sudo apt-get install php php-mbstring php-xml
- name: Install Composer dependencies
run: composer install --no-interaction --prefer-dist --optimize-autoloader
- name: Deploy to EC2
run: |
ssh -i ~/.ssh/id_rsa ubuntu@${{ secrets.EC2_PUBLIC_IP }} 'sudo chown -R ubuntu:ubuntu /var/www/html/server'
rsync -avz --delete --exclude='.env' -e "ssh -i ~/.ssh/id_rsa" ./ ubuntu@${{ secrets.EC2_PUBLIC_IP }}:/var/www/html/server
ssh -i ~/.ssh/id_rsa ubuntu@${{ secrets.EC2_PUBLIC_IP }} '
cd /var/www/html/server &&
composer install --no-interaction --prefer-dist --optimize-autoloader &&
php artisan migrate --force &&
php artisan config:cache &&
php artisan route:cache'
ssh -i ~/.ssh/id_rsa ubuntu@${{ secrets.EC2_PUBLIC_IP }} 'sudo chown -R www-data:www-data /var/www/html/server'
- name: Clear SSH key
run: rm ~/.ssh/id_rsa
- https://medium.com/techvblogs/how-to-deploy-laravel-application-with-nginx-on-ubuntu-cc3ef9f39068
- https://www.linkedin.com/pulse/set-up-github-actions-workflow-deploy-laravel-project-selvanantham/
- https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/
- https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-laravel-with-nginx-on-ubuntu-20-04
- https://www.clickittech.com/tutorial/deploy-laravel-on-aws-ec2/