feat: Major system improvements and production deployment
✨ New Features: - Added view_orders route with proper table display - Implemented CSV upload with preview workflow and date parsing - Added production WSGI server configuration with Gunicorn - Created comprehensive production management scripts 🔧 Bug Fixes: - Fixed upload_data route column mapping for actual CSV structure - Resolved print module database queries and template rendering - Fixed view orders navigation routing (was pointing to JSON API) - Corrected barcode display width constraints in print module - Added proper date format parsing for MySQL compatibility 🎨 UI/UX Improvements: - Updated view_orders template with theme-compliant styling - Hidden barcode text in print module preview for cleaner display - Enhanced CSV upload with two-step preview-then-save workflow - Improved error handling and debugging throughout upload process 🚀 Production Infrastructure: - Added Gunicorn WSGI server with proper configuration - Created systemd service for production deployment - Implemented production management scripts (start/stop/status) - Added comprehensive logging setup - Updated requirements.txt with production dependencies 📊 Database & Data: - Enhanced order_for_labels table compatibility - Fixed column mappings for real CSV data structure - Added proper date parsing and validation - Improved error handling with detailed debugging 🔧 Technical Debt: - Reorganized database setup documentation - Added proper error handling throughout upload workflow - Enhanced debugging capabilities for troubleshooting - Improved code organization and documentation
This commit is contained in:
72
py_app/gunicorn.conf.py
Normal file
72
py_app/gunicorn.conf.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# Gunicorn Configuration File for Trasabilitate Application
|
||||
# Production-ready WSGI server configuration
|
||||
|
||||
import multiprocessing
|
||||
import os
|
||||
|
||||
# Server socket
|
||||
bind = "0.0.0.0:8781"
|
||||
backlog = 2048
|
||||
|
||||
# Worker processes
|
||||
workers = multiprocessing.cpu_count() * 2 + 1
|
||||
worker_class = "sync"
|
||||
worker_connections = 1000
|
||||
timeout = 30
|
||||
keepalive = 2
|
||||
|
||||
# Restart workers after this many requests, to prevent memory leaks
|
||||
max_requests = 1000
|
||||
max_requests_jitter = 50
|
||||
|
||||
# Logging
|
||||
accesslog = "/srv/quality_recticel/logs/access.log"
|
||||
errorlog = "/srv/quality_recticel/logs/error.log"
|
||||
loglevel = "info"
|
||||
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'
|
||||
|
||||
# Process naming
|
||||
proc_name = 'trasabilitate_app'
|
||||
|
||||
# Daemon mode (set to True for production deployment)
|
||||
daemon = False
|
||||
|
||||
# User/group to run worker processes
|
||||
# user = "www-data"
|
||||
# group = "www-data"
|
||||
|
||||
# Preload application for better performance
|
||||
preload_app = True
|
||||
|
||||
# Enable automatic worker restarts
|
||||
max_requests = 1000
|
||||
max_requests_jitter = 100
|
||||
|
||||
# SSL Configuration (uncomment if using HTTPS)
|
||||
# keyfile = "/path/to/ssl/private.key"
|
||||
# certfile = "/path/to/ssl/certificate.crt"
|
||||
|
||||
# Security
|
||||
limit_request_line = 4094
|
||||
limit_request_fields = 100
|
||||
limit_request_field_size = 8190
|
||||
|
||||
def when_ready(server):
|
||||
"""Called just after the server is started."""
|
||||
server.log.info("Trasabilitate Application server is ready. Listening on: %s", server.address)
|
||||
|
||||
def worker_int(worker):
|
||||
"""Called just after a worker exited on SIGINT or SIGQUIT."""
|
||||
worker.log.info("Worker received INT or QUIT signal")
|
||||
|
||||
def pre_fork(server, worker):
|
||||
"""Called just before a worker is forked."""
|
||||
server.log.info("Worker spawned (pid: %s)", worker.pid)
|
||||
|
||||
def post_fork(server, worker):
|
||||
"""Called just after a worker has been forked."""
|
||||
server.log.info("Worker spawned (pid: %s)", worker.pid)
|
||||
|
||||
def worker_abort(worker):
|
||||
"""Called when a worker received the SIGABRT signal."""
|
||||
worker.log.info("Worker received SIGABRT signal")
|
||||
Reference in New Issue
Block a user