20. Hosting and Deployment

From Development to Production

This chapter covers deployment patterns for mORMot 2 applications, from simple stand-alone executables to complex multi-server architectures with CDN integration.


20.1. Platform Support

20.1.1. Operating Systems

mORMot 2 natively supports:

Platform Compiler Notes
Windows (32/64-bit) Delphi, FPC Full support including http.sys
Linux (x86_64, aarch64) Delphi 12+, FPC Recommended for servers
macOS (x86_64, aarch64) Delphi, FPC Development and servers
FreeBSD FPC Server deployments
Android Delphi, FPC Client applications

20.1.2. Resource Requirements

mORMot applications are extremely efficient:

Component Typical Requirement
RAM 50-200 MB for typical server
CPU Minimal; single-core sufficient for most workloads
Storage SQLite3 database + application (~5-50 MB)
Network Standard HTTP/HTTPS ports
Compared to traditional stacks (IIS + .NET + SQL Server), mORMot requires:

20.2. Deployment Patterns

20.2.1. Stand-Alone Application

The simplest deployment — a single executable:

┌─────────────────────────────────────┐
│           Application               │
│  ┌─────────┐  ┌─────────────────┐   │
│  │ Client  │──│  Server (HTTP)  │   │
│  │  Code   │  │  + ORM + SOA    │   │
│  └─────────┘  └─────────────────┘   │
│                     │               │
│              ┌──────┴──────┐        │
│              │  SQLite3    │        │
│              │  Database   │        │
│              └─────────────┘        │
└─────────────────────────────────────┘

Perfect for:

// In-process server access
var
  Server: TRestServerDB;
  Client: TRestClientDB;
begin
  Server := TRestServerDB.Create(Model, 'data.db3');
  Client := TRestClientDB.Create(Server);
  // Client and server in same process
end;

20.2.2. Shared Server

One server handling both ORM and SOA:

┌──────────┐        ┌──────────┐
│ Client 1 │───┐    │ Client 2 │
│ (Delphi) │   │    │  (AJAX)  │
└──────────┘   │    └──────────┘
               │         │
               ▼         ▼
         ┌─────────────────────┐
         │    HTTP Server      │
         │  ┌───────────────┐  │
         │  │   ORM + SOA   │  │
         │  └───────┬───────┘  │
         │          │          │
         │    ┌─────┴─────┐    │
         │    │  SQLite3  │    │
         │    └───────────┘    │
         └─────────────────────┘

Suitable for:

20.2.3. Separated Services (DMZ)

For security-sensitive deployments:

    Internet                    DMZ                    Internal Network
       │                         │                           │
┌──────┴──────┐           ┌──────┴──────┐            ┌───────┴───────┐
│  AJAX/Web   │           │  Services   │            │     ORM       │
│   Clients   │─────────▶ │   Server    │──────────▶ │    Server     │
└─────────────┘           │  (Stateless)│            │  + Database   │
                          └─────────────┘            └───────────────┘
                                │
                          ┌─────┴─────┐
                          │  Firewall │
                          └───────────┘

Benefits:

Implementation:

// Services server (in DMZ)
Server := TRestServerFullMemory.Create(Model);
Server.ServiceDefine(TMyService, [IMyService], sicShared);
// Connect to internal ORM server
Server.RemoteDataCreate(InternalOrmClient, TOrmArticle);

// Internal ORM server
OrmServer := TRestServerDB.Create(Model, 'data.db3');

20.2.4. Microservices

Multiple specialized servers:

┌─────────┐   ┌─────────┐   ┌─────────┐
│ Client  │   │ Client  │   │ C│
└────┬────┘   └────┬────┘   └────┬────┘
     │             │             │
     └──────┬──────┴──────┬──────┘
            ▼             │
     ┌──────────────┐     │
     │   Gateway    │     │
     │   Server     │     │
     └──────┬───────┘     │
            │             │
     ┌──────┼──────┬──────┼──────┐
     ▼      ▼      ▼      ▼      ▼
