Building a Cloud-Ready Expense Tracker: My Spring Boot, Docker & AWS EC2 Journey
I set out to build Treso, a secure and modern expense tracking REST API. I wanted to go beyond simple CRUD apps and dive deep into real-world backend engineering practices including secure authentication, containerization, and deploying to the cloud. This post is a summary of my key learnings and insights not a step-by-step tutorial. If you’re curious about the code, check out my GitHub repo here. 💡 Why This Project? Practice professional backend skills: Not just code that “works,” but code that’s production-ready and maintainable. Experiment with modern Spring Boot features: Security, validation, OpenAPI docs, metrics. Learn cloud deployment: Run my app on AWS EC2 like real-world services. Master Docker: Build once, run anywhere, test with real databases. 🌱 Learnings from Spring Boot 1. Secure Authentication with JWT Spring Security isn’t just about “login” it’s a whole framework for role-based access, request filtering, and best practices. Implementing JWT taught me about: Stateless session management Custom authentication filters Using @ControllerAdvice for clean error responses 2. Data Validation and Exception Handling Using Bean Validation (@Valid, @NotNull, etc.) makes your API more robust and self-documenting. A single global exception handler gives clients clear, consistent error messages no more scattered try/catch blocks. 3. Building for Scale and Maintainability DTOs and service layers are worth it, even in a small app. Using JPA with clear entity relationships (user ↔ expenses) made future feature expansion (analytics, sharing, etc.) much easier. 🐳 Docker: Development and Deployment Multi-stage Dockerfiles are a game changer: fast, clean images without leftover build tools. Environment variables (12-factor style) let me use the same image everywhere from local dev to cloud. Running both the app and Postgres in containers (with Docker Compose) gave me confidence my code would “just work” anywhere. Tip: Debugging Docker networking taught me a lot about how containers talk to each other localhost inside a container is not the same as on your laptop! ...