|
1 | | -# 🚀 Laravel Blog with Elasticsearch & AWS Deployment |
2 | | - |
3 | | -A modern, full-featured blog application built with Laravel 10, featuring powerful Elasticsearch integration and AWS deployment capabilities. This project was developed to enhance my Laravel and AWS skills while building something practical and scalable. |
4 | | - |
5 | | -As a developer looking to deepen my understanding of modern web technologies, I wanted to create a project that would challenge me across multiple areas: |
6 | | - |
7 | | -- **Laravel Mastery**: Implementing clean architecture patterns, advanced features, and best practices |
8 | | -- **AWS Skills**: Learning cloud deployment, infrastructure as code, and scalable architectures |
9 | | -- **Search Technology**: Integrating Elasticsearch for powerful, real-time search capabilities |
10 | | -- **Modern DevOps**: Using Docker, CI/CD pipelines, and automated deployments |
11 | | - |
12 | | -What started as a learning exercise evolved into a robust, production-ready blog platform with some pretty cool features! |
13 | | - |
14 | | -## ✨ Key Features |
| 1 | +# My Laravel Blog AWS Journey |
15 | 2 |
|
16 | | -### 🔍 **Powerful Search with Elasticsearch** |
17 | | -- Lightning-fast full-text search across all blog posts |
18 | | -- Real-time search suggestions and filtering |
19 | | -- Category-based filtering combined with search |
20 | | -- Automatic index synchronization when content changes |
21 | | - |
22 | | -### 👨💼 **Admin Dashboard** |
23 | | -- Clean, intuitive admin interface for managing content |
24 | | -- Full CRUD operations for posts and categories |
25 | | -- Rich text editor for post creation and editing |
26 | | -- Image upload and management |
27 | | -- Category management with automatic URL slug generation |
28 | | - |
29 | | -### 🔄 **Smart Content Synchronization** |
30 | | -- Automatic Elasticsearch index updates when posts are modified |
31 | | -- Background job processing for performance |
32 | | -- Real-time category updates that sync across all related posts |
33 | | -- Event-driven architecture for maintainable code |
34 | | - |
35 | | -### 🏗️ **Clean Architecture** |
36 | | -- Domain-driven design with clear separation of concerns |
37 | | -- Use Cases pattern for business logic |
38 | | -- Repository pattern for data access |
39 | | -- Event/Listener system for loose coupling |
40 | | -- Comprehensive test coverage |
41 | | - |
42 | | -### ☁️ **AWS-Ready Deployment** |
43 | | -- Docker containerization for consistent environments |
44 | | -- Production-ready with environment-specific configs |
45 | | - |
46 | | -### 🎨 **Modern Frontend** |
47 | | -- Responsive design that works on all devices |
48 | | -- Tailwind CSS for beautiful, consistent styling |
49 | | -- Fast page loads with optimized asset pipeline |
50 | | -- SEO-friendly URLs and meta tags |
51 | | - |
52 | | -## 🛠️ Tech Stack |
53 | | - |
54 | | -**Backend:** |
55 | | -- Laravel 10 (PHP 8.2+) |
56 | | -- Elasticsearch 8.x for search |
57 | | -- MySQL for primary data storage |
58 | | -- Redis for caching and queues |
59 | | - |
60 | | -**Frontend:** |
61 | | -- Blade templates with Tailwind CSS |
62 | | -- Vite for asset compilation |
63 | | -- Alpine.js for interactive components |
64 | | - |
65 | | -**Infrastructure:** |
66 | | -- Docker & Docker Compose for development |
67 | | -- AWS ECS for container orchestration |
68 | | -- AWS RDS for managed database |
69 | | -- AWS ElastiCache for Redis |
70 | | -- AWS Elasticsearch Service |
71 | | -- Nginx as reverse proxy |
72 | | - |
73 | | -**DevOps:** |
74 | | -- GitHub Actions for CI/CD |
75 | | -- Automated testing and deployment pipelines |
76 | | - |
77 | | - |
78 | | -### Prerequisites |
79 | | -- Docker and Docker Compose |
80 | | -- Git |
81 | | - |
82 | | -### Local Development Setup |
83 | | - |
84 | | -1. **Clone the repository** |
85 | | - ```bash |
86 | | - git clone https://github.com/yourusername/laravel-blog-aws.git |
87 | | - cd laravel-blog-aws |
88 | | - ``` |
89 | | - |
90 | | -2. **Start the development environment** |
91 | | - ```bash |
92 | | - docker-compose up -d |
93 | | - ``` |
94 | | - |
95 | | -3. **Install dependencies and setup** |
96 | | - ```bash |
97 | | - docker-compose exec app composer install |
98 | | - docker-compose exec app php artisan key:generate |
99 | | - docker-compose exec app php artisan migrate --seed |
100 | | - ``` |
101 | | - |
102 | | -4. **Create Elasticsearch index** |
103 | | - ```bash |
104 | | - docker-compose exec app php artisan elasticsearch:recreate-index |
105 | | - ``` |
106 | | - |
107 | | -5. **Visit your blog** |
108 | | - - Blog: http://localhost |
109 | | - - Admin: http://localhost/admin (after registering an account) |
110 | | - |
111 | | -That's it! You now have a fully functional blog with search capabilities running locally. |
112 | | - |
113 | | - |
114 | | -Building this project significantly improved my skills in: |
115 | | - |
116 | | -**Laravel:** |
117 | | -- Advanced architecture patterns and dependency injection |
118 | | -- Event-driven programming and background job processing |
119 | | -- Testing strategies for complex applications |
120 | | -- Performance optimization and caching strategies |
121 | | - |
122 | | -**AWS:** |
123 | | -- Container orchestration with ECS |
124 | | -- Managed services integration (RDS, ElastiCache, Elasticsearch) |
125 | | -- CI/CD pipeline design and implementation |
126 | | - |
127 | | -**General:** |
128 | | -- Elasticsearch integration and search optimization |
129 | | -- Docker containerization best practices |
130 | | -- Modern PHP development workflows |
131 | | -- Clean code principles and maintainable architecture |
| 3 | +Hey there! 👋 I wanted to learn Terraform and how to create infrastructure with Terraform in AWS, then deploy a Laravel app with different services like Redis, RDS, and Nginx. This project is the result of that learning adventure! |
| 4 | + |
| 5 | +I developed this simple blog system following clean code architecture principles. To improve the search functionality, I integrated Elasticsearch, and I'm using Redis for queuing background jobs. |
| 6 | + |
| 7 | +This is my Terraform module to create AWS infrastructure from scratch - it's been quite a journey! 🚀 |
| 8 | + |
| 9 | +## 🎯 What I Built |
| 10 | + |
| 11 | +I created a production-ready Laravel blog application that runs on AWS with: |
| 12 | + |
| 13 | +- **Laravel 10** - My choice for the backend framework |
| 14 | +- **AWS ECS Fargate** - Because I wanted to learn containerized deployments |
| 15 | +- **RDS MySQL** - Managed database (no more server maintenance headaches!) |
| 16 | +- **ElastiCache Redis** - For caching and my background job queues |
| 17 | +- **Elasticsearch** - This was tricky but so worth it for advanced search |
| 18 | +- **S3** - File storage made simple |
| 19 | +- **Application Load Balancer** - High availability was important to me |
| 20 | +- **ECR** - Container registry for my Docker images |
| 21 | +- **CloudWatch** - Monitoring everything (learned this the hard way!) |
| 22 | + |
| 23 | +## ✨ Features I'm Proud Of |
| 24 | + |
| 25 | +- **Clean Architecture** - I spent time learning domain-driven design patterns |
| 26 | +- **Elasticsearch Integration** - Took me a while to get this right, but the search is amazing now |
| 27 | +- **Background Jobs** - Queue processing with Redis (no more slow page loads!) |
| 28 | +- **Self-Healing Database** - The app automatically runs migrations if tables are missing |
| 29 | +- **CI/CD Pipeline** - GitHub Actions deployment (this was a game-changer for me) |
| 30 | +- **Infrastructure as Code** - Everything in Terraform (scary at first, but so powerful) |
| 31 | +- **Container Security** - Multi-stage Docker builds with security best practices |
| 32 | +- **Auto-scaling** - ECS Fargate scales based on demand |
| 33 | + |
| 34 | +## 🛠 What You'll Need |
| 35 | + |
| 36 | +Before you start this journey, make sure you have: |
| 37 | + |
| 38 | +- **AWS CLI** (v2.0 or later) - You'll need AWS credentials |
| 39 | +- **Terraform** (v1.0 or later) - The star of the show! |
| 40 | +- **Docker** (v20.0 or later) - For containerization |
| 41 | +- **Git** - Version control is essential |
| 42 | + |
| 43 | +## 🚀 Let's Get Started! |
| 44 | + |
| 45 | +### 1. Clone My Project |
| 46 | + |
| 47 | +```bash |
| 48 | +git clone [email protected]:Nadeera3784/laravel-10-blog-aws-deployment.git |
| 49 | +cd laravel-10-blog-aws-deployment |
| 50 | +``` |
| 51 | + |
| 52 | +### 2. Set Up Your AWS Credentials |
| 53 | + |
| 54 | +```bash |
| 55 | +aws configure |
| 56 | +# You'll need your AWS Access Key ID, Secret Access Key, and choose us-east-1 as region |
| 57 | +``` |
| 58 | + |
| 59 | +### 3. Configure Terraform Variables |
| 60 | + |
| 61 | +```bash |
| 62 | +cd terraform |
| 63 | +cp terraform.tfvars.example terraform.tfvars |
| 64 | +``` |
| 65 | + |
| 66 | +Now edit `terraform.tfvars` with your values. Here's what I used: |
| 67 | + |
| 68 | +```hcl |
| 69 | +# AWS Configuration |
| 70 | +aws_region = "us-east-1" |
| 71 | +
|
| 72 | +# Project Configuration |
| 73 | +project_name = "laravel-blog" |
| 74 | +
|
| 75 | +# Application Configuration |
| 76 | +app_env = "production" |
| 77 | +app_debug = "false" |
| 78 | +app_key = "base64:YOUR_GENERATED_APP_KEY_HERE" # Generate this with: php artisan key:generate --show |
| 79 | +
|
| 80 | +# Database Configuration |
| 81 | +db_name = "laravel_blog" |
| 82 | +db_username = "laraveluser" |
| 83 | +db_password = "YourSecurePassword123!" # Make this strong! |
| 84 | +
|
| 85 | +# Elasticsearch Configuration |
| 86 | +opensearch_master_user = "admin" |
| 87 | +opensearch_master_password = "YourSecureElasticsearchPassword123!" |
| 88 | +
|
| 89 | +# ECS Configuration |
| 90 | +app_cpu = "512" |
| 91 | +app_memory = "1024" |
| 92 | +app_count = 1 |
| 93 | +``` |
| 94 | + |
| 95 | +### 4. Deploy the Infrastructure |
| 96 | + |
| 97 | +This is where the magic happens: |
| 98 | + |
| 99 | +```bash |
| 100 | +# Initialize Terraform (first time only) |
| 101 | +terraform init |
| 102 | + |
| 103 | +# See what Terraform will create |
| 104 | +terraform plan |
| 105 | + |
| 106 | +# Deploy everything to AWS |
| 107 | +terraform apply |
| 108 | +``` |
| 109 | + |
| 110 | +### 5. Build and Deploy Your Application |
| 111 | + |
| 112 | +```bash |
| 113 | +# Build the Docker image (make sure it's for the right architecture!) |
| 114 | +docker build --platform linux/amd64 -f docker/php/Dockerfile.prod -t laravel-blog-app:latest . |
| 115 | + |
| 116 | +# Push to AWS ECR |
| 117 | +aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $(terraform output -raw ecr_repository_url) |
| 118 | + |
| 119 | +docker tag laravel-blog-app:latest $(terraform output -raw ecr_repository_url):latest |
| 120 | +docker push $(terraform output -raw ecr_repository_url):latest |
| 121 | + |
| 122 | +# Update the ECS service |
| 123 | +aws ecs update-service --cluster laravel-blog-cluster --service laravel-blog-service --force-new-deployment --region us-east-1 |
| 124 | +``` |
| 125 | + |
| 126 | +## 🔧 Running Database Migrations |
| 127 | + |
| 128 | +Here's something I learned the hard way - you need to run migrations separately. Create a new ECS task with the same task definition and override the command in Container overrides: |
| 129 | + |
| 130 | +```bash |
| 131 | +php artisan migrate |
| 132 | +``` |
| 133 | + |
| 134 | +Launch the task, wait for it to complete, then stop it. Your database will be ready! |
| 135 | + |
| 136 | +## To generate local task_definition |
| 137 | + |
| 138 | +```bash |
| 139 | +terraform apply -auto-approve -target=local_file.task_definition |
| 140 | +``` |
| 141 | + |
| 142 | + |
| 143 | +Here's something I learned the hard way - you need to run migrations separately. Create a new ECS task with the same task definition and override the command in Container overrides: |
| 144 | + |
| 145 | +```bash |
| 146 | +php artisan migrate |
| 147 | +``` |
| 148 | + |
| 149 | +## 🤖 Setting Up CI/CD (The Cool Part!) |
| 150 | + |
| 151 | +I set up GitHub Actions to automatically deploy when I push code. Here's what you need to do: |
| 152 | + |
| 153 | +### Add These Secrets to Your GitHub Repository |
| 154 | + |
| 155 | +Go to **Settings** → **Secrets and variables** → **Actions** → **New repository secret** |
| 156 | + |
| 157 | +| Secret Name | What to Put | Why You Need It | |
| 158 | +|------------|-------------|-----------------| |
| 159 | +| `AWS_ACCESS_KEY_ID` | Your AWS Access Key | For GitHub to access AWS | |
| 160 | +| `AWS_SECRET_ACCESS_KEY` | Your AWS Secret Key | Authentication | |
| 161 | +| `AWS_REGION` | `us-east-1` | Which AWS region | |
| 162 | +| `ECR_REPOSITORY` | `laravel-blog-app` | Your container repository | |
| 163 | +| `ECS_SERVICE` | `laravel-blog-service` | Your ECS service name | |
| 164 | +| `ECS_CLUSTER` | `laravel-blog-cluster` | Your ECS cluster name | |
| 165 | +| `CONTAINER_NAME` | `laravel-app` | Container name in task definition | |
| 166 | + |
| 167 | +### What Happens Automatically |
| 168 | + |
| 169 | +Once you set this up, every time you push to the main branch: |
| 170 | +- ✅ Tests run automatically |
| 171 | +- ✅ Docker image builds |
| 172 | +- ✅ Pushes to ECR |
| 173 | +- ✅ Updates ECS service |
| 174 | +- ✅ Zero downtime deployment! |
| 175 | + |
| 176 | +## 🏗️ What Gets Created in AWS |
| 177 | + |
| 178 | +When you run Terraform, here's what you'll get: |
| 179 | + |
| 180 | +**Core Infrastructure:** |
| 181 | +- VPC with public/private subnets (security first!) |
| 182 | +- ECS Fargate cluster (no servers to manage) |
| 183 | +- RDS MySQL database with automated backups |
| 184 | +- ElastiCache Redis for caching and queues |
| 185 | +- Elasticsearch domain for search functionality |
| 186 | +- Application Load Balancer with health checks |
| 187 | +- S3 bucket for file storage |
| 188 | +- ECR repository for your Docker images |
| 189 | + |
| 190 | +**Security & Monitoring:** |
| 191 | +- CloudWatch log groups (you'll thank me later) |
| 192 | +- IAM roles with minimal permissions |
| 193 | +- Security groups that actually secure things |
| 194 | +- Encryption everywhere (RDS, Redis, Elasticsearch) |
| 195 | + |
| 196 | +## 🎨 What the Blog Can Do |
| 197 | + |
| 198 | +**For Users:** |
| 199 | +- Read blog posts with beautiful, responsive design |
| 200 | +- Search through posts (thanks to Elasticsearch!) |
| 201 | +- Browse by categories |
| 202 | +- Fast loading (Redis caching works wonders) |
| 203 | + |
| 204 | +**For Admins:** |
| 205 | +- Create, edit, and delete posts |
| 206 | +- Manage categories |
| 207 | +- User authentication system |
| 208 | +- Admin dashboard |
| 209 | + |
| 210 | +**Under the Hood:** |
| 211 | +- Background job processing |
| 212 | +- Automatic database migrations |
| 213 | +- Comprehensive error logging |
| 214 | +- Performance optimizations |
| 215 | + |
| 216 | +## 🐳 Docker Development |
| 217 | + |
| 218 | +Want to develop locally? I've got you covered: |
| 219 | + |
| 220 | +```bash |
| 221 | +# Start everything with Docker Compose |
| 222 | +docker-compose up -d |
| 223 | + |
| 224 | +# Run migrations in the container |
| 225 | +docker-compose exec app php artisan migrate |
| 226 | +``` |
| 227 | + |
| 228 | +## 🔍 My Learning Journey |
| 229 | + |
| 230 | +### Challenges I Faced |
| 231 | + |
| 232 | +1. **Docker Architecture Issues** - Learned the hard way about ARM64 vs x86_64 compatibility |
| 233 | +2. **Database Connectivity** - Security groups were confusing at first |
| 234 | +3. **Elasticsearch Setup** - The configuration took several attempts |
| 235 | +4. **ECS Task Definitions** - Understanding CPU/memory allocation was tricky |
| 236 | + |
| 237 | + |
| 238 | +## 🚨 When Things Go Wrong |
| 239 | + |
| 240 | +**ECS Task Failing?** |
| 241 | +```bash |
| 242 | +aws logs get-log-events --log-group-name "/ecs/laravel-blog" --log-stream-name <stream-name> |
| 243 | +``` |
| 244 | + |
| 245 | +**Database Issues?** |
| 246 | +- Check security group rules |
| 247 | +- Verify RDS endpoint in environment variables |
| 248 | +- Make sure your password is correct! |
| 249 | + |
| 250 | +**Docker Build Problems?** |
| 251 | +- Always use `--platform linux/amd64` for AWS |
| 252 | +- Check if Docker daemon is running |
| 253 | + |
| 254 | +## 🎯 What's Next? |
| 255 | + |
| 256 | +Some ideas for improvements: |
| 257 | +1. Add CloudFront for faster static assets |
| 258 | +2. Implement auto-scaling based on traffic |
| 259 | +3. Set up proper SSL certificates |
| 260 | +4. Add more comprehensive monitoring |
| 261 | +5. Create staging environment |
| 262 | + |
| 263 | +## 💝 Why I'm Sharing This |
| 264 | + |
| 265 | +I spent weeks figuring this out, reading documentation, debugging issues, and learning from mistakes. If this helps someone else on their AWS/Terraform journey, it was all worth it! |
0 commit comments