Reviewed-on: #5
EduNeko
EduNeko is a self-hostable, AI-powered study companion. Upload your notes and study materials, then revise them, chat with them, and generate quizzes — all backed by an LLM of your choosing.
EduNeko is open core: this repository is the full, self-hostable application under the AGPL-3.0 license. A managed, hosted version is also offered for users who would rather not run their own server.
Features
- AI note revision — summarize, improve, or turn notes into study questions.
- Study chat — chat grounded in a single uploaded document. Small documents are sent in full; larger ones use in-process embeddings and retrieval (pgvector when available, otherwise a built-in fallback) with inline citations.
- Quiz generator — multiple-choice, true/false, short-answer, or mixed quizzes, with LLM-assisted grading for free-text answers.
- Usage controls — global concurrency gate and per-user rate limits so a shared AI account isn't overwhelmed.
Tech stack
- Node.js + Express (server-rendered EJS views, Tailwind CSS)
- PostgreSQL (sessions, users, files, quizzes, usage accounting)
- OAuth 2.0 / OpenID Connect for authentication (any standard provider)
- Ollama (local or any remote Ollama-compatible endpoint) for AI generation
Prerequisites
- Node.js 18+ and npm
- A PostgreSQL database
- An OAuth 2.0 / OIDC identity provider (see Authentication)
- An Ollama endpoint — local (
http://localhost:11434) or any remote Ollama-compatible host
Setup
git clone <your-fork-url> eduneko
cd eduneko
npm install
cp .env.example .env
# edit .env with your database, OAuth, and Ollama settings
npm run build:css # compile Tailwind
npm start # or: npm run dev (nodemon + Tailwind watch)
The app creates its database schema on first boot and listens on PORT
(default 3000).
Install as an app (PWA)
EduNeko can be installed from supported browsers for a faster, full-screen experience. Static assets are cached for faster loads and a friendly fallback appears while offline; AI features still require a connection.
PWA support is enabled by default and can be disabled with PWA_ENABLED=false. After changing either icon source, regenerate the PNG assets with npm i --no-save sharp && npm run icons.
Running with Docker
The repo ships a multi-stage Dockerfile (builds the CSS and bakes the embedding
model into the image) and a docker-compose.yml. The compose file runs the app
on its own; a PostgreSQL service with the pgvector extension is included behind
a bundled-db profile for quick self-hosting.
Set your configuration as environment variables (the compose file reads them, with
sensible defaults). At minimum you must provide SESSION_SECRET and OLLAMA_URL.
Self-host with the bundled database:
export SESSION_SECRET="$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")"
export OLLAMA_URL="http://your-ollama-host:11434"
export AUTH_MODE=single SINGLE_USER_PASSWORD="choose-a-password"
# For local HTTP testing (no TLS proxy): export COOKIE_SECURE=false TRUST_PROXY=
docker compose --profile bundled-db up -d --build
The app comes up on http://localhost:3000, uploads persist in the uploads
volume, and database data in the pgdata volume.
Use an external / managed PostgreSQL: leave the bundled-db profile off and
point DATABASE_URL at your database (set DATABASE_SSL=true for managed
Postgres; keep DB_AUTO_CREATE=false and create the database yourself).
export DATABASE_URL="postgresql://user:pass@db-host:5432/eduneko"
export DATABASE_SSL=true
docker compose up -d --build
Deploying on Coolify
Coolify can deploy this repo as a Docker Compose resource directly:
- Point Coolify at the repository and select the
docker-compose.yml. - Set the environment variables (
SESSION_SECRET,OLLAMA_URL, your auth and database settings) in Coolify's UI rather than a local shell. - Coolify terminates TLS and proxies to the app, so keep the defaults
COOKIE_SECURE=trueandTRUST_PROXY=1, and setREDIRECT_URI/OAUTH_ISSUERto your real values. - Use a managed PostgreSQL (a Coolify Postgres resource or an external one) and
set
DATABASE_URLaccordingly, or enable the bundledpostgresservice. - The
uploadsvolume holds user files — make sure it is persisted across deploys.
Configuration
All configuration is via environment variables — see .env.example for the full annotated list. The essentials:
| Variable | Purpose |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
SESSION_SECRET |
Session signing secret (>= 16 chars) |
OAUTH_ISSUER |
Base URL of your OAuth/OIDC provider |
OAUTH_CLIENT_ID / OAUTH_CLIENT_SECRET |
Your registered OAuth client |
REDIRECT_URI |
Must match a redirect URI registered with your provider |
OLLAMA_URL / OLLAMA_MODEL |
AI backend and model |
Authentication
EduNeko uses the OAuth 2.0 Authorization Code flow with OpenID Connect. It works
with any standard provider. Set OAUTH_ISSUER, and the authorize/token/JWKS
endpoints default to the conventional /oauth/authorize, /oauth/token, and
/oauth/jwks paths under the issuer — override them individually
(OAUTH_AUTHORIZE_URL, OAUTH_TOKEN_URL, OAUTH_JWKS_URL) if your provider
uses different paths.
Register a client with your provider, set the redirect URI to
<your-app-url>/auth/callback, and request the openid profile email roles
scopes. ID tokens are verified as RS256-signed JWTs against the provider's JWKS.
Single-user mode (no OAuth provider)
Don't have an OAuth/OIDC provider? Set AUTH_MODE=single and a
SINGLE_USER_PASSWORD, and EduNeko serves a simple password login backed by one
local account — no identity provider required. Ideal for personal,
single-person deployments. SINGLE_USER_USERNAME (default admin) and
SINGLE_USER_EMAIL are optional. The app refuses to start in single-user mode
if no password is set.
Admin: usage limits
Usage limits are managed from the command line — direct database access is the admin boundary, so there is no web admin panel.
npm run usage -- show <email|username|id> # show a user's remaining capacity
npm run usage -- reset <email|username|id> # refill a user's limits
npm run usage -- list [limit] # users with active usage
npm run usage -- reset-all --yes # refill everyone
License
Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). See LICENSE. If you run a modified version of EduNeko as a network service, the AGPL requires you to offer that version's source to its users.