Common issues new developers encounter when setting up the TeachLink backend, with causes and fixes.
Cause: PostgreSQL is not running or not accessible on the expected port.
Fix:
# Check if PostgreSQL container is running
docker compose ps postgres
# If not running, start it
docker compose up -d postgres
# Check Docker service is running
docker infoIf using a local PostgreSQL installation:
# Windows (check service)
Get-Service postgresql*
# If stopped, start it
Start-Service postgresql*Cause: DATABASE_USER or DATABASE_PASSWORD in .env does not match the PostgreSQL credentials.
Fix:
# Check current .env values
grep -E "DATABASE_(USER|PASSWORD)" .env
# Verify with psql using those credentials
docker exec -it teachlink-postgres psql -U postgres -d teachlink -c "SELECT 1"Cause: The database specified in DATABASE_NAME has not been created.
Fix:
# Create the database inside the container
docker exec -it teachlink-postgres psql -U postgres -c "CREATE DATABASE teachlink;"
# Or let Docker create it on startup (set POSTGRES_DB env var)Cause: Too many open database connections. The pool may be too large or connections are leaking.
Fix:
# Check active connections
docker exec -it teachlink-postgres psql -U postgres -d teachlink -c "SELECT count(*) FROM pg_stat_activity;"
# Kill idle connections
docker exec -it teachlink-postgres psql -U postgres -d teachlink -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle';"
# Reduce pool size in .env
# DATABASE_POOL_MAX=10
# DATABASE_POOL_MIN=2Cause: Redis is not running.
Fix:
# Start Redis via Docker
docker compose up -d redis
# Verify it's healthy
docker compose ps redisCause: REDIS_HOST or REDIS_PORT in .env is incorrect.
Fix:
# Check current settings
grep -E "REDIS_(HOST|PORT)" .env
# Verify Redis is listening on the correct host/port
docker exec -it teachlink-redis redis-cli ping
# Should return: PONGCause: Redis requires a password but REDIS_PASSWORD is not set in .env.
Fix: Add REDIS_PASSWORD=yourpassword to .env or disable password on the Redis server.
Cause: Another process is already using port 3000.
Fix:
# Windows - find the process using port 3000
netstat -ano | findstr :3000
# Kill the process (replace PID with the actual process ID)
taskkill /PID <PID> /FCause: A local installation of PostgreSQL or Redis is already bound to the default port.
Fix:
# Stop the local service
# PostgreSQL
net stop postgresql-x64-16
# Or change the Docker port mapping in docker-compose.yml:
# ports:
# - "5433:5432" # Maps Docker's 5432 to host's 5433Cause: A required environment variable is missing from .env.
Fix:
# Validate your .env
pnpm validate:env
# Copy the example and fill in missing values
cp .env.example .envCommon required variables for local development:
| Variable | Typical value |
|---|---|
DATABASE_HOST |
localhost |
DATABASE_PORT |
5432 |
DATABASE_USER |
postgres |
DATABASE_PASSWORD |
postgres |
DATABASE_NAME |
teachlink |
REDIS_HOST |
localhost |
REDIS_PORT |
6379 |
JWT_SECRET |
Any string >= 10 chars |
JWT_REFRESH_SECRET |
Any string >= 10 chars |
ENCRYPTION_SECRET |
Exactly 32 characters |
SESSION_SECRET |
Any string >= 10 chars |
SMTP_HOST |
localhost (can be dummy) |
SMTP_PORT |
1025 |
SMTP_USER |
(empty) |
SMTP_PASS |
(empty) |
EMAIL_FROM |
noreply@teachlink.local |
AWS_ACCESS_KEY_ID |
Can be placeholder for local dev |
AWS_SECRET_ACCESS_KEY |
Can be placeholder for local dev |
AWS_S3_BUCKET |
Can be placeholder for local dev |
STRIPE_SECRET_KEY |
Placeholder for local dev |
STRIPE_WEBHOOK_SECRET |
Placeholder for local dev |
SENDGRID_API_KEY |
Placeholder for local dev |
Cause: A migration is trying to create a table that already exists (often because synchronize: true auto-created it first).
Fix:
# Drop the conflicting table and re-run migration
docker exec -it teachlink-postgres psql -U postgres -d teachlink -c "DROP TABLE IF EXISTS <tablename> CASCADE;"
curl -X POST http://localhost:3000/migrations/runPrevention: In development, you can either:
- Use
synchronize: falseand rely entirely on migrations, or - Accept that
synchronizehandles schema and skip migrations
Cause: You're trying to roll back a migration that later migrations depend on.
Fix: Roll back the later migrations first, then the target migration.
# Roll back the last 3 migrations
curl -X POST http://localhost:3000/migrations/rollback/3
# Or reset all (development only)
curl -X DELETE http://localhost:3000/migrations/resetCause: The migration HTTP endpoints may not be wired into the application yet.
Fix: Verify tables are created via TypeORM's synchronize feature (enabled in development). Check directly in PostgreSQL:
docker exec -it teachlink-postgres psql -U postgres -d teachlink -c "\dt"Cause: Docker is not installed or not in PATH.
Fix: Install Docker Desktop from https://www.docker.com/products/docker-desktop/
Cause: Docker Desktop is not running.
Fix:
# Start Docker Desktop
# Windows: Start menu → Docker Desktop
# Then verify:
docker infoCause: Another PostgreSQL instance (local install or another container) is using port 5432.
Fix:
# Stop the conflicting container
docker stop <container-name>
# Or use a different port in docker-compose.yml:
# postgres:
# ports:
# - "5433:5432"
# Then update .env: DATABASE_PORT=5433Cause: The container may be crashing on startup due to misconfiguration.
Fix:
# View container logs
docker compose logs postgres
docker compose logs redis
# Common fixes:
# - Ensure .env has the required variables
# - Check that ports are not in use
# - Ensure enough disk space for Docker volumesCause: Dependencies are not installed.
Fix:
pnpm installCause: TypeScript code has type errors.
Fix:
# Check for type errors
pnpm typecheck
# Common fixes:
# - Update imports for renamed modules
# - Check for missing type definitionsCause: An unhandled error during bootstrap (often database or Redis connection failure).
Fix:
# Check the server logs for the actual error
pnpm start:dev 2>&1 | head -50
# Most common: database not reachable — check step 4 of setup- Run the verification script:
pnpm verify - Check the developer runbook
- Search existing issues: https://github.com/teachlink/backend/issues
- Ask in the Telegram community