The project includes a complete Docker Compose setup for easy deployment and development with version 3.0 configuration | WebSocket | Live reloading. With Django backend and React frontend styled with Tailwind CSS.
- Django 5.2+ - π Web framework
- Django REST Framework - π§ API development
- Django Channels - π‘ WebSocket support
- Daphne - π ASGI server for WebSockets
- Redis - πΎ Channel layer backend
- Simple JWT - π Authentication
- Pillow - πΌοΈ Image processing
- React 18+ - π¨ UI library
- Vite 7.0+ - β‘ Build tool and dev server
- Tailwind CSS - π Styling framework
- Framer Motion - π¬ Animations
- Axios - π¬ HTTP client
- React Router - πΊοΈ Navigation
- JWT Decode - π Token handling
- PostgreSQL (production) or SQLite (development) - π Database
- Redis - π‘ WebSocket channel layer & caching
- WhiteNoise - π Static file serving
- Docker - π³ Containerization platform
- Docker Compose 3.0 - π§ Multi-container orchestration
- Nginx - π Reverse proxy and load balancer
- Alpine Linux - ποΈ Lightweight container base images
- π Python 3.13+
- π’ Node.js 16+ and npm
- π΄ Redis server (for WebSocket channel layer)
- π Git
- π³ Docker Engine 20.0+
- π§ Docker Compose 3.0+
- π Git
π LR 3.0/
βββ π§ pyproject.toml # Python dependencies & project config
βββ π uv.lock # Dependency lock file
βββ π README.md # Project documentation
βββ π backend/ # Django application
β βββ ποΈ db.sqlite3 # Development database
β βββ βοΈ manage.py # Django CLI
β βββ π api/ # Main API app
βββ π frontend/ # React application
βββ π¦ package.json # Node.js dependencies
βββ β‘ vite.config.js # Vite configuration
βββ π¨ tailwind.config.js # Tailwind setup
git clone https://github.com/kevinThulnith/devops-project.git
# Go to project directory
cd devops-project
# Go to main branch
git checkout main
- Create
.env
file inbackend/
directory and add this configuration:
DEBUG=True
REDIS_PORT=6379
REDIS_HOST=127.0.0.1
DATABASE_URL=sqlite:///db.sqlite3
SECRET_KEY="your_secret_key_here_generate_a_secure_one"
- Redis Installation Required: Install Redis on your local device for WebSocket functionality
# If uv is not installed locally
pip install uv
# Install Python dependencies
uv sync
# Activate virtual environment (Windows PowerShell)
.\.venv\Scripts\Activate.ps1
# Navigate to backend directory
cd backend
# Run database migrations
py .\manage.py migrate
# Start backend server with Daphne (ASGI server)
daphne -b 0.0.0.0 -p 8000 backend.asgi:application
# Alternative: If virtual environment not activated
uv run daphne -b 0.0.0.0 -p 8000 backend.asgi:application
# Install Node.js dependencies
cd frontend
npm i
# Start development server with hot reload
npm run dev
# Create production build files
npm run build
# Start with network access (accessible from other devices)
npm run host
A test HTML file (ws_test.html
) is included for WebSocket testing:
- π Start the Django server
- π Open
ws_test.html
in a browser - β Create/update/delete products in Django Admin
- π See real-time updates in the test page
For a complete containerized deployment with all services, check out the docker-compose
branch which includes:
- π Backend Container: Django application with PostgreSQL support
- βοΈ Frontend Container: React application served with Nginx
- π PostgreSQL Database: Fully configured database container
- π Nginx Proxy: Load balancer and reverse proxy
- π΄ Redis Server: Cache and WebSocket channel layer
-
π Prerequisites:
- Docker Engine 20.0+
- Docker Compose 3.0+
-
βοΈ Environment Configuration:
Create a
.env.prod
file in the project root:# Database Configuration POSTGRES_DB=devops_inventory POSTGRES_USER=devops_user POSTGRES_PASSWORD=your_secure_password DATABASE_URL=postgresql://devops_user:your_secure_password@lr-database:5432/devops_inventory # Django Configuration DEBUG=False DJANGO_SECRET_KEY=your-super-secret-key-here ALLOWED_HOSTS=localhost,127.0.0.1,lr-backend # Redis Configuration REDIS_HOST=lr-redis REDIS_PORT=6379
-
πββοΈ Start All Services:
# Change branch git checkout docker-compose # In root dir docker-compose up -d
-
π Check Service Status:
docker-compose ps
- Frontend Application: http://localhost (via Nginx proxy)
- Backend API: http://localhost/api/ (via Nginx proxy)
- Django Admin: http://localhost/admin/ (via Nginx proxy)
- PostgreSQL Database: localhost:5432
- Redis Cache: localhost:6379
Service | Description | Image/Build | Ports | Dependencies |
---|---|---|---|---|
lr-proxy | π Nginx reverse proxy | nginx:1.25-alpine-slim |
80:80 | frontend, backend |
lr-frontend | βοΈ React application | Custom build | 5173:5173 | - |
lr-backend | π Django API server | Custom build | 8000:8000 | database, redis |
lr-database | π PostgreSQL database | postgres:14-alpine |
5432:5432 | - |
lr-redis | π§ Redis cache & pub/sub | redis:7-alpine |
6379:6379 | - |
- π¦ Product Management: CRUD operations for inventory items with image uploads
- β‘ Real-time Updates: Live WebSocket connections for instant product changes
- π User Authentication: JWT-based auth with automatic token refresh
- π± Responsive UI: Modern React interface with Tailwind CSS and Framer Motion animations
- π Advanced Filtering: Search, category filtering, and sorting capabilities
- π‘οΈ Custom JWT WebSocket Middleware: Secure WebSocket authentication using JWT tokens
- π‘ Django Signals Integration: Automatic real-time notifications on model changes
- π§ Protected Routes: Client-side route protection with automatic redirects
- πΌοΈ Image Handling: Product image uploads with media file management
- π CORS Support: Configured for cross-origin frontend-backend communication
- π³ Full Docker Containerization: Complete multi-container setup with Docker Compose 3.0
- π Nginx Reverse Proxy: Load balancing and SSL termination ready
- π¦ Multi-stage Builds: Optimized Docker images for production deployment
- π§ Environment Configuration: Separate configurations for development and production
- π Service Orchestration: Automated service dependency management
- πΎ Persistent Data Volumes: Configured volumes for database and Redis data persistence
- π Health Checks: Container health monitoring and automatic restarts
- π Network Isolation: Secure inter-service communication via Docker networks
Method | Endpoint | Description | Authentication |
---|---|---|---|
POST |
/api/user/register/ |
User registration | β Public |
POST |
/api/token/ |
User login (get JWT token) | β Public |
POST |
/api/token/refresh/ |
Refresh JWT token | π Required |
POST |
/api/token/blacklist/ |
Logout (blacklist token) | π Required |
GET |
/api/user/ |
Get current user info | π Required |
GET |
/api/products/ |
List all products | π Required |
POST |
/api/products/ |
Create new product | π Required |
GET |
/api/products/{id}/ |
Get product details | π Required |
PUT |
/api/products/{id}/ |
Update product (full) | π Required (Owner only) |
PATCH |
/api/products/{id}/ |
Update product (partial) | π Required (Owner only) |
DELETE |
/api/products/{id}/ |
Delete product | π Required (Owner only) |
GET |
/api/products/my_products/ |
Get current user's products | π Required |
The /api/products/
endpoint supports advanced filtering:
Parameter | Description | Example |
---|---|---|
search |
Search in name and description | ?search=laptop |
category |
Filter by category | ?category=electronics |
is_active |
Filter by active status | ?is_active=true |
ordering |
Sort by fields | ?ordering=-created_at |
Available Categories: books
, other
, sports
, clothing
, home
, electronics
Sortable Fields: name
, price
, quantity
, created_at
(use -
prefix for descending)
Endpoint | Description | Authentication |
---|---|---|
/ws/products/ |
Real-time product updates | π JWT Required |
// User Registration
const registerResponse = await fetch("/api/user/register/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: "newuser",
password: "securepassword",
email: "[email protected]",
}),
});
// User Login (Get JWT Token)
const loginResponse = await fetch("/api/token/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "user", password: "pass" }),
});
const tokens = await loginResponse.json();
// Response: { "access": "...", "refresh": "..." }
// Get Current User Info
const userInfo = await fetch("/api/user/", {
headers: { Authorization: `Bearer ${tokens.access}` },
});
// Create Product with Image
const productData = {
name: "Gaming Laptop",
description: "High-performance gaming laptop with RGB keyboard",
price: 1299.99,
quantity: 5,
category: "electronics",
is_active: true,
};
const formData = new FormData();
Object.keys(productData).forEach((key) => {
formData.append(key, productData[key]);
});
// Add image file
formData.append("image", imageFile);
const createResponse = await fetch("/api/products/", {
method: "POST",
headers: { Authorization: `Bearer ${tokens.access}` },
body: formData,
});
// Search Products
const searchResponse = await fetch(
"/api/products/?search=laptop&category=electronics&ordering=-created_at",
{
headers: { Authorization: `Bearer ${tokens.access}` },
}
);
// Get My Products Only
const myProductsResponse = await fetch("/api/products/my_products/", {
headers: { Authorization: `Bearer ${tokens.access}` },
});
// Refresh Token
const refreshResponse = await fetch("/api/token/refresh/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ refresh: tokens.refresh }),
});
// Logout (Blacklist Token)
const logoutResponse = await fetch("/api/token/blacklist/", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${tokens.access}`,
},
body: JSON.stringify({ refresh: tokens.refresh }),
});
Problem | Solution |
---|---|
π« Redis connection failed | Install and start Redis server locally |
ποΈ Database migration errors | Run python manage.py migrate --run-syncdb |
π JWT authentication fails | Check SECRET_KEY in .env file |
π Static files not loading | Run python manage.py collectstatic |
π CORS errors | Verify CORS_ALLOWED_ORIGINS in settings |
Problem | Solution |
---|---|
π¦ npm install fails | Delete node_modules and package-lock.json , then retry |
β‘ Vite dev server won't start | Check if port 5173 is available |
π API connection refused | Ensure backend is running on port 8000 |
π¨ Tailwind styles not applying | Run npm run build to regenerate CSS |
Problem | Solution |
---|---|
π³ Container build fails | Check Docker is running and has sufficient resources |
π Services can't communicate | Verify Docker network configuration |
π Database connection fails | Check environment variables in .env.prod |
πΎ Volume mount errors | Ensure proper file permissions |
# Check backend logs
docker-compose logs lr-backend
# Check database connection
python manage.py dbshell
# Test WebSocket connection
# Open browser console and run:
# const ws = new WebSocket('ws://localhost:8000/ws/products/');
# Check Redis connection
redis-cli ping
# Verify environment variables
docker-compose config
- Database Indexing: Add indexes to frequently queried fields
- Query Optimization: Use
select_related()
andprefetch_related()
- Caching: Implement Redis caching for frequently accessed data
- Image Optimization: Compress uploaded images automatically
- Code Splitting: Implement React lazy loading for routes
- Image Optimization: Use WebP format and responsive images
- Bundle Analysis: Use
npm run build -- --analyze
to check bundle size - Service Worker: Implement PWA features for offline support
- JWT Authentication with automatic token refresh
- CORS Configuration for cross-origin requests
- Input Validation on all API endpoints
- File Upload Security with type and size restrictions
- Environment Variables for sensitive configuration
# Generate secure SECRET_KEY
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
# Set strong database passwords
openssl rand -base64 32
# Enable HTTPS in production
# Update ALLOWED_HOSTS and SECURE_* settings
- Django Admin:
/admin/
- Administrative interface - API Root:
/api/
- API endpoint listing - DRF Browsable API:
/api-auth/
- Interactive API browser
# Test database connection
cd backend
python manage.py dbshell
# Test Redis connection (if Redis is running)
redis-cli ping
# Check Django application
curl http://localhost:8000/api/
# Test WebSocket connection
# Open browser console and run:
# const ws = new WebSocket('ws://localhost:8000/ws/products/');
π Logs/
βββ π Django: /app/logs/django.log
βββ π Nginx: /var/log/nginx/
βββ π³ Docker: docker-compose logs [service_name]
βββ π΄ Redis: /var/log/redis/redis-server.log
We welcome contributions! Please follow these steps:
-
π΄ Fork the repository
-
πΏ Create a feature branch
git checkout -b feature/amazing-feature
-
π» Make your changes
-
β Run tests
# Backend tests cd backend python manage.py test # Frontend tests (if available) cd frontend npm test
-
π Commit your changes
git commit -m "Add: Amazing new feature"
-
π Push to your branch
git push origin feature/amazing-feature
-
π Open a Pull Request
- Python: Follow PEP 8 standards
- JavaScript: Use ESLint configuration provided
- Commit Messages: Use conventional commit format
feat:
for new featuresfix:
for bug fixesdocs:
for documentation changesstyle:
for formatting changesrefactor:
for code refactoring
- Write unit tests for new features
- Ensure all existing tests pass
- Test WebSocket functionality manually
- Verify Docker deployment works
- π§ Email: [[email protected]]
- π Issues: GitHub Issues
- π‘ Discussions: GitHub Discussions
- Django Documentation: https://docs.djangoproject.com/
- React Documentation: https://react.dev/
- Docker Documentation: https://docs.docker.com/
- Tailwind CSS: https://tailwindcss.com/docs
This project is licensed under the MIT License - see the LICENSE file for details.
- β Commercial use allowed
- β Modification allowed
- β Distribution allowed
- β Private use allowed
- β No warranty provided
- β No liability assumed
- Django Team for the amazing web framework
- React Team for the powerful UI library
- Tailwind CSS for the utility-first CSS framework
- Docker for containerization technology
- Redis for real-time functionality
- All Contributors who helped improve this project
π Happy Coding! If you found this project helpful, please give it a β star on GitHub!