Installation
Linux - Docker
- Obtain a license for Mervis DB from Energocentrum – the license number will be included in the configuration file for Mervis DB (see below)
- Determine the public IP address used to access the Docker registry at
registry.mervis.info:5556
, and provide it to Energocentrum so that access can be granted and a user account created - Log in to the Docker registry:
sudo docker login registry.mervis.info:5556
- When prompted, enter your username and password
- Create a Docker network:
sudo docker network create --driver bridge mervis-network --subnet=172.150.0.0/16
- Create a folder for data:
/mnt/bigdata/mervis_db_data/mervis_db
- Create folders for configuration files:
/mnt/bigdata/cfg/mervis_db
/mnt/bigdata/cfg/mervis_db/license
- Create a folder for logs:
/mnt/bigdata/logs/
- Prepare the configuration file, which must include the admin username/password and a valid license number:
- /mnt/bigdata/cfg/mervis_db/appsettings.json
{ "Admin": { "User": "db_admin_login", //Important - define your own "Password": "db_admin_password" //Important - define your own }, "InstanceName": "mervis_db", "IndexFactoryType": "ESG.Db.Server.DataStorage.FileBackend.Indexing.DiskIndexFactory", "InfrastructureDataPath": "/mnt/bigdata/mervis_db_data/mervis_db/", "LogsPath": "/mnt/bigdata/mervis_db_data/mervis_db/", "PermanentFilesPath": "/mnt/bigdata/mervis_db_data/mervis_db/", "UpdateNonPrimaryKeys": true, "MaxDistributionQueueLength": 100000, "MaxVariableCount": 2000, "MaxValueCount": 50000, "GetFunctionsTimeout": 60, "MaxTotalDataSizeInPersLogQueue": 10000000, "IdealChunkDataSizeToStoreInPersLog": 1500000, "PersistentLogCompressionMethod": "Deflate", "PersistentLogForceSavePeriod": 60, "UsersFileSize": 24, "UsersFileGrowth": 20, "VariablesFileSize": 26, "VariablesFileGrowth": 21, "PersLogFileSize": 26, "PersLogFileGrowth": 24, "PermFileSetFileSize": 20, "PermFileSetFileGrowth": 20, "PermFileSize": 30, "PermFileGrowth": 22, "IndexFileSize": 25, "IndexFileGrowth": 20, "DirtyProlongation": 3600, "activeIndexCaching": false, "maxIndexCacheItems": 1000, "minIndexCacheDuration": "00:01:00", "maxIndexCacheDuration": "01:00:00", "indexCacheRefreshPeriod": "00:01:00", "WorkItemsBatchSize": 1000, "DeleteDataBatchSize": 20, "MaxGTCacheRefreshScanAllPf": true, "ServerMonitoringServerName": "localhost_mervis_db", "DbStats_Period": "00:01:00", "CallStats_Active": false, "CallStats_ApiRoot": "dbCall/", "CallStats_ServerId": "localhost_mervis_db", "CallStats_ServerHost": "localhost", "CallStats_ServerPort": 6000, "CallStats_ProtocolVersion": "VERSION_FIVE", "CallStats_MaxMessageSize": "1024", "StatServer.Enabled": false, "StatServer.IP": "localhost", "StatServer.Port": 6000, "Host": { "ServerUrl": "http://*:9876", "ServerUriRoute": "/RcWareDbAccess", "ServerId": "mervis_db", "Threads": { "MinWorkerThreads": 200, "MinCompletionPortThreads": 200, "MaxWorkerThreads": 32767, "MaxCompletionPortThreads": 1000 }, "ResponseCompressionEnabled": false, "IncludeExceptionDetailInFaults": false }, "PerformanceMonitoring": { "CheckPeriod": "00:01:00", "Cpu": { "Enabled": true }, "Memory": { "Enabled": true }, "Disk": { "Enabled": true, "Drives": ["/"] }, "GarbageCollector": { "Enabled": true } }, "Licensing": { "LicensingMode": "Online", // Online, LicenseFile "OnlineParams": { "ServiceId": "mervis_db", "ServiceBaseUri": "https://licenses.mervis.info/online", "User": "", "Password": "", "LicenseNumber": "DBXXXXXXXXXX", //Important - use the license number acquired from Energocentrum Plus, s.r.o. "LocalLicenseCheckDirectory": "/license", //license info is stored in this folder "AdditionalFilesToSend": [] } }, "StatServer": { "Enabled": false, "Uri": "http://localhost:6000", "ApplicationNameAndId": "localhost_mervis_db" }, "Swagger": { "Enabled": true }, "Logging": { "Console": { "Disabled": false, "format": { "outputFormat": "Json", "innerNewLine": "\r\n", "outerNewLine": "\r\n", "logTimeStamp": true, "logCategory": false, "fullCategory": false, "logEventId": false, "logThreadId": false } "Format": { "LogCategory": false, "FullCategory": false, "LogEventId": false, "LogThreadId": false } }, "File": { "Disabled": false, "Path": "/mnt/bigdata/logs/mervis_db.log", "NewFileOnStart": false, "Rotate": { "Interval": "day", "MaxFileSizeMB": 50, "MaxTotalSizeMB": 500, "MaxFileCount": 10 }, "format": { "outputFormat": "Text", "innerNewLine": "\r\n", "outerNewLine": "\r\n", "logTimeStamp": true, "logCategory": false, "fullCategory": false, "logEventId": false, "logThreadId": false } "Format": { "LogCategory": false, "FullCategory": false, "LogEventId": false, "LogThreadId": false } }, "Scopes": { "Default": true, "Categories": { // keys are case insensitive "system.": false, "microsoft.": false } }, "Levels": { "Default": "Warning", //"Information", //"Warning", //"Trace", "Categories": { // keys are case insensitive "system.": "None", "microsoft.": "None", "ESG.StatServer.Shared.StatServerClient": "Warning" } } } }
- Create the container:
sudo docker create --name mervis_db --network mervis-network -p 9876:9876 --restart unless-stopped -v /mnt/bigdata/cfg/mervis_db/appsettings.json:/app/appsettings.json:ro -v "/mnt/bigdata/cfg/mervis_db/license:/license" -v /mnt/bigdata/mervis_db_data:/mnt/bigdata/mervis_db_data registry.mervis.info:5556/db/mervis_db:beta
- Restart the container twice to ensure the license loads and is saved properly:
sudo docker restart mervis_db
- Administration interface is available at: http://localhost:9876/admin
- To enable data storage, create a user in the administration panel. The defined username and password will be used for storing data.
- Data API is available at: http://localhost:9876/RcWareDbAccess
- Do not expose this API publicly without encryption (e.g., Nginx reverse proxy) and secured admin interface (/admin)!
Installing Nginx for DB Admin Access
- create the directory
/mnt/bigdata/cfg/mervis_nginx/www
- create the file
/mnt/bigdata/cfg/mervis_nginx/etc/nginx/nginx.conf
with the following content:user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## log_format upstream_time '$remote_addr [$time_local] ' '"$request" $status $body_bytes_sent gzipRatio=$gzip_ratio ' 'request_time=$request_time up_response_time="$upstream_response_time"'; log_format grpc_format '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; ## # Virtual Host Configs ## ##important - we have very large bodies client_body_buffer_size 500M; client_max_body_size 250M; #enable logging at the server level! access_log off; #security server_tokens off; more_clear_headers Server; error_page 301 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 /error.html; #https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#upstream-groups ####################################### 80 server { listen 80; listen [::]:80; server_name _; index index.html index.php; root /mnt/bigdata/cfg/mervis_nginx/www; ##old API on project-storage requires "." in the header... #ignore_invalid_headers off; gzip on; gzip_types text/plain; gzip_proxied no-cache no-store private expired auth; gzip_min_length 1000; #security headers #add_header X-Content-Type-Options nosniff; #add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always; #add_header X-Frame-Options "SAMEORIGIN"; #add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' *.tile.openstreetmap.org data:; frame-src kb.mervis.info; object-src 'none';" always; location = /error.html { ssi on; internal; auth_basic off; root /mnt/bigdata/cfg/mervis_nginx/www/errors/; } # for certbot ssl location /.well-known/acme-challenge { alias /mnt/bigdata/cfg/mervis_nginx/www/.well-known/acme-challenge; } location /admin { # list of allowed IP addresses / ranges allow 127.0.0.1; allow 192.168.1.0/24; #allow 10.0.0.0/16; deny all; # Admin specific configuration... proxy_pass http://mervis_db:9876/admin; } } }
- create a Docker container:
- for access via port 80:
sudo docker create --name mervis_nginx -p 80:80 --network mervis-network --restart unless-stopped -v /mnt/bigdata/cfg/mervis_nginx/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro registry.mervis.info:5556/mervis_nginx/nginx:production
- for access via ports 80 and 443 (for secure communication, SSL certificate and config adjustments required):
sudo docker create --name mervis_nginx -p 80:80 -p 443:443 --network mervis-network --restart unless-stopped -v /etc/letsencrypt/:/etc/letsencrypt/ -v /mnt/bigdata/cfg/mervis_nginx/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro registry.mervis.info:5556/mervis_nginx/nginx:production
SPDBA – Interface for Data Storage from PLC
Mervis DB can receive data from Mervis RT using the SPDBA interface. This component is not part of Mervis DB itself – it is installed as a separate service.
- Create directories:
- cache:
/mnt/bigdata/spdba/mervis_spdba
- config:
/mnt/bigdata/cfg/spdba/mervis_spdba
- Configuration file:
- /mnt/bigdata/cfg/spdba/mervis_spdba/appsettings.json
{ "urls": "http://*:15000", //main service port "DbSaver": { "DbUri": "http://mervis_db:9876/RcWareDbAccess", "CachePath": "./data", "Compress": false }, "StatsTracker": { "RtIdExpirationPeriod": "12:00:00" }, "StatServer": { "Uri": "udp://localhost:6000?Enabled=false&ServerName=mervis_spdba&MaxMessageSize=1024" }, "Logging": { "Console": { "Disabled": false, "Format": { "LogCategory": false, "FullCategory": false, "LogEventId": false, "LogThreadId": false } }, "Levels": { "Default": "Trace", "Categories": { "system.": "None", "microsoft.": "None", "ESG.StatServer.Shared.StatServerClient": "Warning" } } }, "AllowedHosts": "*" }
- Create the Docker container:
sudo docker create --name mervis_spdba -p 15000:15000 --network mervis-network -v /mnt/bigdata/cfg/spdba/mervis_spdba/appsettings.json:/app/appsettings.json -v /mnt/bigdata/spdba/mervis_spdba:/app/data --restart unless-stopped registry.mervis.info:5556/spdba/shark_plc_spdba:beta
- Start the container:
sudo docker start mervis_spdba
- URL for PLC data storage:
Windows (obsolete)
Prerequisites
- Check Minimum Requirements
- Download the latest Mervis DB installation archive.
- Obtain a license number, e.g., RCWDBXXXXXXXXXXX. Request it from Energocentrum Plus, s.r.o..
Installation
- Download hwinfo2.zip
- Run
ESG.Licenses.HwInfo.exe
and use a valid license number to create the.hwdesc
file. - Obtain the activation file ".licact" from: https://licenses.rcware.eu/new/
- Unpack the Mervis DB files into any folder on your drive.
- Copy the
.licact
file next toESG.Db.Server.Host.exe
. - To install Mervis DB as a Windows service, run the following command from an Elevated Command Prompt:
ESG.Db.Server.Host.exe --installService --configFile ESG.Db.Server.Host.exe.config --instanceName MyMervisDbInstance
- Multiple Mervis DB instances can be installed (using the –instanceName parameter). Subject to licensing policy.
- For more options, run:
ESG.Db.Server.Host.exe --help
- Edit the configuration in
ESG.Db.Server.Host.exe.config
as needed. At minimum, set:- PermanentFilesPath
- LogsPath
- InfrastructureDataPath
- Admin username and password
- Log into the admin interface (default: http://localhost:11112/)
- Username and password can be set in
ESG.Db.Server.Host.exe.config
- Create at least one user with access to the database
- Configure the firewall to allow access to the Admin, Monitoring, and Data API as needed.
Do not expose Administration, Monitoring, or Data API to the public internet!
SPDBA Storing Data from Mervis PLC
You can store data directly from Mervis PLC into Mervis DB. A special ASP.NET interface must be installed.
ASP.NET application to convert binary data sent from Mervis PLC into SOAP calls of Mervis DB. You have to install SPDBA if you want to save data directly from Mervis PLC (UniPi, Domat, …).
Requirements
- IIS server with ASP.NET 4.5.
Configuration
Web.config
- Mervis DB settings
- URL of the MervisDB server: ../system.serviceModel/client/endpoint/@address
... <client> <endpoint address="http://localhost:9876/RcWareDbAccess" binding="basicHttpBinding" bindingConfiguration="RcWareDbAccess" contract="ESG.Db.ServerAccess.HistoryDbAccess" name="RcWareDbAccess" behaviorConfiguration="RcWareDbBehavior" /> </client> ...
- Logging
- ../system.diagnostics/../listener
- standard .NET logging, extensible in a standard way
- Metadata cache
- Path to the folder where cached metadata should be stored
... <appSettings> <add key="KeyValuePersistentStorageRoot" value="c:\temp\spdba"/> </appSettings> ...