Files
bus-manager/README.md
T

4.2 KiB

Bus Manager

A Django-based bus coordination and management system. Handles transport scheduling, traveller management, location tracking, coordinator workflows, and optional SMS (Telstra) and SSO (Azure AD) integrations.


Stack

Component Technology
Web framework Django 6 + Gunicorn
Database PostgreSQL 16
Auth (optional) Azure AD SSO via MSAL
SMS (optional) Telstra Messaging API
Scheduling django-crontab (nightly coordinator check)
Container runtime Docker + Docker Compose

Deployment

Prerequisites

  • Docker and Docker Compose installed on the host
  • A reverse proxy (e.g. Nginx Proxy Manager) to front the app

1. Clone the repository

git clone https://gitea.hideawaygaming.com.au/jessikitty/bus-manager.git
cd bus-manager

2. Configure environment

cp .env.example .env

Edit .env and set at minimum:

Variable Description
SECRET_KEY Long random string — generate with python -c "import secrets; print(secrets.token_urlsafe(50))"
SQL_PASSWORD Postgres password (picked up by both the db and web containers)
ALLOWED_HOSTS Space-separated list of hostnames the app will be served from (e.g. busmanager.yourdomain.com)
APP_PORT Host port Gunicorn will be exposed on (default: 8000)

Optional variables for email, Azure SSO, and Telstra SMS are documented in .env.example.

3. Build and start

docker compose up -d --build

On first start the web container will:

  1. Wait for Postgres to pass its healthcheck
  2. Run manage.py migrate to initialise the database schema
  3. Run manage.py collectstatic to gather static assets
  4. Register the nightly cron job via manage.py crontab add
  5. Start Gunicorn on port 8000

4. Create a superuser

docker compose exec web python manage.py createsuperuser

5. Reverse proxy (Nginx Proxy Manager)

Create a new proxy host in NPM pointing to:

http://<docker-host-ip>:<APP_PORT>

Enable SSL via Let's Encrypt as usual. No special headers required — Gunicorn handles WSGI directly.


Updating

git pull
docker compose up -d --build

Migrations run automatically on startup, so schema changes are applied without manual intervention.


Useful commands

Task Command
View logs docker compose logs -f web
Open Django shell docker compose exec web python manage.py shell
Run migrations manually docker compose exec web python manage.py migrate
Check crontab docker compose exec web python manage.py crontab show
Restart app only docker compose restart web
Stop everything docker compose down
Stop and wipe database docker compose down -v ⚠️ destructive

Environment variables reference

Variable Required Default Description
SECRET_KEY Django secret key
DEBUG False Enable Django debug mode
ALLOWED_HOSTS localhost Space-separated allowed hostnames
SQL_DATABASE busmanager Postgres database name
SQL_USER busmanager Postgres username
SQL_PASSWORD Postgres password
APP_PORT 8000 Host port for Gunicorn
GUNICORN_WORKERS 3 Number of Gunicorn worker processes
GUNICORN_TIMEOUT 120 Gunicorn worker timeout (seconds)
EMAIL_HOST SMTP relay hostname
EMAIL_PORT 25 SMTP relay port
AZURE_CLIENT_ID Azure app client ID (enables SSO)
AZURE_CLIENT_SECRET Azure app client secret
AZURE_REDIRECT_URI Azure OAuth redirect URI
AZURE_AUTHORITY Azure authority URL
TELSTRA_CLIENT_ID Telstra API client ID (enables SMS)
TELSTRA_CLIENT_SECRET Telstra API client secret

Data persistence

Two named Docker volumes are created automatically:

  • postgres_data — PostgreSQL data directory
  • static_files — collected Django static assets

These survive docker compose down and are only removed with docker compose down -v.