┌────────┐ ┌────────┐ ┌────────┐
│ Auth   │ │ Orders │ │ Reports│
│ Service│ │ Service│ │ Service│
└────────┘ └────────┘ └────────┘

Each service:


20.3. Windows Deployment

20.3.1. Console Application

Simplest deployment for development:

program MyServer;
{$APPTYPE CONSOLE}
begin
  // Server initialization
  WriteLn('Server running on http://localhost:8080');
  ReadLn;  // Wait for Enter to stop
end.

20.3.2. Windows Service

For production deployment:

program MyServerService;

uses
  mormot.app.daemon;

type
  TMyDaemon = class(TDaemon)
  protected
    fServer: TRestServerDB;
    fHttp: TRestHttpServer;
    procedure DoStart; override;
    procedure DoStop; override;
  end;

procedure TMyDaemon.DoStart;
begin
  fServer := TRestServerDB.Create(Model, 'data.db3');
  fHttp := TRestHttpServer.Create('8080', [fServer]);
end;

procedure TMyDaemon.DoStop;
begin
  fHttp.Free;
  fServer.Free;
end;

begin
  TDaemonService.Create(TMyDaemon, 'MyServer', 'My mORMot Server');
  TDaemonService.RunAsService;
end.

Service management:

:: Install service
MyServerService.exe /install

:: Start service
net start MyServer

:: Stop service
net stop MyServer

:: Uninstall service
MyServerService.exe /uninstall

20.3.3. HTTP.SYS Configuration

For best Windows performance, use http.sys:

HttpServer := TRestHttpServer.Create('8080', [Server], '+',
  useHttpApiRegisteringUri);  // Uses http.sys

URL reservation (run as Administrator):

netsh http add urlacl url=http://+:8080/ user=Everyone

SSL certificate binding:

netsh http add sslcert ipport=0.0.0.0:443 ^
  certhash=YOUR_CERT_THUMBPRINT ^
  appid={YOUR_APP_GUID}

20.4. Linux Deployment

20.4.1. Systemd Service

Create /etc/systemd/system/mormot-server.service:

[Unit]
Description=mORMot Server
After=network.target

[Service]
Type=simple
User=mormot
Group=mormot
WorkingDirectory=/opt/mormot
ExecStart=/opt/mormot/myserver
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Management:

# Enable and start
sudo systemctl enable mormot-server
sudo systemctl start mormot-server

# Check status
sudo systemctl status mormot-server

# View logs
sudo journalctl -u mormot-server -f

20.4.2. Docker Deployment

Dockerfile:

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y \
    libsqlite3-0 \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY myserver /app/
COPY Views/ /app/Views/

EXPOSE 8080
USER nobody:nogroup

CMD ["/app/myserver"]

docker-compose.yml:

version: '3.8'
services:
  mormot-server:
    build: .
    ports:
      - "8080:8080"
    volumes:
      - ./data:/app/data
    restart: unless-stopped
    environment:
      - MORMOT_LOG_LEVEL=debug

20.4.3. Performance Tuning

System limits (/etc/security/limits.conf):

mormot soft nofile 65535
mormot hard nofile 65535

Kernel parameters (/etc/sysctl.conf):

net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535

20.5. Reverse Proxy Configuration

20.5.1. Nginx

upstream mormot {
    server 127.0.0.1:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://mormot;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Connection "";

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # Static files served by Nginx
    location /.static/ {
        alias /opt/mormot/static/;
        expires 30d;
    }
}

20.5.2. Apache

<VirtualHost *:80>
    ServerName api.example.com

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/

    # WebSocket support
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
</VirtualHost>

20.5.3. SSL Termination

With Let's Encrypt (certbot):

sudo certbot --nginx -d api.example.com

Or manually in Nginx:

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    location / {
        proxy_pass http://127.0.0.1:8080;
        # ... proxy settings
    }
}

20.6. CDN Integration

20.6.1. Architecture

┌─────────┐     ┌─────────┐     ┌─────────┐
│ Client  │     │ Client  │     │ Client  │
│  (US)   │     │  (EU)   │     │ (Asia)  │
└────┬────┘     └────┬────┘     └────┬────┘
     │               │               │
     ▼               ▼               ▼
