# TechDesk — IT Ticket System ## Complete Deployment & Implementation Guide --- ## Table of Contents 1. [Project Structure](#1-project-structure) 2. [Prerequisites](#2-prerequisites) 3. [Server Setup](#3-server-setup) 4. [MySQL Database Setup](#4-mysql-database-setup) 5. [Application Deployment](#5-application-deployment) 6. [Gunicorn Configuration](#6-gunicorn-configuration) 7. [Systemd Service](#7-systemd-service) 8. [Nginx Configuration](#8-nginx-configuration) 9. [SSL Certificate](#9-ssl-certificate) 10. [First Login & Admin Setup](#10-first-login--admin-setup) 11. [AI Chatbot Configuration](#11-ai-chatbot-configuration) 12. [Email Configuration](#12-email-configuration) 13. [Code Change Map](#13-code-change-map) 14. [Features Overview](#14-features-overview) 15. [Maintenance & Operations](#15-maintenance--operations) --- ## 1. Project Structure ``` it-ticket-system/ ├── run.py ← Flask entry point ├── gunicorn.conf.py ← Gunicorn worker config ├── it-ticket-system.service ← Systemd unit file ├── nginx.conf ← Nginx site config ├── setup_db.sql ← MySQL DB + user creation ├── requirements.txt ← Python dependencies ├── .env.example ← Environment variable template ├── config/ │ └── config.py ← Flask config classes (Dev/Prod) ├── app/ │ ├── __init__.py ← App factory, extension init, seed admin │ ├── models.py ← All SQLAlchemy models │ ├── routes/ │ │ ├── __init__.py │ │ ├── auth.py ← Login, register, logout, profile │ │ ├── tickets.py ← Ticket CRUD, comments, attachments │ │ ├── admin.py ← IT/admin management views │ │ ├── api.py ← JSON API + WebSocket events │ │ └── chatbot.py ← AI assistant endpoint │ ├── services/ │ │ ├── __init__.py │ │ ├── notification_service.py ← Email + in-app + WebSocket notifications │ │ └── log_service.py ← Activity log + ticket history helpers │ └── templates/ │ ├── base.html ← Sidebar, topbar, chat widget, JS │ ├── auth/ │ │ ├── login.html │ │ ├── register.html │ │ └── profile.html │ ├── tickets/ │ │ ├── dashboard_employee.html │ │ ├── dashboard_it.html │ │ ├── create.html │ │ ├── list.html │ │ ├── detail.html │ │ ├── notifications.html │ │ ├── knowledge_base.html │ │ └── kb_article.html │ └── admin/ │ ├── index.html │ ├── tickets.html │ ├── users.html │ ├── edit_user.html │ ├── kb_list.html │ ├── kb_edit.html │ └── activity_logs.html └── logs/ ← Created automatically at runtime ``` --- ## 2. Prerequisites On your **Ubuntu 22.04** server, ensure the following are installed: ```bash # Update system sudo apt update && sudo apt upgrade -y # Python 3.10+, pip, venv sudo apt install -y python3 python3-pip python3-venv python3-dev # MySQL Server sudo apt install -y mysql-server libmysqlclient-dev # Nginx sudo apt install -y nginx # Certbot (Let's Encrypt SSL) sudo apt install -y certbot python3-certbot-nginx # Build tools (needed for some pip packages) sudo apt install -y build-essential libssl-dev libffi-dev # (Optional) Git for deployment sudo apt install -y git ``` --- ## 3. Server Setup ### 3.1 Create Application User & Directory ```bash # Create a dedicated system user sudo useradd --system --no-create-home --shell /bin/false it-tickets # Create application directory sudo mkdir -p /var/www/it-ticket-system sudo chown it-tickets:www-data /var/www/it-ticket-system sudo chmod 755 /var/www/it-ticket-system ``` ### 3.2 Deploy Application Files ```bash # Option A: Clone from your Git repository sudo -u it-tickets git clone https://your-repo-url.git /var/www/it-ticket-system # Option B: Upload manually via scp scp -r ./it-ticket-system/* user@your-server:/var/www/it-ticket-system/ ``` ### 3.3 Create Python Virtual Environment ```bash cd /var/www/it-ticket-system sudo -u it-tickets python3 -m venv venv sudo -u it-tickets venv/bin/pip install --upgrade pip sudo -u it-tickets venv/bin/pip install -r requirements.txt ``` ### 3.4 Create Upload & Log Directories ```bash sudo -u it-tickets mkdir -p /var/www/it-ticket-system/app/static/uploads sudo -u it-tickets mkdir -p /var/www/it-ticket-system/logs # Ensure www-data (nginx) can read uploads sudo chown -R it-tickets:www-data /var/www/it-ticket-system/app/static/uploads sudo chmod -R 775 /var/www/it-ticket-system/app/static/uploads ``` --- ## 4. MySQL Database Setup ### 4.1 Secure MySQL Installation ```bash sudo mysql_secure_installation # Follow prompts: set root password, remove anonymous users, # disallow remote root login, remove test database. ``` ### 4.2 Create Database and User ```bash # Run the provided SQL setup script sudo mysql -u root -p < /var/www/it-ticket-system/setup_db.sql # Or manually: sudo mysql -u root -p <<'EOF' CREATE DATABASE IF NOT EXISTS it_tickets CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS 'it_tickets_user'@'localhost' IDENTIFIED BY 'YOUR_SECURE_PASSWORD'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, REFERENCES ON it_tickets.* TO 'it_tickets_user'@'localhost'; FLUSH PRIVILEGES; EOF ``` ### 4.3 Verify Connection ```bash mysql -u it_tickets_user -p it_tickets # Should connect without errors. Type \q to exit. ``` --- ## 5. Application Deployment ### 5.1 Configure Environment Variables ```bash # Copy the example env file sudo -u it-tickets cp /var/www/it-ticket-system/.env.example /var/www/it-ticket-system/.env # Edit with your actual values sudo nano /var/www/it-ticket-system/.env ``` **Critical values to change in `.env`:** ```ini # Generate a strong secret key: # python3 -c "import secrets; print(secrets.token_hex(32))" SECRET_KEY=your-generated-secret-key # Database — match what you set in setup_db.sql DB_PASSWORD=YOUR_SECURE_PASSWORD # Mail — your SMTP server credentials MAIL_SERVER=smtp.yourdomain.com MAIL_USERNAME=ittickets@yourdomain.com MAIL_PASSWORD=your-email-password IT_DEPT_EMAIL=it-department@yourdomain.com # Public URL of your app APP_BASE_URL=https://tickets.yourdomain.com # Anthropic API key for AI chatbot ANTHROPIC_API_KEY=sk-ant-... # Change default admin password ADMIN_EMAIL=admin@yourdomain.com ADMIN_PASSWORD=YourStrongAdminPassword! ``` ### 5.2 Initialize the Database The application automatically creates all tables and seeds the admin user on first startup. You can also trigger it manually: ```bash cd /var/www/it-ticket-system sudo -u it-tickets venv/bin/python -c " from app import create_app, db app = create_app('production') with app.app_context(): db.create_all() print('Database tables created successfully.') " ``` ### 5.3 Set File Permissions ```bash # Application files: readable by the app user sudo find /var/www/it-ticket-system -type f -exec chmod 644 {} \; sudo find /var/www/it-ticket-system -type d -exec chmod 755 {} \; sudo chmod 600 /var/www/it-ticket-system/.env sudo chown it-tickets:it-tickets /var/www/it-ticket-system/.env # Virtual environment executables sudo chmod +x /var/www/it-ticket-system/venv/bin/gunicorn sudo chmod +x /var/www/it-ticket-system/venv/bin/python ``` --- ## 6. Gunicorn Configuration The `gunicorn.conf.py` file at the project root controls the WSGI server. **Key settings explained:** | Setting | Value | Reason | |---|---|---| | `worker_class` | `eventlet` | Required for Flask-SocketIO WebSocket support | | `workers` | `1` | eventlet mandates a single worker | | `worker_connections` | `1000` | Max concurrent connections per worker | | `timeout` | `120` | Seconds before killing an unresponsive worker | | `bind` | `127.0.0.1:5000` | Internal only — nginx proxies publicly | **Test Gunicorn manually before enabling the service:** ```bash cd /var/www/it-ticket-system sudo -u it-tickets venv/bin/gunicorn --config gunicorn.conf.py run:app # You should see: [INFO] Listening at: http://127.0.0.1:5000 # Press Ctrl+C to stop. ``` --- ## 7. Systemd Service ### 7.1 Install the Service ```bash # Copy unit file to systemd sudo cp /var/www/it-ticket-system/it-ticket-system.service /etc/systemd/system/ # Edit to confirm paths and user match your setup sudo nano /etc/systemd/system/it-ticket-system.service ``` **Update these lines in the service file if needed:** ```ini User=it-tickets Group=www-data WorkingDirectory=/var/www/it-ticket-system EnvironmentFile=/var/www/it-ticket-system/.env ExecStart=/var/www/it-ticket-system/venv/bin/gunicorn \ --config gunicorn.conf.py \ run:app ``` ### 7.2 Enable and Start the Service ```bash sudo systemctl daemon-reload sudo systemctl enable it-ticket-system sudo systemctl start it-ticket-system # Verify it is running sudo systemctl status it-ticket-system ``` ### 7.3 Useful Service Commands ```bash # View live logs sudo journalctl -u it-ticket-system -f # Restart after code changes sudo systemctl restart it-ticket-system # Stop the service sudo systemctl stop it-ticket-system ``` --- ## 8. Nginx Configuration ### 8.1 Install Site Configuration ```bash # Copy nginx config sudo cp /var/www/it-ticket-system/nginx.conf /etc/nginx/sites-available/it-ticket-system # Edit: replace tickets.yourdomain.com with your actual domain sudo nano /etc/nginx/sites-available/it-ticket-system # Enable the site sudo ln -s /etc/nginx/sites-available/it-ticket-system /etc/nginx/sites-enabled/ # Remove default nginx site (optional) sudo rm -f /etc/nginx/sites-enabled/default # Test configuration syntax sudo nginx -t # Reload nginx sudo systemctl reload nginx ``` ### 8.2 Nginx Tuning (Optional) Add to `/etc/nginx/nginx.conf` inside the `http {}` block: ```nginx # Increase for large file uploads client_max_body_size 20M; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1000; gzip_types text/plain text/css application/json application/javascript text/xml; # Rate limiting limit_req_zone $binary_remote_addr zone=app:10m rate=30r/m; ``` --- ## 9. SSL Certificate ```bash # Obtain Let's Encrypt certificate sudo certbot --nginx -d tickets.yourdomain.com # Certbot will automatically update your nginx config with SSL settings. # Verify auto-renewal: sudo certbot renew --dry-run # The nginx.conf provided already has the SSL block commented out. # After certbot runs, it will populate the ssl_certificate paths automatically. ``` --- ## 10. First Login & Admin Setup 1. Open your browser: `https://tickets.yourdomain.com` 2. Log in with the credentials you set in `.env`: - **Email:** `admin@yourdomain.com` - **Password:** `YourStrongAdminPassword!` 3. **Change the admin password immediately** via Profile → Change Password. 4. Navigate to **Admin → Users** to create IT Staff accounts. 5. Set their role to `it_staff` or `admin`. ### Default Roles | Role | Capabilities | |---|---| | `employee` | Create tickets, add comments, view own tickets, use chatbot, read KB | | `it_staff` | All employee permissions + view/update all tickets, assign tickets, internal notes, manage KB | | `admin` | All IT staff permissions + manage users, view full activity logs, deactivate accounts | --- ## 11. AI Chatbot Configuration The chatbot uses the **Anthropic Claude API** (`claude-sonnet-4-20250514`). 1. Obtain an API key from [console.anthropic.com](https://console.anthropic.com) 2. Add to `.env`: ```ini ANTHROPIC_API_KEY=sk-ant-api03-... ``` 3. Restart the service: `sudo systemctl restart it-ticket-system` **Chatbot capabilities:** - Conversationally gathers issue details from employees - Automatically creates tickets with appropriate category and priority - Notifies IT staff immediately upon ticket creation - Answers general IT questions without creating tickets - Detects critical/urgent language and escalates priority accordingly If `ANTHROPIC_API_KEY` is not set, the chatbot gracefully informs users to contact IT directly — **the rest of the application continues to function normally.** --- ## 12. Email Configuration ### Gmail / Google Workspace ```ini MAIL_SERVER=smtp.gmail.com MAIL_PORT=587 MAIL_USE_TLS=True MAIL_USERNAME=ittickets@yourdomain.com MAIL_PASSWORD=your-app-password # Use App Password, not account password ``` ### Microsoft 365 / Outlook ```ini MAIL_SERVER=smtp.office365.com MAIL_PORT=587 MAIL_USE_TLS=True MAIL_USERNAME=ittickets@yourdomain.com MAIL_PASSWORD=your-password ``` ### Local Postfix (no external relay) ```ini MAIL_SERVER=localhost MAIL_PORT=25 MAIL_USE_TLS=False MAIL_USERNAME= MAIL_PASSWORD= ``` **Email notifications are sent for:** - New ticket created → IT Department email + all IT staff (in-app) - Ticket status changed → Ticket creator - Ticket assigned → Assigned IT staff member - New comment added → Ticket creator + assignee If email fails (wrong credentials, network issue), errors are **logged silently** — the ticket operation still succeeds. --- ## 13. Code Change Map This section documents every file and what was added/changed, as a reference for future modifications. ### New Files (All files are new — this is a greenfield application) | File | Purpose | Key Functions/Routes | |---|---|---| | `run.py` | Entry point | Starts Flask + SocketIO | | `config/config.py` | Environment config | `Config`, `DevelopmentConfig`, `ProductionConfig` | | `app/__init__.py` | App factory | `create_app()`, `_seed_admin()` | | `app/models.py` | Database models | `User`, `Ticket`, `Comment`, `Attachment`, `Notification`, `TicketHistory`, `ActivityLog`, `KnowledgeBase` | | `app/routes/auth.py` | Authentication | `GET/POST /auth/login`, `GET/POST /auth/register`, `GET /auth/logout`, `GET/POST /auth/profile` | | `app/routes/tickets.py` | Ticket management | `GET/POST /tickets/new`, `GET /tickets`, `GET/POST /tickets/`, `POST /tickets//update`, `POST /comments//delete`, `GET /attachments/`, `GET/POST /notifications`, `GET /kb`, `GET /kb/` | | `app/routes/admin.py` | Admin/IT views | `GET /admin/`, `GET /admin/tickets`, `GET /admin/users`, `GET/POST /admin/users//edit`, `POST /admin/users//delete`, KB CRUD, `GET /admin/logs` | | `app/routes/api.py` | JSON API + WebSocket | `GET /api/notifications/unread-count`, `POST /api/notifications//read`, `POST /api/notifications/mark-all-read`, `GET /api/stats/tickets`, Socket events: `connect`, `disconnect`, `join_ticket`, `leave_ticket` | | `app/routes/chatbot.py` | AI assistant | `POST /chatbot/message` | | `app/services/notification_service.py` | Notification delivery | `create_notification()`, `send_email()`, `notify_new_ticket()`, `notify_status_change()`, `notify_comment_added()`, `notify_assignment()` | | `app/services/log_service.py` | Audit logging | `log_action()`, `log_ticket_history()` | | `gunicorn.conf.py` | WSGI server config | eventlet worker, bind address, log paths | | `it-ticket-system.service` | Systemd unit | Auto-start, restart-on-failure | | `nginx.conf` | Reverse proxy | SSL termination, WebSocket upgrade, static file serving | | `setup_db.sql` | DB initialisation | Creates database, user, grants | ### Where Logging (`log_action`) Is Called | Event | File | Function | Log Action String | |---|---|---|---| | User login | `auth.py` | `login()` | `user_login` | | User registration | `auth.py` | `register()` | `user_register` | | User logout | `auth.py` | `logout()` | `user_logout` | | Profile update | `auth.py` | `profile()` | `user_profile_update` | | Ticket created | `tickets.py` | `create_ticket()` | `ticket_create` | | Ticket updated | `tickets.py` | `update_ticket()` | `ticket_update` | | Comment created | `tickets.py` | `ticket_detail()` | `comment_create` | | Comment deleted | `tickets.py` | `delete_comment()` | `comment_delete` | | Ticket created via chatbot | `chatbot.py` | `chat()` | `ticket_create_chatbot` | | Admin edits user | `admin.py` | `edit_user()` | `admin_user_edit` | | Admin deactivates user | `admin.py` | `delete_user()` | `admin_user_deactivate` | | KB article created | `admin.py` | `kb_new()` | `kb_create` | | KB article edited | `admin.py` | `kb_edit()` | `kb_edit` | | KB article deleted | `admin.py` | `kb_delete()` | `kb_delete` | --- ## 14. Features Overview ### Employee Features - **Dashboard** — open/active/resolved ticket counts, recent tickets, top KB articles - **Submit Ticket** — form with title, category, priority, location, asset tag, file attachments - **AI Chatbot** — floating chat widget (🤖 button, bottom-right); conversationally creates tickets - **Ticket Tracking** — full ticket detail with comment thread, change history, attachments - **Notifications** — real-time bell (WebSocket) + notification centre page - **Knowledge Base** — self-service articles before submitting a ticket - **Profile** — update name/department/phone, toggle email/web notifications, change password ### IT Staff Features - **IT Dashboard** — queue metrics (open/in-progress/pending/resolved), assigned tickets, recent activity - **All Tickets View** — filterable by status, priority, assignment (mine/unassigned/all) - **Ticket Update Panel** — change status, priority, assignee, due date, resolution notes, internal notes - **Internal Notes** — IT-only comments not visible to the employee - **Ticket History** — field-level change log on every ticket - **Knowledge Base Management** — create, edit, publish/unpublish, delete articles ### Admin Features - **User Management** — list all users, edit role/department/status, reset passwords, deactivate - **Activity Log** — full audit trail of all create/update/delete actions with IP addresses - **IT Overview** — aggregate stats across all tickets and users ### Technical Features - **Real-time WebSocket** — notifications pushed instantly via Flask-SocketIO / eventlet - **Email Notifications** — HTML emails for new tickets, status changes, comments, assignments - **File Attachments** — on tickets and comments; UUID-stored filenames prevent collisions - **Ticket Numbering** — sequential daily format: `TKT-20240315-0001` - **Audit Trail** — every significant action persisted to `activity_logs` + `ticket_history` - **AI Ticket Creation** — chatbot flags `ai_generated=True` on auto-created tickets --- ## 15. Maintenance & Operations ### Application Logs ```bash # Application logs (Flask) tail -f /var/www/it-ticket-system/logs/it_tickets.log # Gunicorn access log tail -f /var/www/it-ticket-system/logs/gunicorn_access.log # Gunicorn error log tail -f /var/www/it-ticket-system/logs/gunicorn_error.log # Systemd journal sudo journalctl -u it-ticket-system -f --since "1 hour ago" # Nginx logs sudo tail -f /var/log/nginx/it_tickets_access.log sudo tail -f /var/log/nginx/it_tickets_error.log ``` ### Deploying Code Updates ```bash cd /var/www/it-ticket-system # Pull latest code sudo -u it-tickets git pull origin main # Install any new dependencies sudo -u it-tickets venv/bin/pip install -r requirements.txt # Apply database migrations (if you add Flask-Migrate) # sudo -u it-tickets venv/bin/flask db upgrade # Restart the service sudo systemctl restart it-ticket-system sudo systemctl status it-ticket-system ``` ### Database Backup ```bash # Full backup mysqldump -u it_tickets_user -p it_tickets > backup_$(date +%Y%m%d_%H%M%S).sql # Automated daily backup via cron (add to root's crontab): # 0 2 * * * mysqldump -u it_tickets_user -pPASSWORD it_tickets | gzip > /backups/it_tickets_$(date +\%Y\%m\%d).sql.gz ``` ### Firewall Configuration ```bash sudo ufw allow 22/tcp # SSH sudo ufw allow 80/tcp # HTTP (redirects to HTTPS) sudo ufw allow 443/tcp # HTTPS sudo ufw deny 5000/tcp # Block direct Gunicorn access sudo ufw enable sudo ufw status ``` ### Troubleshooting Quick Reference | Symptom | Likely Cause | Fix | |---|---|---| | 502 Bad Gateway | Gunicorn not running | `sudo systemctl restart it-ticket-system` | | WebSocket not connecting | nginx missing upgrade headers | Verify `/socket.io/` location block in nginx.conf | | Emails not sending | SMTP credentials | Check `.env` MAIL_* values; test with `flask shell` | | Chatbot not responding | Missing API key | Set `ANTHROPIC_API_KEY` in `.env` and restart | | File uploads failing | Wrong permissions on uploads dir | `sudo chown -R it-tickets:www-data app/static/uploads` | | DB connection error | Wrong credentials | Verify `DB_*` values in `.env` match `setup_db.sql` | | Static files 404 | Wrong nginx alias | Check `alias` path in nginx `/static/` block |