13 KiB
Bitip GeoIP Service - Configuration Guide
This document provides detailed information about configuring the Bitip GeoIP Service using environment variables.
Table of Contents
Backend Configuration
The backend is configured via environment variables, typically stored in .env
at the project root or src/backend/.env
.
Configuration File Locations
- Development:
d:\Git\Home\Bitip\.env
(project root) - Production: Set via Docker environment variables or system environment
Backend Environment Variables
API Keys
FRONTEND_API_KEY=frontend-dev-key
EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2
FRONTEND_API_KEY
- Purpose: API key used by the frontend application to authenticate with the backend
- Format: String (alphanumeric recommended)
- Required: Yes
- Security: Change this to a secure random value in production
- Example:
your-secure-frontend-api-key-here
EXTERNAL_API_KEYS
- Purpose: Comma-separated list of API keys for external clients (non-frontend applications)
- Format: Comma-separated strings
- Required: Yes (can be empty string if no external access needed)
- Security: Use strong, randomly generated keys in production
- Example:
key1-abc123,key2-def456,key3-ghi789
Frontend Origin Validation
FRONTEND_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174,http://localhost:5175
FRONTEND_ALLOWED_ORIGINS
- Purpose: Comma-separated list of allowed origins (domains) that can use the frontend API key
- Format: Comma-separated full URLs (including protocol and port)
- Required: Yes
- Default:
http://localhost:5173
(if not set) - Security:
- Provides additional protection layer beyond rate limiting
- Validates
Origin
orReferer
header for requests using frontend API key - Only applies to frontend API key - external keys are not origin-restricted
- Note: Can be bypassed from Postman/curl, but blocks browser-based abuse from other domains
- Development Example:
http://localhost:5173,http://localhost:5174,http://localhost:5175
- Production Example:
https://your-domain.com,https://www.your-domain.com
- Use Cases:
- Prevent frontend API key theft and reuse from other websites
- Block cross-site abuse while still allowing legitimate frontend access
- Works in conjunction with CORS for defense-in-depth
- Important Notes:
- Must include protocol (
http://
orhttps://
) - Must include port if non-standard (e.g.,
http://localhost:5173
) - Requests without
Origin
orReferer
header will be rejected - Multiple origins supported for staging/production environments
- Must include protocol (
Server Configuration
PORT=5172
BASE_PATH=/geoip-ui
NODE_ENV=development
PORT
- Purpose: Port number on which the backend API server listens
- Format: Integer (1-65535)
- Required: Yes
- Default: 5172 (if not set)
- Development: 5172
- Production: Typically 5172 or 8080
- Example:
5172
BASE_PATH
- Purpose: Base URL path for all API routes and static files
- Format: String starting with
/
(or just/
for root) - Required: Yes
- Default:
/
- Use Cases:
/
- Application at root (e.g.,http://localhost:5172/api/health
)/geoip-ui
- Application under subpath (e.g.,http://localhost:5172/geoip-ui/api/health
)- Useful for reverse proxy scenarios or hosting multiple apps on same domain
- Example:
/geoip-ui
- Note: All API routes are prefixed with this path automatically
NODE_ENV
- Purpose: Node.js environment mode
- Format: String
- Required: No (defaults to 'development')
- Valid Values:
development
- Enables verbose logging, detailed errorsproduction
- Optimized for performance, minimal logging
- Example:
production
MaxMind Database Configuration
MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs
MAXMIND_DB_PATH
- Purpose: Absolute file system path to MaxMind GeoLite2 database files
- Format: Absolute path (OS-specific)
- Required: Yes
- Windows Example:
D:\\tools\\maxmind-dbs
(note double backslashes) - Linux Example:
/usr/share/GeoIP
- Docker Example:
/usr/share/GeoIP
(mounted volume) - Expected Files:
GeoLite2-City.mmdb
- City-level geolocation database- Provided by separate GeoIP update service or manual download
- Note: Bitip does NOT download databases - they must be provided externally
Rate Limiting Configuration
FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30
EXTERNAL_RATE_WINDOW_MS=60000
EXTERNAL_RATE_MAX=1000
FRONTEND_RATE_WINDOW_MS
- Purpose: Time window (milliseconds) for frontend API key rate limiting
- Format: Integer (milliseconds)
- Required: Yes
- Default: 60000 (1 minute)
- Example:
60000
= 1 minute window
FRONTEND_RATE_MAX
- Purpose: Maximum number of requests allowed from frontend API key within the time window
- Format: Integer
- Required: Yes
- Default: 100
- Example:
100
= 100 requests per minute
EXTERNAL_RATE_WINDOW_MS
- Purpose: Time window (milliseconds) for external API keys rate limiting
- Format: Integer (milliseconds)
- Required: Yes
- Default: 60000 (1 minute)
- Example:
60000
= 1 minute window
EXTERNAL_RATE_MAX
- Purpose: Maximum number of requests allowed from external API keys within the time window
- Format: Integer
- Required: Yes
- Default: 1000
- Example:
1000
= 1000 requests per minute
Batch Configuration
BATCH_LIMIT=100
DEBOUNCE_MS=2000
BATCH_LIMIT
- Purpose: Maximum number of IP addresses allowed in a single batch lookup request
- Format: Integer
- Required: Yes
- Default: 100
- Example:
100
- Use Case: Prevents abuse and excessive memory usage
DEBOUNCE_MS
- Purpose: Debounce delay (milliseconds) for frontend input - delays API calls until user stops typing
- Format: Integer (milliseconds)
- Required: Yes
- Default: 2000 (2 seconds)
- Example:
2000
= 2 seconds - Note: Also configured on frontend - backend value is for reference
Seq Logging Configuration (Optional)
# SEQ_URL=http://localhost:5341
# SEQ_API_KEY=your-seq-api-key
SEQ_URL
- Purpose: URL of Seq structured logging server
- Format: HTTP/HTTPS URL
- Required: No (logging works without Seq)
- Default: Not set (Seq logging disabled)
- Example:
http://localhost:5341
- Use Case: Centralized structured logging and monitoring
SEQ_API_KEY
- Purpose: API key for authenticating with Seq server
- Format: String
- Required: No (some Seq instances don't require authentication)
- Default: Not set
- Example:
your-seq-api-key
Frontend Configuration
The frontend is configured via environment variables, typically stored in src/frontend/.env
.
Configuration File Location
- Development:
src/frontend/.env
- Production: Build-time environment variables or
.env.production
Frontend Environment Variables
VITE_API_KEY=frontend-dev-key
VITE_API_URL=http://localhost:5172/geoip-ui/api
VITE_DEBOUNCE_MS=2000
VITE_API_KEY
- Purpose: API key to authenticate with the backend (must match
FRONTEND_API_KEY
in backend) - Format: String
- Required: Yes
- Example:
frontend-dev-key
- Note: Must match backend's
FRONTEND_API_KEY
exactly
VITE_API_URL
- Purpose: Full URL to the backend API (including base path and
/api
suffix) - Format: HTTP/HTTPS URL
- Required: Yes
- Development Example:
http://localhost:5172/geoip-ui/api
- Production Example:
https://your-domain.com/geoip-ui/api
- Note: Must match backend's
PORT
andBASE_PATH
configuration
VITE_DEBOUNCE_MS
- Purpose: Debounce delay (milliseconds) for IP input field - delays API calls until user stops typing
- Format: Integer (milliseconds)
- Required: Yes
- Default: 2000 (2 seconds)
- Example:
2000
= 2 seconds - Use Case: Reduces API calls while user is still typing
Development Setup
Quick Start
-
Copy
.env.example
to.env
:cp .env.example .env
-
Edit
.env
for development:FRONTEND_API_KEY=frontend-dev-key EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2 PORT=5172 BASE_PATH=/geoip-ui NODE_ENV=development MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs FRONTEND_RATE_WINDOW_MS=60000 FRONTEND_RATE_MAX=30 EXTERNAL_RATE_WINDOW_MS=60000 EXTERNAL_RATE_MAX=1000 BATCH_LIMIT=100 DEBOUNCE_MS=2000
-
Edit
src/frontend/.env
:VITE_API_KEY=frontend-dev-key VITE_API_URL=http://localhost:5172/geoip-ui/api VITE_DEBOUNCE_MS=2000
-
Ensure MaxMind databases are available:
- Databases should be provided by separate GeoIP update service
- Place
GeoLite2-City.mmdb
in the path specified byMAXMIND_DB_PATH
-
Start development servers:
npm run dev
Development URLs
- Frontend: http://localhost:5173/
- Backend API: http://localhost:5172/geoip-ui/api/
- Health Check: http://localhost:5172/geoip-ui/api/health
Production Setup
Environment Variables
Backend (via Docker or system environment):
FRONTEND_API_KEY=<secure-random-key>
EXTERNAL_API_KEYS=<key1>,<key2>,<key3>
FRONTEND_ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com
PORT=5172
BASE_PATH=/
NODE_ENV=production
MAXMIND_DB_PATH=/usr/share/GeoIP
FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30
EXTERNAL_RATE_WINDOW_MS=60000
EXTERNAL_RATE_MAX=1000
BATCH_LIMIT=100
DEBOUNCE_MS=2000
Frontend (build-time .env.production
):
VITE_API_KEY=<same-as-backend-FRONTEND_API_KEY>
VITE_API_URL=https://your-domain.com/api
VITE_DEBOUNCE_MS=2000
Security Recommendations
-
Generate Strong API Keys:
# Linux/Mac openssl rand -hex 32 # PowerShell [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
-
Never Commit Real Keys:
- Keep
.env
in.gitignore
- Use
.env.example
as template only - Use secret management in production (Docker secrets, Kubernetes secrets, etc.)
- Keep
-
Configure Allowed Origins:
- Set
FRONTEND_ALLOWED_ORIGINS
to your actual production domain(s) - Include all variants (www, non-www, subdomains)
- Must use HTTPS in production:
https://your-domain.com
- This provides defense-in-depth against frontend API key theft
- Set
-
Use HTTPS in Production:
- Set
VITE_API_URL
to HTTPS endpoint - Configure reverse proxy (nginx, Traefik, etc.) for TLS termination
- Set
-
Adjust Rate Limits:
- Based on expected traffic patterns
- Monitor and adjust as needed
- Consider more aggressive limits for frontend key (e.g., 30-50 req/min)
-
Understanding Security Model:
- Frontend API Key: Semi-public, visible in browser
- Protected by: Origin validation + Rate limiting + CORS
- Can still be extracted and used from Postman/curl
- Origin validation blocks browser-based cross-site abuse
- External API Keys: Fully secret, never exposed to browser
- Protected by: Rate limiting only
- For trusted backend integrations
- Best Practice: Use aggressive rate limiting on frontend key to make abuse impractical
- Frontend API Key: Semi-public, visible in browser
Troubleshooting
Backend Won't Start
- Check
MAXMIND_DB_PATH
: Ensure path exists and containsGeoLite2-City.mmdb
- Check Port Conflicts: Ensure
PORT
is not already in use - Check Environment Loading: Verify
.env
file is at project root
Frontend Can't Connect to Backend
- Check
VITE_API_URL
: Must match backendPORT
andBASE_PATH
- Check CORS: Backend allows frontend origin by default
- Check API Key:
VITE_API_KEY
must match backendFRONTEND_API_KEY
Authentication Errors
- 401 Unauthorized: API key mismatch between frontend and backend
- Verify Keys Match: Frontend
VITE_API_KEY
=== BackendFRONTEND_API_KEY
Origin Validation Errors
-
403 Forbidden - "Origin header required": Request missing
Origin
orReferer
header- Cause: Typically happens when testing from Postman/curl with frontend API key
- Solution: Use external API key for non-browser clients, or add
Origin
header manually in testing tools
-
403 Forbidden - "Invalid origin": Frontend origin not in allowed list
- Check
FRONTEND_ALLOWED_ORIGINS
: Ensure your frontend domain is listed - Protocol Mismatch: Ensure protocol matches (
http://
vshttps://
) - Port Mismatch: Include port if non-standard (e.g.,
http://localhost:5173
) - Development: Add all Vite dev server ports (5173, 5174, 5175, etc.)
- Production: Add all domain variants (www, non-www, subdomains)
- Check
Rate Limiting Issues
- 429 Too Many Requests: Exceeded rate limits
- Increase Limits: Adjust
*_RATE_MAX
values in.env
- Check Time Window: Adjust
*_RATE_WINDOW_MS
values
Additional Resources
- Main README:
/README.md
- Breaking Changes:
/docs/BREAKING-CHANGES-FIXED.md
- Package Updates:
/docs/PACKAGE-UPDATES.md
- API Documentation: See inline code comments in
/src/backend/routes/api.ts