A comprehensive Laravel application deployment setup integrating Docker, ELK Stack (Elasticsearch, Logstash, Kibana), with advanced logging, monitoring, and automated DevOps features. Check ELK-Stack-with-Laravel on github for more information.
βββ .github/
β βββ workflows/
β βββ backup.yml
β βββ ci-cd.yml
βββ apache/
β βββ 000-default.conf
βββ elasticsearch/
β βββ elasticsearch.yml
βββ kibana/
β βββ kibana.yml
βββ logstash/
β β βββ config/
β β βββ logstash.yml
β β βββ pipeline/
β β βββ laravel.conf
βββ php/
β βββ php.ini
βββ src/
β βββ [Laravel Project Files]
βββ Dockerfile
βββ docker-compose.yml
βββ wait-for-it.sh
Change the following environment variables in your docker-compose.yml
file:
# Laravel & MySQL
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=root
DB_PASSWORD=root_password
Sensitive data such as AWS credentials and Slack webhook URLs should be stored securely as GitHub Secrets. To configure these:
Navigate to your GitHub repository and go to Settings β Secrets and variables β Actions.
Add the following secrets:
Secret Name | Description |
---|---|
DB_HOST |
The host address of your database server. |
DB_PORT |
The port of your database server (e.g., 3306 for MySQL). |
DB_DATABASE |
The name of the database to back up. |
DB_USERNAME |
The username for the database. |
DB_PASSWORD |
The password for the database. |
AWS_BUCKET |
The name of your S3 bucket where backups will be stored. |
AWS_ACCESS_KEY_ID |
Your AWS Access Key ID. |
AWS_SECRET_ACCESS_KEY |
Your AWS Secret Access Key. |
AWS_DEFAULT_REGION |
Your AWS region (e.g., us-east-1 ). |
SLACK_WEBHOOK_URL |
The Slack Webhook URL for sending notifications. |
Secrets are referenced directly in the GitHub Actions workflow like so:
env:
AWS_ACCESS_KEY_ID: $
AWS_SECRET_ACCESS_KEY: $
AWS_DEFAULT_REGION: $
AWS_BUCKET: $
SLACK_WEBHOOK_URL: $
git clone https://github.com/anas1412/ELK-Stack-with-Laravel.git
cd ELK-Stack-with-Laravel
OPTION 1: Add your own project and renaume it to src/
. Ensure the project is properly configured and accessible.
git clone [your-project-url]
mv [your-project-name] /src
OPTION 2: add your files if they already exist:
mv /path/to/your/laravel/project src/
OPTION 3: if you want to test it out on a new laravel project before moving forward:
composer create-project laravel/laravel src
N.B:
DB_DATABASE
etc .. in docker-compose.yml
to match your new projectβs database name.php.ini
& 000-default.conf
to match your new projectβs requirements.docker-compose up -d --build
Elasticsearch
cluster.name: "elasticsearch"
network.host: localhost
Kibana
server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://elasticsearch:9200"]
monitoring.ui.container.elasticsearch.enabled: true
Logstash
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.hosts: ["http://elasticsearch:9200"]
http.host: 0.0.0.0
path.logs: /var/log/logstash
log.level: debug
Logstash Pipeline Configuration
input {
file {
type => "laravel-logs"
path => "/var/www/html/storage/logs/laravel.log"
start_position => "beginning"
sincedb_path => "/dev/null"
codec => plain { charset => "UTF-8" }
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log_level} %{GREEDYDATA:message}" }
}
mutate {
add_field => {
"timestamp" => "%{timestamp}"
"log_level" => "%{log_level}"
"message" => "%{message}"
}
}
json {
source => "message"
target => "json_message"
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "laravel-logs-%{+YYYY.MM.dd}"
index_settings => {
"number_of_replicas" => 0 # Disable replicas for this index
}
}
# Optional: Output to stdout for debugging purposes
stdout {
codec => rubydebug
}
slack {
url => "${SLACK_WEBHOOK_URL}"
channel => "#alerts"
username => "ELK Alert Bot"
when => [
"[log_level]" == "error"
]
}
}
GitHub Action Workflow (backup.yml)
name: Database Backup
on:
schedule:
- cron: "0 0 * * *" # Daily at midnight
workflow_dispatch: # Allows manual triggering of the workflow
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Backup Database
run: |
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="backup-$TIMESTAMP.sql"
mysqldump -h $ \
-P $ \
-u $ \
-p$ \
$ > $BACKUP_FILE
echo "Backup created: $BACKUP_FILE"
- name: Upload to S3
uses: aws-actions/aws-cli@v2
with:
args: s3 cp $BACKUP_FILE s3://$/backups/$BACKUP_FILE
env:
AWS_ACCESS_KEY_ID: $
AWS_SECRET_ACCESS_KEY: $
AWS_DEFAULT_REGION: $
- name: Cleanup
run: |
rm -f $BACKUP_FILE
echo "Local backup file deleted."
notify-failure:
runs-on: ubuntu-latest
if: failure() # Only run this job if the backup job fails
steps:
- name: Notify on Failure via Slack Webhook
run: |
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"β *Database Backup Failed!*\n- Repository: '$'\n- Workflow: '$'\n- Job: '$'\n- Time: '$'"}' \
$
Log Monitoring Dashboard:
Performance Dashboard:
Alerts are triggered for:
Here you can configure your CI/CD pipeline to automate the deployment process. This includes building, testing, and deploying your Laravel application. You can customize the workflow to fit your specific needs.
name: Laravel CI/CD
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# Step 1: Checkout the code
- name: Checkout Code
uses: actions/checkout@v2
# Step 2: Set up Docker and Docker Compose
- name: Set up Docker Compose
run: |
sudo apt-get update
sudo apt-get install -y docker-compose
# Step 3: Install Composer
- name: Install Composer
run: |
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# Optional Step: Download a new Laravel project or change this with your project URL
- name: Set up a new Laravel project
run: composer create-project --prefer-dist laravel/laravel src --no-interaction
# Step 4: Build Docker Images
- name: Build Docker Images
run: docker-compose build
# Step 5: Run Laravel Tests
- name: Run Tests
run: docker-compose run app php artisan test
# Step 6: Deploy the Application
- name: Deploy
if: success()
run: |
docker-compose up -d
docker-compose exec --no-TTY app php artisan migrate --force --no-interaction
echo "Application deployed successfully."
docker-compose down
ELK Stack Connection Issues:
# Check Elasticsearch status
curl -XGET 'localhost:9200/_cluster/health?pretty'
# Check Logstash pipeline
docker logs elk-logstash
# Verify Kibana connection
docker logs elk-kibana
Backup Issues:
# Check AWS credentials
aws s3 ls s3://your-bucket
Log Collection Issues:
# Check Elasticsearch
curl -XGET 'localhost:9200/_cluster/health?pretty'
# Logstash logs
docker logs logstash
# Laravel application logs
docker-compose exec app tail -f /var/www/html/storage/logs/laravel.log
indices.memory.index_buffer_size: 30%
bootstrap.memory_lock: true
pipeline.workers: 2
pipeline.batch.size: 125
pipeline.batch.delay: 50
[] Improve the Slack notification configurations in Logstash
[] Implement comprehensive error handling.
[] Enhance Kibana dashboard visualizations
[] Create more detailed logging filters
[] Fine-tune Elasticsearch memory settings
[] Implement log rotation strategies
[] Add caching mechanisms
[] Enable Elasticsearch security features
[] Implement SSL/TLS for services
[] Integrate application performance monitoring (APM)
[] Create custom Grafana dashboards
[] Set up more advanced alerting rules
[] Develop rollback strategies
[] Create staging environment configurations
[] Automate dependency updates
[] Implement infrastructure-as-code (IaC)
This project is licensed under the MIT License. See the LICENSE file for more information.
Contributions are welcome! Please feel free to open issues or pull requests to help improve this project.