CodEdu is a modern platform for classrooms and training programs to assign coding tasks, collect submissions, and deliver instant feedback. It streamlines the full workflow for teachers and students—from creating assignments to automated evaluation and clear, actionable results.
—
- Role‑based access for students, teachers, and admins
- Easy assignment creation and management
- One‑click code submissions with immediate feedback
- Clear grading and progress tracking
- Secure, self‑hosted by you
—
Prerequisites: Docker and Docker Compose installed on your machine/server.
- Start the database (first time only)
docker compose -f docker-compose.db.yml up -d
- Launch the app
docker compose up -d
- Open the app
- Visit
http://localhost:61189
Stop the app at any time with docker compose down. To stop the database as well: docker compose -f docker-compose.db.yml down.
Tip: For local development, you can also use ./refresh_docker.sh to rebuild and restart both app and DB.
—
To customize your instance (admin account, email, captchas, integrations), set environment variables in a .env file before starting. A copy of example values is provided in the repository. Restart the containers after changes.
—
Create a .env file at the project root before starting the app. At minimum, set the following variables:
DATABASE_URL– PostgreSQL connection stringJWT_SECRET– secret used to sign sessions/tokensADMIN_EMAIL– initial administrator emailADMIN_PASSWORD– initial administrator password
Optional (recommended for production):
PUBLIC_TURNSTILE_SITE_KEY– site key for Turnstile challenge (frontend)TURNSTILE_SECRET_KEY– secret key for Turnstile verification (backend)PASSWORD_RESET_BASE_URL– public URL of the app, used in emails (e.g.,https://codedu.example.com)APP_BASE_URL– optional; overrides links in emails (defaults toPASSWORD_RESET_BASE_URL)SMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD– SMTP credentials for outgoing emailSMTP_FROM– verified sender address (e.g.,[email protected])SMTP_FROM_NAME– display name for the senderSMTP_DKIM_SELECTOR,SMTP_DKIM_DOMAIN– DKIM signing configuration (optional)SMTP_DKIM_PRIVATE_KEYorSMTP_DKIM_PRIVATE_KEY_FILE– DKIM private key (inline or file path)BAKALARI_BASE_URL– optional integration endpoint for BakalářiAPP_PORT– public HTTP port for the proxy (default61189)BACKEND_PORT– internal backend port (default8080)DB_NAME,DB_USER,DB_PASSWORD,DB_HOST,DB_PORT,DB_SSLMODE– database settings used by containersDB_HOST_PORT– host port to expose Postgres when usingbackend/docker-compose.ymlCOMPOSE_PROJECT_NAME– set this to run multiple instances in parallel (isolates networks/volumes)
Quick start template:
DATABASE_URL=postgres://postgres:postgres@db:5432/codedu?sslmode=disable
JWT_SECRET=change-me-very-secret
[email protected]
ADMIN_PASSWORD=change-me-strong
# Public URL of your deployment (used for links in emails)
PASSWORD_RESET_BASE_URL=http://localhost:61189
# Email (optional but recommended)
SMTP_HOST=
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
[email protected]
SMTP_FROM_NAME=CodEdu
# Human verification (optional)
PUBLIC_TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=
# Optional integrations
BAKALARI_BASE_URL=
After editing .env, (re)start the services with docker compose up -d.
—
Use a unique COMPOSE_PROJECT_NAME and APP_PORT per instance to avoid port and database collisions. Each project name gets its own Docker network and volume, so the database is isolated per instance.
Example:
APP_PORT=61189 COMPOSE_PROJECT_NAME=codedu_a ./refresh_docker.sh
APP_PORT=61190 COMPOSE_PROJECT_NAME=codedu_b ./refresh_docker.sh
Open the apps at:
http://localhost:61189http://localhost:61190
—
To optimize VM boot times, you must generate a snapshot of the base image. This is a one-time setup step (or whenever the base image changes).
- Ensure
vm/base.imgis present. - Run the snapshot preparation command from the
backenddirectory:
cd backend
go run . --prepare-snapshotThis will boot the VM, wait for it to be ready, and save the state to vm/vm.state. Subsequent VM launches will use this snapshot for sub-second boot times.
—
- Automated periodic backups of the database are created and stored locally in the
backupsfolder. - To restore from a backup, stop the app, restore the database from the desired archive, and start the app again.
—
- Found an issue or have a feature request? Open an issue in this repository.
- For general questions, please get in touch with your system administrator or course lead.
—
For development updates or inquiries, please contact the project maintainer.