BytesBlogs is a high-performance, full-stack blogging application tailored for developers. It features a modern React Single Page Application (SPA) frontend and a secure, robust Spring Boot backend. Authors can write posts in Markdown with live syntax highlighting, organize content via categories and tags, upload images to Cloudinary, sign in with Google OAuth2 or OTP-verified email verification, and administrators can manage users and posts using a sleek analytics-enabled dashboard.
- Key Features
- Architecture Overview
- Technology Stack
- Project Directory Map
- Local Development Setup
- Environment Configurations
- Dockerization Guide
- Unified Production Build (Topology A)
- Postman Integration Testing
- Secure Sessions & Auth: JWT authentication utilizing secure, stateless HTTP-Only cookies for robust cross-site scripting (XSS) and cross-site request forgery (CSRF) protection.
- OTP & OAuth2 Sign-In: Supports single-click Google Sign-In as well as password-less logins via secure OTP (One-Time Password) codes sent straight to the user's inbox.
- Markdown Editor: Real-time parsed Markdown view enabling developers to write technical posts with instant preview and syntax highlighting for major programming languages.
- Cloud Storage: Seamless media upload handling directly integrated with Cloudinary for fast CDN-driven image delivery.
- Admin Console: Access statistical oversight graphs (users growth, category counts, top stories) and role control centers to manage post moderation and users accounts.
- Interactions: Built-in views, likes, and comment threads for maximum community engagement.
The following diagram illustrates the network flow and service communication:
graph TD
Client[React SPA Client - Vite] <-->|HTTP / CORS / JWT| API[Spring Boot REST API]
API <-->|Spring Security / Filter Chain| Auth[JWT & OAuth2 Client]
API <-->|Spring Data JPA| DB[(MySQL Database)]
API --->|SMTP Protocol| Email[Brevo / SMTP Service]
API --->|Cloudinary API| Cloud[Cloudinary Image Storage]
├── frontend/ # React Frontend Application
│ ├── public/ # Static assets & favicons
│ ├── src/
│ │ ├── components/ # UI components (Header, Footer, LogoBug)
│ │ ├── context/ # React contexts (Auth, Theme)
│ │ ├── pages/ # Page views (Auth, BlogDetail, Admin Console)
│ │ ├── services/ # HTTP client APIs
│ │ └── App.jsx # Routing and modal coordination
│ ├── tailwind.config.js # Styles design token configuration
│ └── package.json # Frontend dependency manifest
│
└── spring-backend/ # Spring Boot Backend REST Service
├── src/main/java/com/blogapp/
│ ├── controller/ # REST Controllers (Auth, Blogs, Comments)
│ ├── dto/ # Request & Response Data Objects (DTOs)
│ ├── model/ # JPA Entity Definitions
│ ├── repository/ # Spring Data JPA Repository interfaces
│ ├── security/ # Spring Security, JWT validation filters
│ └── service/ # Logic implementations
├── src/main/resources/
│ ├── application.yaml # Main environment configurations
│ └── application-dev.yaml # Dev configurations (with environment overrides)
├── Dockerfile # Multi-stage containerization build file
├── postman_collection.json # Integrated API testing collection
└── pom.xml # Maven build dependencies config
- Java: JDK 25 installed
- NodeJS: Version 18 or higher (along with npm)
- Database: MySQL Server instance running locally
- Create a MySQL database instance named
blog_db:CREATE DATABASE blog_db;
- Navigate to
spring-backend/src/main/resourcesand configure your credentials insideapplication-dev.yaml. - Start the Spring Boot application using the wrapper:
cd spring-backend ./mvnw spring-boot:run
- Navigate to the
frontendfolder:cd frontend - Install npm dependencies:
npm install
- Start the Vite server:
npm run dev
- Open your browser to
http://localhost:5173. Vite is pre-configured to proxy API requests to your local backend on port8080.
For deployments or container overrides, configure the variables listed below:
| Variable Name | Description | Default / Example |
|---|---|---|
PORT |
Backend server port | 8080 |
DB_URL |
MySQL Connection URL | jdbc:mysql://localhost:3306/blog_db |
DB_USERNAME |
Database username | root |
DB_PASSWORD |
Database password | your_mysql_password |
JWT_SECRET |
256-bit Base64 JWT Secret Key | Generate a secure random string |
JWT_EXPIRATION |
JWT token expiration time (in ms) | 86400000 (1 day) |
GOOGLE_CLIENT_ID |
Google Console OAuth Client ID | your-google-client-id |
GOOGLE_CLIENT_SECRET |
Google Console OAuth Client Secret | your-google-client-secret |
GOOGLE_REDIRECT_URI |
Google OAuth redirect URI override | http://localhost:8080/login/oauth2/code/google |
MAIL_HOST |
SMTP Server Host Address | smtp.gmail.com or Brevo SMTP |
MAIL_PORT |
SMTP Server Connection Port | 587 |
MAIL_USERNAME |
Mailer account username | example@gmail.com |
MAIL_PASSWORD |
Mailer account SMTP password / app password | your-app-password |
MAIL_FROM |
Origin mail address for notifications | no-reply@bytesblogs.com |
CLOUDINARY_CLOUD_NAME |
Cloudinary Account Cloud Name | your-cloud-name |
CLOUDINARY_API_KEY |
Cloudinary API Key | your-api-key |
CLOUDINARY_API_SECRET |
Cloudinary API Secret Key | your-api-secret |
FRONTEND_URL |
Frontend client origin (CORS/Redirects) | http://localhost:5173 |
Navigate to your spring-backend directory and compile the multi-stage image:
cd spring-backend
docker build -t blog-backend:latest .- Open Docker Desktop and navigate to the Images tab.
- Find
blog-backend:latestand click the blue Run button. - Click on Optional settings to configure variables:
- Container Name:
blog-backend-container - Ports: Map Host Port
8080to Container Port8080. - Environment Variables: Click the + (Add) button to supply:
DB_URL➡️jdbc:mysql://host.docker.internal:3306/blog_dbDB_USERNAME➡️rootDB_PASSWORD➡️your_mysql_password
- Container Name:
- Click Run. The app will launch and securely connect to the host MySQL database using the
host.docker.internalgateway loop.
For ease of hosting, compile the frontend assets directly inside the JAR to serve the app on a single unified port:
- Navigate to the frontend folder and build the assets:
cd frontend && npm run build
- Move static files to the Spring static resource directory:
cp -r dist/* ../spring-backend/src/main/resources/static/ - Compile the package JAR:
cd ../spring-backend ./mvnw clean package -DskipTests - Execute the JAR:
Your site will be fully accessible at
java -jar target/spring-backend-0.0.1-SNAPSHOT.jar
http://localhost:8080.
To test the API endpoints independently:
- Locate postman_collection.json in the
spring-backenddirectory. - Import it into Postman.
- Set the
baseUrlvariable tohttp://localhost:8080. - Run requests under the Auth folder (e.g. Register, Login, OTP confirmation) to verify JWT generation and stateless cookie authorization.