A self-hosted help desk for K-12 technology teams. The application uses a Django/PostgreSQL backend, three separately exposed portal origins, local accounts, configurable Gmail delivery, and role-based access.
- Staff portal with email-verified requester accounts, remembered building/room, ticket history, replies, and attachments
- Guest portal for infrequent unauthenticated requests with private ticket links and rate limiting
- Technician portal with queues, per-technician unread-message indicators, assignments, statuses, public replies, internal notes, service alerts, and attachment handling
- Searchable submit on behalf of workflow restricted by security group
- Filtered aggregate reports with CSV export and no requester details
- Gmail SMTP or Workspace relay for confirmations, threaded replies, status changes, assignments, new-ticket technician alerts, and service alerts
- Optional Gmail IMAP worker that imports valid requester and assigned-technician email replies into ticket conversations while removing quoted Gmail history
- Administration-managed buildings, issue types/details, conditional device choices, users, groups, alerts, and mail configuration
-
Copy
.env.exampleto.envand replace every prototype secret. -
Start the stack:
docker-compose up -d --build
-
Create the first global administrator:
docker-compose exec web python manage.py createsuperuser -
Open the portals:
- Staff: http://localhost:8788
- Technician and Administration: http://localhost:8789
- Guest: http://localhost:8790
Health check: http://localhost:8788/healthz
Application access is managed through these Django groups:
- Help Desk Requesters — eligible requester accounts; verified self-service accounts join automatically
- Help Desk Request on Behalf — add-on permission for staff who may submit for another requester
- Help Desk Technicians — ticket, reply, alert, and assignment operations
- Help Desk Report Viewers — read-only aggregate reporting
- Help Desk Administrators — help-desk configuration and account administration
Admin-created users are intentionally not assigned a help-desk role automatically. Assign the appropriate group under Administration → Users. Reserve Django superuser status for global administrators.
Gmail can be configured entirely through Administration → Email configuration. The saved credential is encrypted at rest. Configure the public staff/technician URLs before sending production messages so ticket buttons point to the correct hostnames.
See docs/GMAIL-SETUP.md for Gmail SMTP, Workspace relay, inbound IMAP, and credential-key guidance.
- Put real values in the ignored
.env; never deploy with the Compose fallback database password or Django secret. - Set
COOKIE_SECURE=truewhen the public portals are HTTPS-only. - Keep the technician hostname behind an identity-aware proxy such as Cloudflare Access in addition to application login.
- The three Nginx origins deliberately expose different API surfaces. Preserve that separation when adding reverse-proxy hostnames.
- Normal startup never creates sample tickets. Run
python manage.py seed_demomanually only in disposable demo environments. - Portal proxies dynamically re-resolve the web service, and Compose waits for its health check before starting dependent services.
- Docker JSON logs rotate at 10 MB with five retained files per container.
- Back up the
postgres_dataandmedia_dataDocker volumes.
docker-compose exec -T web python manage.py test
docker-compose exec -T web python manage.py check
docker-compose exec -T web python manage.py makemigrations --check --dry-run- Password-reset email is not implemented yet; administrators must reset passwords.
- Inventory/device-system integration is intentionally deferred.
- Guest access should be monitored and can be placed behind additional edge abuse controls before a broad public launch.
See docs/AUTH-AND-MAIL.md for the trust and account model.