Command reference for PlacePrep exam mode: Docker, ports and firewall, sync APIs and fixes for the most common setup problems.
Technical Reference
Quick reference for every command you'll need when running PlacePrep in self-hosted / exam mode.
For the full step-by-step guide, see Self-Hosting.
Application Commands
Start / Stop
powershell# Start Docker (local Appwrite) + Next.js dev server (students can connect over LAN) bun run exam:start # Stop everything — kills Next.js process and stops Docker containers bun run exam:stop # Build the Next.js app (required after changing .env or after updating code) bun run build # Start the Next.js dev server manually (without Docker) bun run dev # Start the Next.js production server manually (after build) bun run start
Database Setup
The setup script creates 16 collections and thepowershell# Create all Appwrite collections in the CLOUD database bun run setup:appwrite # Create all Appwrite collections in the LOCAL (Docker) database bun run setup:appwrite:local # Preview what the setup script would create, without writing anything bun run setup:appwrite:dry # Bootstrap the local admin user (only needed once, before first pre-exam sync) bun run exam:bootstrap-admin
tnp_documents storage bucket. It skips anything that already exists, so it is safe to re-run.
Docker Commands
Start / Stop Containers
powershell# Start local Appwrite stack in background (detached) docker compose -f docker/exam-mode/docker-compose.yml up -d # Stop containers (data is preserved in volumes) docker compose -f docker/exam-mode/docker-compose.yml down # Stop containers AND wipe ALL local data (volumes deleted — run ONLY after post-exam sync) docker compose -f docker/exam-mode/docker-compose.yml down -v # Restart containers docker compose -f docker/exam-mode/docker-compose.yml restart
Status & Verification
powershell# List all running containers docker ps # List all containers (including stopped ones) docker ps -a # Show status of exam-mode compose services docker compose -f docker/exam-mode/docker-compose.yml ps # Check resource usage (CPU, memory) of running containers docker stats # List Docker images on your machine docker images # Show disk usage by images, containers, and volumes docker system df
Logs
Container names:powershell# Stream Appwrite server logs (live — press Ctrl+C to stop) docker logs appwrite -f # Stream MariaDB logs docker logs appwrite-mariadb -f # Stream Redis logs docker logs appwrite-redis -f # Stream the PlacePrep app container logs docker logs placeprep-app -f # View last 100 lines of Appwrite logs (no streaming) docker logs appwrite --tail 100 # View logs for all compose services at once docker compose -f docker/exam-mode/docker-compose.yml logs -f
placeprep-app, appwrite, appwrite-console, appwrite-realtime, appwrite-traefik, appwrite-mariadb, appwrite-redis, plus the worker containers appwrite-worker-databases, appwrite-worker-audits, appwrite-worker-deletes, and appwrite-task-maintenance.
Volumes & Data
Volumes:powershell# List Docker volumes docker volume ls # Inspect a volume (find its mount path) docker volume inspect appwrite-uploads # Remove a specific volume manually docker volume rm <volume-name> # Remove ALL unused volumes (careful — affects all Docker projects) docker volume prune
appwrite-mariadb, appwrite-redis, appwrite-cache, appwrite-uploads, appwrite-imports, appwrite-certificates, appwrite-functions, appwrite-sites, appwrite-builds, appwrite-config.
Cleanup
powershell# Remove stopped containers, unused networks, dangling images, and build cache docker system prune # Also remove unused volumes (frees the most space — use carefully) docker system prune --volumes # Remove all unused images (not just dangling ones) docker image prune -a
Network & Port Commands (Windows)
Find Your Machine's IP
Look for thepowershell# Show all network adapters and their IPs ipconfig # Show only the IPv4 address of your active adapter ipconfig | findstr "IPv4"
IPv4 Address under your active Wi-Fi or Ethernet adapter (e.g. 192.168.1.42). Students connect to http://192.168.1.42:3000.
Port Troubleshooting
powershell# Find which process is using port 3000 netstat -ano | findstr :3000 # Find which process is using port 80 (used by local Appwrite) netstat -ano | findstr :80 # Kill a process by PID (replace <PID> with the number from netstat output) taskkill /F /PID <PID> # Kill the entire process tree by PID (use if the above doesn't work) taskkill /T /F /PID <PID>
Firewall
powershell# Allow port 3000 through Windows Firewall (so students can connect) netsh advfirewall firewall add rule name="PlacePrep Exam" dir=in action=allow protocol=TCP localport=3000 # Remove the rule when done netsh advfirewall firewall delete rule name="PlacePrep Exam" # Allow port 80 (if students need direct Appwrite console access — usually not needed) netsh advfirewall firewall add rule name="PlacePrep Appwrite" dir=in action=allow protocol=TCP localport=80
Sync API Reference
These endpoints are called by the exam dashboard UI. You can also call them directly for scripting or debugging.
Pre-Exam Sync: Cloud → Local
POST http://localhost:3000/api/exam-mode/sync-to-local Headers: x-user-id: <admin-user-id> (normal auth) x-admin-key: <APPWRITE_LOCAL_API_KEY> (bootstrap auth — use when DB is empty) Body (optional — restrict to specific exams): { "examIds": ["exam_id_1", "exam_id_2"] }
Post-Exam Sync: Local → Cloud
POST http://localhost:3000/api/exam-mode/sync-to-cloud Headers: x-user-id: <admin-user-id> Body (optional — restrict to specific exams): { "examIds": ["exam_id_1"] }
Auto-Submit Expired Exams
POST http://localhost:3000/api/exam-mode/auto-submit-expired
Force-submits all in-progress attempts whose exam end time has passed. The exam dashboard calls this every 15 seconds while Auto-refresh (15s) is enabled and the tab is open. There is no server-side cron, so keep the dashboard open during the exam.
Register Walk-in Student
API-only — there is no button for this on the dashboard.
The returnedPOST http://localhost:3000/api/exam-mode/register-local Body: { "name": "Student Name", "email": "student@college.edu", "registration_number": "22105109024", "branch": "CSE", "college_name": "Example College" } Response: { "userId": "...", "examPassword": "exam2026" }
examPassword is always the EXAM_PASSWORD_PREFIX value — the same shared password every student uses.
Other Exam Mode Endpoints
| Endpoint | Purpose |
|---|---|
GET /api/exam-mode/status | Exam mode configuration and connectivity |
GET /api/exam-mode/list-exams | Live exams available to monitor |
GET /api/exam-mode/active-students | Students currently attempting |
GET /api/exam-mode/completed-students | Students who have submitted |
GET /api/exam-mode/student-progress | Per-student progress within an exam |
GET /api/exam-mode/list-credentials | Student name + shared password list |
POST /api/exam-mode/force-submit | Force-submit one student's attempt |
POST /api/exam-mode/restart-exam | Clear a student's answers and restart their timer |
POST /api/exam-mode/delete-attempt | Delete a completed attempt |
Common Bug Fixes
Port 3000 still in use after Ctrl+C
powershell# Find the PID using port 3000 netstat -ano | findstr :3000 # Kill it taskkill /T /F /PID <PID>
Or use the dedicated stop command:
powershellbun run exam:stop
Port 80 already in use (Appwrite won't start)
Port 80 is typically occupied by IIS (Windows), Nginx, or XAMPP.
powershell# Stop IIS iisreset /stop # Or find and kill the process using port 80 netstat -ano | findstr :80 taskkill /F /PID <PID>
Then retry:
powershelldocker compose -f docker/exam-mode/docker-compose.yml up -d
"exam-db" database missing after container restart
The database persists in a Docker volume and should survive restarts. If it's gone, it means you randown -v previously. Recreate the schema:
powershellbun run setup:appwrite:local
Then run the pre-exam sync again to pull data from cloud.
Docker containers keep restarting / crashing
powershell# Check logs for the specific container that's failing docker logs appwrite -f # Common cause: not enough disk space docker system df # Free up space if needed docker system prune
Pre-exam sync authentication error (first run)
The local DB is empty, so there is no admin account to authenticate with yet. Use bootstrap auth:
- On the exam dashboard, the Bootstrap Sync dialog asks for a local API key
- Enter the value of
APPWRITE_LOCAL_API_KEYfrom your.env - Run the sync
Post-exam sync: users not appearing in cloud
Make sure you're running Post-Exam Sync (Local → Cloud), not pre-exam. Check the sync report — theusers (local → cloud) row should show +N for newly created users. Existing cloud users show as skipped (normal).
Build fails after changing .env
Environment variables with NEXT_PUBLIC_ prefix are baked into the build at compile time. After changing them:
powershell# Clear Next.js build cache Remove-Item -Recurse -Force .next # Rebuild bun run build
Appwrite console unreachable at localhost/console
powershell# Check if the container is running docker ps # If not running, start it docker compose -f docker/exam-mode/docker-compose.yml up -d # If running but console is unreachable, check logs docker logs appwrite --tail 50
Wait 30–60 seconds after starting for Appwrite to fully initialize.
Important File Locations
| File | Purpose |
|---|---|
.env | All environment variables — never commit this file |
.env.example | Template to copy to .env |
docker/exam-mode/docker-compose.yml | Docker Compose config for local Appwrite stack |
docker/exam-mode/appwrite.env | Appwrite internal secrets — change before production use |
.next-server.pid | PID file written by exam:start — used by exam:stop to kill the process |
scripts/exam-start.ts | Starts Docker, then next dev --hostname 0.0.0.0 --port 3000 |
scripts/exam-stop.ts | Kills the Next.js process tree and stops Docker |
scripts/setup-appwrite.ts | Creates all Appwrite collections and the storage bucket (cloud or local) |
scripts/bootstrap-local-admin.ts | Creates the first admin in the local Appwrite instance |
src/lib/exam-mode/config.ts | Exam mode configuration and the shared exam password |
src/lib/exam-mode/syncService.ts | Core sync logic (cloud↔local) |
src/app/api/exam-mode/ | All exam-mode API routes |
src/app/exam-dashboard/ | The live exam monitoring dashboard |
Environment Variable Quick Reference
Seeenv# Cloud Appwrite NEXT_PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1 NEXT_PUBLIC_APPWRITE_PROJECT_ID=your_cloud_project_id NEXT_PUBLIC_APPWRITE_DATABASE_ID=your_cloud_database_id APPWRITE_API_KEY=your_cloud_api_key # Exam mode EXAM_MODE=true APPWRITE_LOCAL_ENDPOINT=http://localhost/v1 APPWRITE_LOCAL_PROJECT_ID=your_local_project_id APPWRITE_LOCAL_DATABASE_ID=exam-db APPWRITE_LOCAL_API_KEY=your_local_api_key # Exam password (shared by all students; the value IS the password) EXAM_PASSWORD_PREFIX=exam2026 # Optional: IP restriction for exam APIs (blank = allow all) EXAM_ALLOWED_IPS=192.168.1.0/24
.env.example in the repository root for the full list, including the AI provider, feedback, analytics, and email variables.Found a problem with this page? Help us fix it.
Still stuck? Read the FAQ or the troubleshooting guide.