You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Then start the dev stack - on first run this will build the containers, run migrations, load the HC schema, and collect static files:
dev/start.sh
Dev Scripts
All developer scripts live in dev/ and can be run from the repo root.
Script
Description
dev/lib.sh
Library script to autodetech compose engine, make sure the engine is running, and check if the web stack is running.
dev/start.sh
Start the dev stack. Detects first run and handles setup automatically.
dev/update.sh
Pull latest changes, rebuild image if dependencies changed, and run migrations.
dev/lock.sh
Regenerate uv lockfile inside the dev container. Defaults to all three. --upgrade upgrades all packages; --upgrade-package pkg upgrades a single package across all files.
dev/reset.sh [--clean] [--force]
Tear down volumes and restart. --clean also removes built images forcing a full Docker rebuild. --force skips the confirmation prompt.
dev/shell.sh [bash|django|db]
Open a shell in the web container: bash (default), django (Django shell), db (dbshell).
dev/lint.sh [dir]
Run ruff across all Python files (or a specific app directory).
dev/logs.sh [service]
Tail logs for a service (web default; also worker, beat, db, redis).
dev/migrate.sh [app]
Run pending migrations (all apps, or a specific one).
dev/makemigrations.sh [app]
Create migrations for model changes (all apps, or a specific one). Passes through any extra Django args (e.g. --check).
dev/runtests.sh [--fresh] [target]
Run tests and format output as a GitHub-ready markdown comment. --fresh drops and recreates the test DB first.
dev/coverage.sh [app]
Run tests with coverage and print a full coverage report sorted by worst coverage first.
Run tests, push branch, and open a PR with test results embedded in the body. Aborts if tests fail. Requires gh. Defaults to dev as the base branch.
Running Tests
# Run all tests
dev/runtests.sh
# Run a single app's tests
dev/runtests.sh ffdonations
# Run a specific test class or method
dev/runtests.sh ffdonations.tests.TeamAdminSyncDonationsTest
dev/runtests.sh ffdonations.tests.TeamAdminSyncDonationsTest.test_queues_task_for_each_selected_team
Or use Django directly:
docker compose exec web uv run python manage.py test
podman compose exec web uv run python manage.py test
Useful Commands
Inside the container (dev/shell.sh):
uv run python manage.py shell # Django shell
uv run python manage.py dbshell # Postgres shell
uv run python manage.py migrate # Run migrations
uv run python manage.py collectstatic --no-input
Environment Variables
Copy env.sample to .env to get started. All optional variables have sensible defaults — only set them if you need to override.
Required
Variable
Description
SECRET_KEY
Django secret key (generate with python -c "import secrets; print(secrets.token_urlsafe(50))")
Redis
Variable
Default
Description
REDIS_URL
redis://localhost
Single Redis instance (split across DB indexes 0-4)
REDIS0_URL-REDIS4_URL
-
Override individual Redis DB URLs (default, tasks, tombs, timers, cache)
Discord OAuth2
Variable
Default
Description
DISCORD_CLIENT_ID
-
OAuth2 app client ID
DISCORD_CLIENT_SECRET
-
OAuth2 app client secret
DISCORD_GUILD_ID
164136635762606081
Required guild; users not in this guild are denied login
Discord Bot
Variable
Default
Description
DISCORD_BOT_TOKEN
-
Bot token for role sync and slash commands
ADD_DISCORD_COMMANDS
true
Set to false to start the bot without registering slash commands
Default wait (seconds) between retries if no Retry-After header
Twitch Bot Integration
Variable
Default
Description
FRAG_BOT_API
https://bot.fragforce.org/dbquery
Twitch bot API endpoint
FRAG_BOT_KEY
-
API key
FRAG_BOT_BOT
misterfragbot
Bot username
Donations
Variable
Default
Description
SINGAPORE_DONATIONS
0.0
Manual donation adjustment (SGD region)
OTHER_DONATIONS
0.0
Manual donation adjustment (other)
TARGET_DONATIONS
1.0
Donation goal override
SEND_MISSED_DONATIONS
10
Minutes of missed donations to re-announce
Streaming
Variable
Default
Description
STREAM_URL
-
Stream URL
STREAM_DASH_BASE
https://stream.fragforce.org
DASH stream server base URL
Django / Performance
Variable
Default
Description
DEBUG
True
Django debug mode
DJANGO_LOG_LEVEL
INFO
Log level
MAX_API_ROWS
1024
Max rows returned by API endpoints
GOOGLE_ANALYTICS_ID
-
GA tracking ID
MAX_UPCOMING_EVENTS
20
Max upcoming events shown
MAX_PAST_EVENTS
20
Max past events shown
DOCKER
False
Use Docker database config
DOCKER_PROD
False
Use Docker production database config
View Cache Timeouts (seconds)
Variable
Default
VIEW_TEAMS_CACHE
20
VIEW_PARTICIPANTS_CACHE
20
VIEW_DONATIONS_CACHE
20
VIEW_DONATIONS_STATS_CACHE
20
VIEW_SITE_EVENT_CACHE
60
VIEW_SITE_SITE_CACHE
60
VIEW_SITE_STATIC_CACHE
300
See env.sample for a commented template of all variables.
Managing Dependencies
Dependencies are declared in pyproject.toml and locked in one file:
File
Used by
pyproject.toml
All dependencies, including dev and ci only dependencies
uv.lock
UV Lockfile containing exact package versions, hashes, and upload dates
To regenerate lockfile after editing pyproject.toml:
dev/lock.sh # regenerate the lockfile
All packages will be re-evaulated from the constraints contained in pyproject.toml and versions that match those contstraints will be updated in uv.lock, verify all changes before committing.
After regenerating, rebuild containers to pick up changes: