Skip to content

Installation & Setup

Get started with the License Server API in minutes. This guide covers deployment options, configuration, and initial setup.

Quick Start

The fastest way to get started is with Docker:

bash
# 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:latest

From Source

Clone and run from source code:

bash
# 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 start

Environment Configuration

Required Environment Variables

Create a .env file with the following variables:

bash
# 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.db

Security 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:

bash
# 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:

yaml
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: local

Deploy with:

bash
# 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 -d

Kubernetes

Deploy to Kubernetes with secrets management:

yaml
# 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: ClusterIP

Deploy to Kubernetes:

bash
kubectl apply -f license-server-secret.yaml
kubectl apply -f license-server-deployment.yaml

Verification

Health Check

Verify the server is running:

bash
curl http://localhost:3001/v1/

Expected response:

json
{
  "message": "License API is running",
  "version": "1.0.0"
}

Admin Authentication Test

Test admin endpoints:

bash
curl -H "Authorization: Bearer your-admin-api-key" \
     http://localhost:3001/v1/admin/stats

Expected response:

json
{
  "totalLicenses": 0,
  "activeLicenses": 0,
  "revokedLicenses": 0,
  "totalActivations": 0,
  "recentActivations": []
}

Configuration Options

Database Configuration

The License Server uses SQLite by default. Configure the database location:

bash
# 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:

bash
# 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.log

Next Steps

Now that your License Server is running:

  1. Set up authentication - Configure admin API keys
  2. Understand rate limits - Learn about request quotas
  3. Issue your first license - Create a test license
  4. Integrate with your app - Add license verification

Troubleshooting

Common Issues

Port already in use:

bash
# Check what's using port 3001
lsof -i :3001

# Use a different port
PORT=3002 npm start

Database permission errors:

bash
# Ensure the data directory exists and is writable
mkdir -p ./data
chmod 755 ./data

Invalid encryption key:

bash
# 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: