Installation & Setup
Get started with the License Server API in minutes. This guide covers deployment options, configuration, and initial setup.
Quick Start
Using Docker (Recommended)
The fastest way to get started is with Docker:
# Pull the latest image
docker pull your-org/license-server:latest
# Run with environment variables
docker run -d \
--name license-server \
-p 3001:3001 \
-e ADMIN_API_KEY="your-secure-admin-key" \
-e ENCRYPTION_KEY="your-32-byte-encryption-key" \
-e LICENSE_SIGNING_SECRET="your-signing-secret" \
-e DB_FILE="/data/licenses.db" \
-v ./license-data:/data \
your-org/license-server:latestFrom Source
Clone and run from source code:
# Clone the repository
git clone https://github.com/your-org/license-server.git
cd license-server
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Edit .env with your configuration
# Start the server
npm startEnvironment Configuration
Required Environment Variables
Create a .env file with the following variables:
# Server Configuration
PORT=3001
NODE_ENV=production
# Security Keys (REQUIRED)
ADMIN_API_KEY=your-secure-admin-api-key-here
ENCRYPTION_KEY=your-32-byte-hex-encryption-key-here
LICENSE_SIGNING_SECRET=your-license-signing-secret-here
# Database
DB_FILE=./data/licenses.dbSecurity Warning
Never commit real secrets to version control! Use secure methods to manage production secrets:
- Environment variables
- Docker secrets
- Cloud secret managers (AWS Secrets Manager, Azure Key Vault, etc.)
- HashiCorp Vault
Generating Secure Keys
Generate cryptographically secure keys for production:
# Generate admin API key (32+ characters recommended)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Generate encryption key (must be exactly 32 bytes / 64 hex chars)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Generate signing secret (32+ characters recommended)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Deployment Options
Docker Compose
Create a docker-compose.yml for easy deployment:
version: '3.8'
services:
license-server:
image: your-org/license-server:latest
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- PORT=3001
- ADMIN_API_KEY=${ADMIN_API_KEY}
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- LICENSE_SIGNING_SECRET=${LICENSE_SIGNING_SECRET}
- DB_FILE=/data/licenses.db
volumes:
- license-data:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/v1/"]
interval: 30s
timeout: 10s
retries: 3
volumes:
license-data:
driver: localDeploy with:
# Set environment variables
export ADMIN_API_KEY="your-admin-key"
export ENCRYPTION_KEY="your-encryption-key"
export LICENSE_SIGNING_SECRET="your-signing-secret"
# Start the services
docker-compose up -dKubernetes
Deploy to Kubernetes with secrets management:
# license-server-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: license-server-secrets
type: Opaque
stringData:
admin-api-key: "your-admin-api-key"
encryption-key: "your-encryption-key"
signing-secret: "your-signing-secret"
---
# license-server-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: license-server
labels:
app: license-server
spec:
replicas: 2
selector:
matchLabels:
app: license-server
template:
metadata:
labels:
app: license-server
spec:
containers:
- name: license-server
image: your-org/license-server:latest
ports:
- containerPort: 3001
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3001"
- name: ADMIN_API_KEY
valueFrom:
secretKeyRef:
name: license-server-secrets
key: admin-api-key
- name: ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: license-server-secrets
key: encryption-key
- name: LICENSE_SIGNING_SECRET
valueFrom:
secretKeyRef:
name: license-server-secrets
key: signing-secret
- name: DB_FILE
value: "/data/licenses.db"
volumeMounts:
- name: data-volume
mountPath: /data
livenessProbe:
httpGet:
path: /v1/
port: 3001
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /v1/
port: 3001
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: license-server-pvc
---
# license-server-service.yaml
apiVersion: v1
kind: Service
metadata:
name: license-server-service
spec:
selector:
app: license-server
ports:
- protocol: TCP
port: 80
targetPort: 3001
type: ClusterIPDeploy to Kubernetes:
kubectl apply -f license-server-secret.yaml
kubectl apply -f license-server-deployment.yamlVerification
Health Check
Verify the server is running:
curl http://localhost:3001/v1/Expected response:
{
"message": "License API is running",
"version": "1.0.0"
}Admin Authentication Test
Test admin endpoints:
curl -H "Authorization: Bearer your-admin-api-key" \
http://localhost:3001/v1/admin/statsExpected response:
{
"totalLicenses": 0,
"activeLicenses": 0,
"revokedLicenses": 0,
"totalActivations": 0,
"recentActivations": []
}Configuration Options
Database Configuration
The License Server uses SQLite by default. Configure the database location:
# Relative path
DB_FILE=./data/licenses.db
# Absolute path
DB_FILE=/var/lib/license-server/licenses.db
# In-memory (development only)
DB_FILE=:memory:Database Backups
For production deployments:
- Regular backups of the SQLite database file
- Consider database replication for high availability
- Monitor database size and performance
Rate Limits
Rate limits are fixed values set in the server implementation and are not configurable via environment variables.
Logging Configuration
Configure logging levels and output:
# Log level: error, warn, info, debug
LOG_LEVEL=info
# Log format: json or pretty
LOG_FORMAT=json
# Log file (optional, logs to stdout by default)
LOG_FILE=/var/log/license-server.logNext Steps
Now that your License Server is running:
- Set up authentication - Configure admin API keys
- Understand rate limits - Learn about request quotas
- Issue your first license - Create a test license
- Integrate with your app - Add license verification
Troubleshooting
Common Issues
Port already in use:
# Check what's using port 3001
lsof -i :3001
# Use a different port
PORT=3002 npm startDatabase permission errors:
# Ensure the data directory exists and is writable
mkdir -p ./data
chmod 755 ./dataInvalid encryption key:
# Encryption key must be exactly 64 hex characters (32 bytes)
node -e "
const key = 'your-key-here';
console.log('Key length:', key.length, '(should be 64)');
console.log('Valid hex:', /^[0-9a-f]{64}$/i.test(key));
"Support
If you encounter issues:
- Check the troubleshooting guide
- Review server logs for error messages
- Open an issue on GitHub
- Search Stack Overflow