A high-performance, production-ready full-stack Todo application built with Drogon C++ Framework for the backend, Next.js 15 for the frontend, and PostgreSQL as the database. Features include JWT authentication, RESTful API, Docker containerization, and Kubernetes deployment with CI/CD pipeline.
- Features
- Tech Stack
- Architecture
- Prerequisites
- Installation & Setup
- API Documentation
- Deployment
- Project Structure
- Contributing
- License
- 🚀 High-Performance: Built with Drogon, one of the fastest C++ web frameworks
- 🔐 JWT Authentication: Secure token-based authentication with bcrypt password hashing
- 📝 CRUD Operations: Complete Todo management (Create, Read, Update, Delete)
- 🗄️ PostgreSQL Integration: Robust ORM support with Drogon's built-in mapper
- 🛡️ Custom Middleware: Authentication filters and error handling
- 🌐 CORS Support: Pre-configured CORS for frontend integration
- 🏥 Health Check: Built-in health monitoring endpoint
- 📦 Docker Ready: Multi-stage builds for optimized production images
- ⚡ Next.js 15: Latest React framework with Turbopack
- 🎨 Modern UI: Tailwind CSS with Radix UI components
- 🔄 Real-time Updates: Seamless todo management interface
- 🎯 Type-Safe: Full TypeScript implementation
- 📱 Responsive Design: Mobile-first approach
- 🐳 Docker & Docker Compose: Containerized development and production
- ☸️ Kubernetes Ready: Complete K8s manifests with Ingress
- 🔄 CI/CD Pipeline: Jenkins integration with automated builds
- 📊 ArgoCD: GitOps-based continuous deployment
- 🔒 Secrets Management: Kubernetes secrets for sensitive data
- Framework: Drogon v1.9.0 (C++20)
- Database: PostgreSQL 15
- Authentication: JWT-CPP, Bcrypt.cpp
- ORM: Drogon ORM
- Build System: CMake 3.5+
- Framework: Next.js 15.2.4
- Language: TypeScript 5
- Styling: Tailwind CSS 4
- UI Components: Radix UI, Lucide Icons
- HTTP Client: Axios
- Containerization: Docker, Docker Compose
- Orchestration: Kubernetes
- CI/CD: Jenkins, ArgoCD
- Ingress: NGINX Ingress Controller
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Next.js │────────▶│ Drogon C++ │────────▶│ PostgreSQL │
│ Frontend │ HTTP │ Backend │ ORM │ Database │
│ (Port 3000)│ │ (Port 3001) │ │ (Port 5432) │
└─────────────┘ └──────────────┘ └──────────────┘
│ │
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ Docker │ │ Kubernetes │
│ Compose │ │ Cluster │
└─────────────┘ └──────────────┘
- Docker (20.10+)
- Docker Compose (2.0+)
- C++20 compiler (GCC 10+/Clang 10+/MSVC 2019+)
- CMake (3.5+)
- PostgreSQL (15+)
- Drogon Framework (v1.9.0)
- Node.js (20+) - only if working on the frontend
my-fastest-drogon-app-cpp/
├── CMakeLists.txt
├── config.json
├── config.docker.json
├── Dockerfile # production (multi-stage)
├── Dockerfile.dev # development image with entrypoint
├── docker-compose.yml # postgres service (API optional)
├── db.dockerfile # builds DB image seeded with init.sql
├── init.sql # DB schema (users, todos)
├── Jenkinsfile # CI pipeline: build, push, retag k8s, push changes
├── scripts/
│ └── dev-entrypoint.sh
├── src/
│ ├── main.cc
│ ├── controllers/
│ │ ├── api_v1_User.{h,cc}
│ │ ├── api_v1_todos.{h,cc}
│ │ └── api_v1_health.{h,cc}
│ ├── filters/
│ │ ├── auth.{h,cc}
│ │ └── CorsMiddleware.{h,cc}
│ ├── models/
│ │ ├── Users.{h,cc}
│ │ ├── Todos.{h,cc}
│ │ └── model.json
│ └── utils/
│ ├── AppError.{h,cc}
│ └── token.{h,cc}
├── k8s/
│ ├── namespace.yaml
│ ├── ingress.yaml
│ ├── app/
│ │ ├── deployment.yaml
│ │ ├── secret.yaml
│ │ └── svc.yaml
│ └── db/
│ ├── deployment.yaml
│ ├── pv.yaml
│ ├── pvc.yaml
│ ├── secrets.yaml
│ └── svc.yaml
└── dependencies/ # vendored jwt-cpp, Bcrypt (used via CMake)
Note: Folders build/
, pgdata/
, uploads/
excluded. Frontend has its own README in frontend/
.
Two configs are provided; Drogon auto-loads config.json
from the working directory.
config.json
(local): connects to127.0.0.1:5432
config.docker.json
(containers): connects to servicepostgres
Example (local config.json
):
{
"listeners": [{ "address": "0.0.0.0", "port": 3001 }],
"db_clients": [{
"rdbms": "postgresql",
"host": "127.0.0.1",
"port": 5432,
"dbname": "userdb",
"user": "postgres",
"password": "postgres",
"is_fast": false
}]
}
JWT secret (required by src/utils/token.cc
):
- Local/dev: set environment variable
JWT_SECRET
- Kubernetes: provided through
k8s/app/secret.yaml
(key:jwt_secret
)
-
Start PostgreSQL with Docker Compose
docker-compose up -d postgres
-
Build and run the application
docker build -t drogon-app:latest -f Dockerfile . docker run --rm -p 3001:3001 -e JWT_SECRET=your-secret-key drogon-app:latest
-
Install Drogon (build from source v1.9.0 as shown in
setup.md
) -
Build the application
mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Debug cmake --build . -j
-
Setup database and run
# Ensure PostgreSQL is running and load the schema psql -h 127.0.0.1 -U postgres -d userdb -f ../init.sql # Set JWT secret and run $Env:JWT_SECRET="your-secret-key-here" .\my_drogon_app.exe
Backend will read
config.json
and listen on port 3001.
Base URL: http://localhost:3001/api/v1
- POST
/User/signup
— Register (name, email, password) → returns JWT - POST
/User/login
— Login (email, password) → returns JWT - GET
/User/profile
— Get user profile (requiresAuthorization: Bearer <token>
)
- POST
/todos/create
— Create todo{ title, completed }
- GET
/todos/getAll
— List all todos for authenticated user - GET
/todos/{id}
— Get single todo by ID - GET
/todos/getAll/{completion}
— Filter todos by completion status (true/false) - PUT
/todos/update/{id}
— Update todo{ title, completed }
- DELETE
/todos/delete/{id}
— Delete todo
- GET
/health/
— Service status
CORS is handled globally in src/main.cc
and via CorsMiddleware
.
-
Create namespace
kubectl apply -f k8s/namespace.yaml
-
Deploy PostgreSQL database
kubectl apply -f k8s/db/
-
Deploy application
kubectl apply -f k8s/app/
-
Setup Ingress
kubectl apply -f k8s/ingress.yaml
-
Verify deployment
kubectl get pods -n drogon-project kubectl get svc -n drogon-project kubectl get ingress -n drogon-project
Jenkins Pipeline (Jenkinsfile
):
- Validates parameters (requires
BACKEND_DOCKER_TAG
) - Cleans workspace and clones repository
- Builds Docker image and pushes to Docker Hub (requires
dockerhubCredentials
) - Updates
k8s/app/deployment.yaml
image tag - Commits changes back to repository (requires
Github-Cred
)
ArgoCD: Helper scripts and documentation in k8s/
for GitOps-style continuous deployment.
src/utils/token.cc
readsJWT_SECRET
from environment variable- ORM models are mapped in
src/models/*.cc
andmodel.json
(tables: users, todos) src/filters/auth.*
injectsuserId
andemail
into request parameters after JWT validationinit.sql
createsusers
andtodos
tables with foreign keys and timestamps
-
Define route in controller header (
src/controllers/api_v1_User.h
):METHOD_ADD(User::newEndpoint, "/newPath", Post, "auth"); void newEndpoint(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback);
-
Implement method (
src/controllers/api_v1_User.cc
):void User::newEndpoint(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) { try { auto json = req->getJsonObject(); // Your logic here Json::Value response; response["status"] = "success"; auto resp = HttpResponse::newHttpJsonResponse(response); callback(resp); } catch (const std::exception &e) { auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k500InternalServerError); resp->setBody(e.what()); callback(resp); } }
-
Rebuild and test:
cd build cmake --build . -j .\my_drogon_app.exe
-
Update database schema (
init.sql
):CREATE TABLE new_table ( id SERIAL PRIMARY KEY, field1 VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
-
Update model configuration (
src/models/model.json
):{ "tables": ["users", "todos", "new_table"] }
-
Generate model classes:
drogon_ctl create model src/models/model.json
-
Update CMakeLists.txt to include the new model source files and rebuild
-
Port Already in Use
# Find and stop the process using port 3001 Get-Process -Id (Get-NetTCPConnection -LocalPort 3001).OwningProcess | Stop-Process
-
Database Connection Failed
- Ensure PostgreSQL is running
- Check database credentials in
config.json
- Verify database exists:
psql -h localhost -U postgres -d userdb
-
Build Errors
- Ensure Drogon is properly installed
- Check CMake version:
cmake --version
- Verify C++20 compiler support
-
Docker Issues
# Reset Docker containers docker-compose down -v docker-compose up -d
- Fork the repository
- Create a feature branch:
git checkout -b feature-name
- Make your changes and test thoroughly
- Commit:
git commit -m 'Add feature'
- Push:
git push origin feature-name
- Submit a pull request
MIT License © 2025 Suryansh Verma - see LICENSE file for details.
- Drogon Framework - High-performance C++ web framework
- PostgreSQL - Robust database system
- JWT-CPP - JWT token library
- BCrypt - Password hashing
Built with ❤️ using C++20 and Drogon Framework