This repository contains the backend API for codePost, built with Django.
- See
CHANGELOG.mdfor recent API changes and release notes.
| Branch | Purpose |
|---|---|
main |
Default branch. All feature work and PRs target here. Pushes auto-deploy to the dev server. |
release/* |
Cut from main via the "Create Release Branch" workflow. Deployed to production manually via deploy_production.yml. |
Versioning uses Conventional Commits and explicit version tags created during production deploys.
- When you deploy to production, you provide a version (e.g.,
3.4.0). The deploy workflow:- Deploys the release branch to production servers
- Creates a git tag (
v3.4.0) on the release branch - Creates a GitHub Release with auto-generated notes
- Triggers SDK regeneration in
codePost-uiandcodepost-python
All commits must follow the Conventional Commits format. This is enforced by CI on pull requests.
feat: add new rubric export endpoint → minor bump (3.2.0 → 3.3.0)
fix: correct permission check on courses → patch bump (3.2.0 → 3.2.1)
feat!: redesign submission model → major bump (3.2.0 → 4.0.0)
chore: update dependencies → no release
docs: update API documentation → no release
| Workflow | Trigger | What it does |
|---|---|---|
test_codepost.yml |
Push/PR to main, release/* |
Lint, typecheck, tests |
deploy_development.yml |
Push to main |
Deploy to dev server |
deploy_production.yml |
Manual trigger (specify branch + version) | Deploy to production, tag, GitHub Release, SDK sync |
release-branch.yml |
Manual trigger | Create release/* branch from main |
- Go to Actions → Create Release Branch → Run workflow (optionally specify version)
- A
release/X.Y.Zbranch is created frommain - Do final testing on the release branch (CI runs automatically)
- Go to Actions → Deploy to Production Server → Run workflow with
ref: release/X.Y.Zandversion: X.Y.Z - The workflow deploys, creates a version tag, GitHub Release, and triggers SDK regeneration
- Fix the bug on
mainfirst (via a normal PR) - Cherry-pick the fix onto the active
release/*branch - Go to Actions → Deploy to Production Server → Run workflow with the same release branch and an incremented patch version (e.g.,
3.4.1)
This README documents the current production deployment flow used for codePost with a multi-VM layout and docker-compose.
Primary services in this repo:
codepost-api: Django API servicecodepost-entry: Nginx TLS reverse proxy for APIcodepost-worker: Celery worker for background jobs/autogradingcodepost-worker-shell: worker-shell relay processcodepost-database: MariaDBcodepost-redis: Redis
Optional operational services:
codepost-flower: Celery monitoring UIadminer: database web UI
This is the fastest path for a new operator starting from zero.
Provision these VMs:
- Data VM
- Backend VM
- Worker VM
- Frontend VM
Install on each VM:
- Git
- Docker Engine
- Docker Compose plugin (
docker-composecommand) - Python 3 (for env generation script)
Also ensure:
- VM-to-VM connectivity is open for required ports (DB/Redis/API)
- DNS records are configured for API and frontend domains
On Data, Backend, and Worker VMs:
git clone https://github.com/rutgers-lcsr/codePost-api.git
cd codePost-apiOn Frontend VM:
git clone https://github.com/rutgers-lcsr/codePost-ui.git
cd codePost-uiCreate .env once in codePost-api/ (for example on Backend VM):
python3 ./scripts/create_env.pyThen copy the same .env to Data VM and Worker VM in their codePost-api/ folders.
Important values to confirm before deploy:
DB_HOSTNAMEpoints to the Data VM hostAPI_URLis your external API URL (example:https://api.example.edu)CLIENT_URLis your frontend URL (example:https://codepost.example.edu)WORKER_SHELL_SHARED_SECRETis identical on Backend + WorkerNFS_*values are set correctly if NFS-backed DB volume is enabled
In codePost-api/, place cert files:
certs/fullchain.pemcerts/privkey.pem
In codePost-ui/, create .env with:
REACT_APP_API_URL=https://api.yourdomain.comIn codePost-ui/, place cert files:
certs/fullchain.pemcerts/privkey.pem
On Data VM (codePost-api/):
docker-compose --env-file .env -f docker-compose-data.yml up -dOn Backend VM (codePost-api/):
docker-compose --env-file .env -f docker-compose-prod.yml up -d --buildOn Worker VM (codePost-api/):
docker-compose --env-file .env -f docker-compose-worker.yml up -d --buildOn Frontend VM (codePost-ui/):
docker-compose --env-file .env -f docker-compose.yml up -d --build- API health check:
https://<api-domain>/health-check - Frontend loads over HTTPS
- Login succeeds in UI
- Background jobs run successfully on worker
init.shauto-creates admin user fromAPI_USER/API_PASSWORD- Open Django admin at
https://<api-domain>/admin/ - Create Organization and link your profile
Current recommended topology:
- Data VM:
docker-compose-data.yml - Backend VM:
docker-compose-prod.yml - Worker VM:
docker-compose-worker.yml - Frontend VM: deployed from
codePost-ui(see README)
Use this order for first deploy and most restarts:
- Data VM
- Backend VM
- Worker VM
- Frontend VM
- Docker + Docker Compose plugin installed
- DNS / routing configured so VMs can reach each other
- TLS certificates available on API and UI hosts
- Host paths created where required:
HOST_DATASET_ROOT(default/mnt/datasets)/tmp/codepost-staging
Create a .env file in codePost-api/ using one of the following:
# Interactive (recommended)
python3 ./scripts/create_env.py
# Non-interactive defaults/placeholders
python3 ./scripts/create_env.py --non-interactive
# Backward-compatible wrapper still works
./scripts/create_env.shThe interactive flow will ask whether optional features should be activated (for example, NFS-backed DB volume and autograder auto-execution).
Or copy .env.example manually and edit values.
Required (or strongly recommended) fields for production:
DEBUG=False
SECRET_KEY=<secure_random_string>
FIELD_ENCRYPTION_KEY=<secure_random_key>
DB_HOSTNAME=<hostname_or_ip_of_data_vm_database_and_redis>
DB_NAME=codepost
DB_PASSWORD=<db_password>
ROOT_DATABASE_PASSWORD=<db_root_password>
API_USER=<initial_admin_username>
API_PASSWORD=<initial_admin_password>
API_URL=https://api.yourdomain.com
CLIENT_URL=https://yourdomain.com
EMAIL_HOST=<smtp_host>
DEFAULT_EMAIL_FROM=<noreply@yourdomain.com>
CELERY_CONCURRENCY=4
HOST_DATASET_ROOT=/mnt/datasets
WORKER_SHELL_SHARED_SECRET=<shared_secret_used_by_api_and_worker>
WORKER_SHELL_REDIS_URL=redis://<data-vm-host>:6379
WORKER_SHELL_WORKER_ID=<optional_worker_id>
# Required when using NFS-backed database volume in docker-compose-data.yml
NFS_SERVER_IP=<nfs_server_ip>
NFS_SHARE_PATH=<nfs_export_path>Notes:
- Compose files set
DB_USERNAME=codepost_userinternally. .env.exampleincludesDB_USER; this variable is retained for compatibility but is not used by the current compose runtime.DB_HOSTNAMEis also used for Redis URLs in current compose files.
On the Data VM, from codePost-api/:
docker-compose --env-file .env -f docker-compose-data.yml up -dThis starts MariaDB + Redis and optional operations services (codepost-flower, adminer).
On the Backend VM, from codePost-api/:
docker-compose --env-file .env -f docker-compose-prod.yml up -d --buildThis starts API + Nginx entry service.
On the Worker VM, from codePost-api/:
docker-compose --env-file .env -f docker-compose-worker.yml up -d --buildThis starts Celery worker + worker-shell relay.
Deploy UI from codePost-ui using its README (../codePost-ui/README.md).
codepost-entry expects cert files mounted from ./certs:
./certs/fullchain.pem./certs/privkey.pem
These map to:
/etc/ssl/certs/fullchain.pem/etc/ssl/certs/privkey.pem
At startup, API containers run init.sh, which:
- runs migrations (
python manage.py migrate --noinput) - creates/updates the API admin user from
API_USERandAPI_PASSWORD - prints/creates API token for that user
After deploy:
- Data VM: DB and Redis containers healthy
- Backend VM:
https://<api-domain>/health-checkreachable - Worker VM: worker containers running and stable
- Frontend VM: UI loads and can make authenticated API requests
For local development:
pip install poetry && poetry installpython manage.py migrate./init.sh python manage.py runserver
Create interactive superuser:
docker-compose -f docker-compose-prod.yml exec codepost-api python manage.py createsuperuserLegacy helper for default development users:
docker-compose -f docker-compose-prod.yml exec codepost-api python manage.py createsuAfter admin user creation:
- Open Django admin (
/admin/) - Create an Organization under
Core > Organizations - Link your user profile under
Core > Profiles - Enable needed permissions (
CanCreateCourses,CanModifyRosters)
This repository is licensed under the Rutgers Non-commercial License (RU-NCL).
See LICENSE for the full terms.
Alternative deployment files (including platform-specific configurations) are maintained separately from this public quickstart.