Troubleshooting

Common issues and solutions for enterprise deployments.

Backend fails to start with import errors

The PYTHONPATH in the Dockerfile must point to /app/backend. This ensures backend modules not covered by the setuptools include pattern (like adapters/, migrations/) are importable.

# Check PYTHONPATH inside the container
docker compose exec backend env | grep PYTHONPATH
# → PYTHONPATH=/app/backend

Enterprise tables not created

Check that:

  1. VERBATIM_DATABASE_URL starts with postgresql+asyncpg://
  2. The enterprise plugin startup hook ran — look for "Enterprise PostgreSQL engine active" in logs:
    docker compose logs backend | grep "Enterprise PostgreSQL"
  3. Enterprise models import Base from persistence.models (not a standalone DeclarativeBase)

License returns "No license key configured"

The VERBATIM_LICENSE_KEY env var must be set:

docker compose exec backend env | grep LICENSE

If it's empty, check your .env file and ensure the variable is set without extra whitespace or quotes.

License returns "Invalid license"

The VERBATIM_SECRET_KEY must exactly match the --secret used when the license was generated. Even one character difference will cause validation to fail.

Frontend shows blank page

Verify the frontend files exist in the container:

docker compose exec backend ls /app/frontend/
# Should contain index.html and asset files

Also check that VERBATIM_FRONTEND_DIR=/app/frontend is set in the environment.

Cannot pull image from GHCR

Ensure Docker is logged into the registry:

# Re-run the setup script
./scripts/setup.sh --license <your-jwt>

# Or log in manually
docker login ghcr.io -u verbatim-customer

PostgreSQL connection refused

The PostgreSQL container may not be ready yet. The compose file includes a health check, but on first run the initialization can take a few seconds. Check the status:

docker compose ps
docker compose logs postgres

Port 80 already in use

Another service is using port 80. Either stop that service or change the nginx port mapping in docker-compose.prod.yml:

# Change to port 8080
ports:
  - "8080:80"

Viewing logs

# All services
docker compose -f docker-compose.prod.yml logs -f

# Backend only
docker compose -f docker-compose.prod.yml logs -f backend

# Last 100 lines
docker compose -f docker-compose.prod.yml logs --tail 100 backend