A modern, full-featured news content management system built with React, Flask, and PostgreSQL. This portfolio project demonstrates professional web development practices including role-based access control, media management, and containerized deployment.
π Live Demo: https://lankalive.himanmanduja.fun/
This CMS platform enables administrators to create, edit, and manage news content with a clean, responsive interface. Currently configured for single admin use, the architecture is designed to scale for multiple users with different permission levels.
- Admin Dashboard: Secure login system with JWT authentication for content management
- Rich Content Editor: Create and edit articles with media uploads and categorization
- Responsive Design: Modern UI built with React 18 and Tailwind CSS 4
- Search & Filter: Advanced search functionality with date range filtering
- Media Management: Inline image uploads with automatic optimization
- Role-Based Access: Secure admin-only content management (scalable to multi-user system)
- Production Ready: Dockerized deployment with Nginx, Gunicorn, and PostgreSQL
- Scalable Design: Built with multi-user capability in mind - easily extendable for team content management
- Separation of Concerns: Clean MVC architecture with DAOs, services, and controllers
- Modern Stack: React 18 + Vite 7, Flask 3.0, PostgreSQL 16, Docker Compose
- CI/CD Pipeline: Automated deployment via GitHub Actions
- Flask 3.0.0
- SQLAlchemy 2.0.23
- PostgreSQL 15
- JWT Authentication (PyJWT 2.8.0)
- Pillow 10.1.0 for image processing
- React 18
- Vite 7
- React Router v6
- Tailwind CSS 4
- PostgreSQL 16-alpine
- Python 3.12-slim
- Node 20-alpine + Nginx-alpine (multi-stage build)
- β Article management with rich text editor
- β Category and tag organization
- β Media asset management with inline upload
- β Search functionality with debouncing (500ms)
- β Date filtering
- β Featured articles display
- β Latest news page with pagination
- β Role-based access control (Admin/Public)
- β Professional error pages (404, Unauthorized)
- β Privacy Policy and Terms of Service pages
- Node.js 20+
- Python 3.12+
- PostgreSQL 15
- npm or yarn
- Copy the example environment file:
Copy-Item .env.example .env- Update
.envwith your local database credentials:
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/lankalive
DEV=true
DOMAIN=
FLASK_ENV=development
SECRET_KEY=your-secret-key-here
JWT_SECRET=your-jwt-secret-here
- Create the database:
psql -U postgres -c "CREATE DATABASE lankalive;"- Initialize schema:
psql -U postgres -d lankalive -f sql_script/init_schema.sql- (Optional) Load sample data:
psql -U postgres -d lankalive -f sql_script/sample_data.sqlcd backend
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r requirements.txt
python run.pyBackend will run on http://localhost:8000
cd frontend
npm install
npm run devFrontend will run on http://localhost:5173
- Copy and configure environment:
Copy-Item .env.example .env- Update
.envfor Docker deployment:
DEV=false
DOMAIN=yourdomain.com # or leave empty for localhost
SECRET_KEY=generate-a-strong-secret-key
JWT_SECRET=generate-a-strong-jwt-secret
- Build and run:
docker-compose build
docker-compose up -d- Access the application:
- Frontend: http://localhost:8080
- Backend API: http://localhost:8080/api (proxied internally)
The docker-compose stack includes:
-
PostgreSQL (postgres:15-alpine)
- Internal port: 5432
- Automatically initializes with
init_schema.sqlandsample_data.sql - Persistent storage via
postgres_datavolume - Health checks enabled
-
Backend (Python 3.12-slim)
- Internal port: 8000
- Connects to postgres container via internal network
- Mounts
./backend/staticfor media uploads - Health checks on
/api/healthendpoint
-
Frontend (Nginx-alpine)
- External port: 8080
- Internal port: 80
- Serves built React SPA
- Configured for SPA routing
- Gzip compression and caching enabled
# Build all containers
docker-compose build
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop all services
docker-compose down
# Stop and remove volumes (WARNING: deletes database)
docker-compose down -v
# Rebuild specific service
docker-compose build backend
docker-compose up -d backend
# Access container shell
docker-compose exec backend bash
docker-compose exec postgres psql -U postgres -d lankalive| Variable | Description | Local Dev | Docker/VPS |
|---|---|---|---|
DATABASE_URL |
PostgreSQL connection string | postgresql://postgres:postgres@localhost:5433/lankalive |
Auto-configured |
DEV |
Development mode flag | true |
false |
DOMAIN |
Domain for VPS deployment | `` (empty) | yourdomain.com |
FLASK_ENV |
Flask environment | development |
production |
SECRET_KEY |
Flask secret key | Any value | Strong random key |
JWT_SECRET |
JWT signing secret | Any value | Strong random key |
The backend uses the DEV flag to determine database connection:
- DEV=true: Uses
DATABASE_URLfrom.envfile (local PostgreSQL) - DEV=false: Auto-configures to use Docker postgres container (
postgresql://postgres:postgres@postgres:5432/lankalive)
This project includes automated deployment via GitHub Actions. Every push to main branch automatically deploys to your VPS.
-
Add GitHub Secrets (Settings β Secrets and variables β Actions):
- See
SECRETS.mdfor the complete list of required secrets - Generate keys:
python -c "import secrets; print(secrets.token_hex(32))"
- See
-
Prepare VPS (one-time setup):
# Install Docker curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh apt install docker-compose -y # Clone repository git clone https://github.com/HimanM/Lankalive-Clone.git cd Lankalive-Clone # Open port 8080 ufw allow 8080/tcp
-
Deploy:
- Push to
mainbranch, or - Go to Actions tab β Run workflow
- Push to
-
Access:
http://your-domain-or-ip:8080
π Full Documentation: See DEPLOYMENT.md for detailed instructions and troubleshooting.
- Clone repository on VPS:
git clone https://github.com/HimanM/Lankalive-Clone.git
cd Lankalive-Clone- Configure environment:
cp .env.example .env
nano .envUpdate .env:
DEV=false
DOMAIN=yourdomain.com
FLASK_ENV=production
SECRET_KEY=<generate-strong-key>
JWT_SECRET=<generate-strong-key>
POSTGRES_PASSWORD=<strong-password>
- Generate secure keys:
# Generate SECRET_KEY
python3 -c "import secrets; print(secrets.token_hex(32))"
# Generate JWT_SECRET
python3 -c "import secrets; print(secrets.token_hex(32))"- Build and deploy:
docker compose build
docker compose up -d- Verify deployment:
# Check containers
docker compose ps
# Test backend
curl http://localhost:8000/api/health
# Test through frontend proxy
curl http://localhost:49155/api/articles- Access application:
- Frontend: http://your-vps-ip:49155
- Backend API: http://your-vps-ip:8000 (for testing)
- Gunicorn WSGI Server: 4 worker processes for production performance
- Nginx Proxy: Frontend Nginx proxies
/api/and/static/to backend - No CORS Issues: All requests are same-origin
- Docker Volumes: Database and media uploads persist across deployments
# 1. Check all services are up
docker compose ps
# 2. View logs
docker compose logs -f
# 3. Test individual services
docker compose logs backend -f
docker compose logs frontend -f
docker compose logs postgres -f
# 4. Test API endpoint
curl http://localhost:49155/api/articleslankalive/
βββ backend/
β βββ controllers/ # Route handlers
β βββ services/ # Business logic
β βββ daos/ # Database access layer
β βββ models/ # SQLAlchemy models
β βββ utils/ # Helper functions
β βββ static/uploads/ # Media storage
β βββ Dockerfile # Backend container
β βββ requirements.txt # Python dependencies
β βββ run.py # Entry point
βββ frontend/
β βββ src/
β β βββ components/ # React components
β β βββ pages/ # Page components
β β βββ App.jsx # Main app component
β βββ Dockerfile # Frontend container
β βββ nginx.conf # Nginx configuration
β βββ package.json # Node dependencies
βββ sql_script/
β βββ init_schema.sql # Database schema
β βββ sample_data.sql # Sample data
βββ docker-compose.yml # Docker orchestration
βββ .env # Environment variables (not in git)
βββ .env.example # Environment template
βββ README.md # This file
GET /api/articles- List all published articlesGET /api/articles/:id- Get article detailsGET /api/categories- List all categoriesGET /api/latest-news- Get latest news articles
POST /api/auth/login- Admin loginPOST /api/articles- Create articlePUT /api/articles/:id- Update articleDELETE /api/articles/:id- Delete articlePOST /api/media- Upload mediaPOST /api/categories- Create category
Issue: Port 8080 already in use
# Find process using port 8080
netstat -ano | findstr :8080
# Kill process by PID
taskkill /PID <pid> /FIssue: Database connection refused
# Check postgres container health
docker-compose ps
docker-compose logs postgres
# Verify postgres is running
docker-compose exec postgres pg_isready -U postgresIssue: Frontend can't connect to backend
- Verify
VITE_API_URLin docker-compose.yml points tohttp://backend:8000 - Check backend health:
docker-compose logs backend - Verify network:
docker network inspect lankalive_lankalive_network
Issue: Database connection error
- Verify PostgreSQL is running on port 5433
- Check credentials in
.envmatch your local setup - Ensure database
lankaliveexists
Issue: Frontend can't connect to backend API
- Verify backend is running on http://localhost:8000
- Check CORS configuration in backend
- Verify
VITE_API_URLin frontend environment
Portfolio project by: hghimanmanduja@gmail.com
This is a portfolio clone project created for educational purposes. It is not affiliated with the original "Lanka Live" website and is clearly branded as "Lanka Live Clone" throughout the application.
MIT License - See LICENSE file for details.
This project is open source and available for educational purposes.