┌─────────┐     ┌─────────┐     ┌─────────┐
│ CDN     │     │ CDN     │     │ CDN     │
│ Edge US │     │ Edge EU │     │Edge Asia│
└────┬────┘     └────┬────┘     └────┬────┘
     │               │               │
     └───────────────┼───────────────┘
                     │
                     ▼
              ┌─────────────┐
              │   Origin    │
              │   Server    │
              │  (mORMot)   │
              └─────────────┘

20.6.2. Cache Headers

Enable caching for appropriate endpoints:

procedure TMyServer.GetPublicData(Ctxt: TRestServerUriContext);
begin
  Ctxt.Returns(Data, HTTP_SUCCESS,
    'Content-Type: application/json'#13#10 +
    'Cache-Control: public, max-age=300',  // 5 minutes
    True);  // Handle304NotModified
end;

20.6.3. Cloudflare Configuration

Page Rules:

Important: Authenticated endpoints must bypass cache:

// Disable authentication for cacheable endpoints
Server.ServiceMethodByPassAuthentication('GetPublicData');

20.7. Monitoring and Logging

20.7.1. Built-in Logging

// Configure logging
with TSynLog.Family do
begin
  Level := LOG_VERBOSE;
  DestinationPath := '/var/log/mormot/';
  RotateFileCount := 10;
  RotateFileSizeKB := 10240;  // 10 MB per file
end;

20.7.2. Health Checks

procedure TMyServer.Health(Ctxt: TRestServerUriContext);
var
  Status: TDocVariantData;
begin
  Status.InitObject([
    'status', 'ok',
    'timestamp', NowUtc,
    'uptime', GetTickCount64 - fStartTime,
    'connections', fActiveConnections
  ]);
  Ctxt.Returns(Status.ToJson);
end;

// Register without authentication
Server.ServiceMethodByPassAuthentication('Health');

20.7.3. Metrics Endpoint

procedure TMyServer.Metrics(Ctxt: TRestServerUriContext);
var
  Info: TDocVariantData;
begin
  Info.InitObject([
    'requests_total', fRequestCount,
    'requests_per_second', fRequestsPerSecond,
    'memory_mb', GetHeapStatus.TotalAllocated div (1024*1024),
    'db_connections', Server.DB.ConnectionCount,
    'active_sessions', Server.Sessions.Count
  ]);
  Ctxt.Returns(Info.ToJson);
end;

20.8. High Availability

20.8.1. Load Balancing

Multiple mORMot instances behind a load balancer:

upstream mormot_cluster {
    least_conn;
    server 10.0.0.1:8080 weight=5;
    server 10.0.0.2:8080 weight=5;
    server 10.0.0.3:8080 backup;
    keepalive 32;
}

20.8.2. Session Affinity

For stateful services, use sticky sessions:

upstream mormot_cluster {
    ip_hash;  # Same client always goes to same server
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
}

Or use external session storage (Redis):

// Store sessions externally
Server.SessionClass := TAuthSessionRedis;

20.8.3. Database Replication

For high availability with SQLite3:

// Master server
MasterServer := TRestServerDB.Create(Model, 'master.db3');

// Replica servers (read-only)
ReplicaServer := TRestServerDB.Create(Model, 'replica.db3');
ReplicaServer.DB.OpenV2('replica.db3', SQLITE_OPEN_READONLY);

Or use external databases with built-in replication (PostgreSQL, MySQL).


20.9. Security Checklist

20.9.1. Network Security

20.9.2. Application Security

20.9.3. Server Hardening


Summary

mORMot 2 deployment options:

Scenario Recommended Setup
Development Console application
Windows Production Windows Service + http.sys
Linux Production systemd + Nginx
Containers Docker with Alpine/Debian
High Traffic Load balancer + CDN
High Availability Cluster + session sharing
Key takeaways:

Navigation

Previous Index Next
Chapter 19: MVC/MVVM Web Applications Index Chapter 21: Security