Overview
The server supports configuration through environment variables, allowing you to customize behavior without modifying source code. Different server implementations use different subsets of these variables.All environment variables are optional and have sensible defaults.
Quick Reference Table
| Variable | Default | servidor.py | server.py | servidor_multi.py | Description |
|---|---|---|---|---|---|
ZK_IP | 192.168.1.205 | ✅ | ❌ | ❌ | Single device IP address |
ZK_PORT | 4370 | ✅ | ❌ | ❌ | Single device port |
ZK_PASSWORD | 0 | ✅ | ❌ | ❌ | Single device password |
ZK_TIMEOUT | 5 | ✅ | ❌ | ❌ | Single device timeout (seconds) |
API_HOST | 0.0.0.0 | ✅ | ✅ | ✅ | Server listening interface |
API_PORT | 5000 | ✅ | ✅ | ✅ | Server listening port |
CERT_FILE | cert.pem | ✅ | ✅ | ✅ | SSL certificate file path |
KEY_FILE | key.pem | ✅ | ✅ | ✅ | SSL private key file path |
DEVICES_FILE | devices.json | ❌ | ✅ | ✅ | Device registry file path |
SERVER_HOST | 192.168.1.100 | ❌ | ❌ | ✅ | Server’s public/internal IP |
PORT | 5000 | ❌ | ❌ | ✅ | Alternative port variable (Render) |
Device Connection Variables
ZK_IP
IP address of the ZKTeco biometric device.Used by: Notes:
servidor.py (single-device only)Example:- Must be a valid IPv4 address
- Device must be reachable on the network
- For multi-device servers, devices are registered via API instead
ZK_PORT
Port number of the ZKTeco device.Used by: Notes:
servidor.py (single-device only)Example:- Default ZKTeco port is 4370
- Some devices may use custom ports
- Verify device configuration if connection fails
ZK_PASSWORD
Communication password for the ZKTeco device.Used by: Notes:
servidor.py (single-device only)Example:- Most devices use default password
0 - Check device manual if connection requires password
- Must be numeric value
ZK_TIMEOUT
Connection timeout in seconds for device communication.Used by: Notes:
servidor.py (single-device only)Example:- Increase for slow networks or distant devices
- Values too low may cause premature timeouts
- Recommended range: 5-30 seconds
Server Configuration Variables
API_HOST
Network interface the Flask server listens on.Used by: All server implementationsExample:Common values:
0.0.0.0- Listen on all network interfaces (default, recommended)127.0.0.1- Listen only on localhost (local access only)- Specific IP - Listen on single interface
API_PORT
Port number the Flask server listens on.Used by: All server implementationsExample:Notes:
- Must not conflict with other services
- Ports below 1024 require root privileges on Linux
- Common alternatives: 5000, 8000, 8080, 3000
PORT
Alternative port variable, primarily for cloud platforms like Render.Used by: Notes:
servidor_multi.py onlyExample:- Takes precedence over
API_PORTinservidor_multi.py - Used by Render and some other cloud platforms
- If both
PORTandAPI_PORTare set,PORTis used
SERVER_HOST
The server’s public or internal IP address for display and certificate CN.Used by: Usage:
servidor_multi.py onlyExample:- Used in health check response to show access URL
- Sets Common Name (CN) when generating SSL certificates
- Purely informational for API responses
SSL/TLS Configuration Variables
CERT_FILE
Path to SSL certificate file (PEM format).Used by: All server implementationsExample:Notes:
- File must exist and be readable
- Can be relative or absolute path
- Used together with
KEY_FILEfor HTTPS - If file doesn’t exist, server attempts auto-generation
KEY_FILE
Path to SSL private key file (PEM format).Used by: All server implementationsExample:Notes:
- File must exist and be readable
- Should have restrictive permissions (600 or 640)
- Never commit private keys to version control
- If file doesn’t exist, server attempts auto-generation
Data Persistence Variables
DEVICES_FILE
Path to JSON file storing device registry for multi-device servers.Used by: File format:Behavior:
server.py and servidor_multi.pyExample:- Created automatically on first run if missing
- Updated automatically on device add/edit/delete
- Loaded on server startup to restore device registry
- Must be writable by server process
Configuration by Server Type
servidor.py (Single Device)
For managing one ZKTeco device:server.py (Multi-Device)
For managing multiple devices via API:Devices are registered via POST /devices endpoint, not environment variables.
servidor_multi.py (Multi-Device for Render)
For cloud deployment with optional static device configuration:Deployment Examples
Local Development
Systemd Service
Create/etc/systemd/system/zkteco.service:
Docker
- Single Device
- Multi-Device
Docker Compose
Kubernetes
Cloud Platforms
- Render
- Heroku
- AWS EC2
In Render dashboard, set environment variables:Render provides HTTPS automatically, so SSL variables are not needed.
Environment Variable Precedence
When multiple configuration sources exist:- Explicit environment variables (highest priority)
- Environment files (e.g., systemd
EnvironmentFile) - Default values in source code (lowest priority)
Validation and Debugging
Check Current Environment
Verify Server Configuration
The server logs show active configuration on startup:Common Issues
Environment Variable Not Applied
Environment Variable Not Applied
Problem: Changed environment variable but server uses old valueSolutions:
- Restart the server after changing variables
- For systemd:
sudo systemctl daemon-reload && sudo systemctl restart zkteco - Verify variable is actually set:
env | grep VAR_NAME - Check for typos in variable names (case-sensitive)
Integer Parsing Errors
Integer Parsing Errors
Problem:
ValueError: invalid literal for int()Solutions:- Ensure numeric variables contain only digits:
- ✅
export ZK_PORT="4370" - ❌
export ZK_PORT="4370 "(trailing space) - ❌
export ZK_PORT="port4370"(contains text)
- ✅
File Path Not Found
File Path Not Found
Problem:
FileNotFoundError for CERT_FILE, KEY_FILE, or DEVICES_FILESolutions:- Use absolute paths for production:
/etc/ssl/certs/cert.pem - Verify file exists:
ls -la $CERT_FILE - Check permissions:
stat $CERT_FILE - Ensure working directory is correct
Port Already in Use
Port Already in Use
Problem:
OSError: [Errno 98] Address already in useSolutions:- Check what’s using the port:
sudo lsof -i :5000 - Change API_PORT to unused port
- Kill conflicting process:
sudo kill <PID>
Security Considerations
Sensitive Variables
These variables may contain sensitive information:ZK_PASSWORD- Device access passwordKEY_FILEpath - Location of private keyDEVICES_FILEpath - May reveal infrastructure details
Best Practices
Use Secret Management
For production, use proper secret management:
- AWS Secrets Manager
- HashiCorp Vault
- Kubernetes Secrets
- Environment variable injection from CI/CD
Restrict File Permissions
Protect environment files:
Use .gitignore
Exclude sensitive files:
Rotate Certificates
Regularly update SSL certificates:
Next Steps
Single Device Deployment
Deploy servidor.py with environment variables
Multi-Device Deployment
Deploy server.py with devices.json persistence
SSL Configuration
Configure HTTPS with certificates
API Reference
Use the configured server