Portal Installation Guide

© 2023 MonkeyProof Solutions BV



T: +31 (0)76 8200 314

Table of contents

Portal Installation Guide

Table of contents

Azure AD Configuration

NGINX Configuration

PHP Configuration

Mail Configuration



The Simian Portal Server is an application written in PHP 8.

The Portal Server has the following main tasks:

  1. Web based Admin Portal for:
    • Configuring deployed applications
    • Managing application access
    • Managing available front-end versions
    • Providing log access
  2. Web based User Portal for:
    • Listing the authorized applications and relevant information
  3. Deliver "static" content (the generic frontend application versions) to the client browser
  4. Manage user sessions including:
    • Authentication/authorization
    • Mapping of application instances to the appropriate back-end endpoints
    • Data flow

Configurations are stored in a json file and, if applicable, configuration/application specific data in additional supporting files.

No SQL database is required.

System Requirements

This paragraph provides some guidance in server hard- and software requirements.

The server does not need to be a high performance computing server, the back-end server(s) do the hard computational work.

Depending on the type of deployed applications, the dataflow can be significant and needs to be managed in-memory.

The duration of computations and the number of simultaneous users need to be accomodated. If there are many users doing many long-running computations, the server resources (memory) and number of simultaneous PHP processes need to be scaled up accordingly.

Server Hardware Requirements

Server Type

The server is provided as a Docker image. Hence any server that is able to deploy docker images can be used.

CPU and Memory

As for any web application, you should size your server based on the traffic on the site.

Typically analytics applications deployed through the Portal Server are quite data intensive. During interaction with the server all data, including file up- and downloads, lives in memory in the Portal Server.

It is recommended to assign 512MB per simultaneous active server request. If applications do not do significant file up- and download this can be reduced.


The Portal Server Docker image is less than 150 MB.

The main driving factors behind required additional disk space are:

  1. Temporary storage of up- and downloads.
  2. The amount of front-end versions to be supported (current production versions < 10 MB each).
  3. Logging enabled in combination with traffic through the server.

Logging directory can be configured outside the installation directory (recommended).

Particularly when traffic logging (intended for debugging purposes only) is enabled for an application log files can grow rapidly.

Apart from disk space for file storage and logging it is recommended to allocate at least 1GB of diskspace for the application itself.

Client Requirements

The Portal Server should run on all recent browsers in the market, including but not limited to:

  • Chrome
  • Firefox
  • Edge
  • Safari

Development and testing is primarily being done with Chrome and Firefox.

New Installation

This chapter explains how to perform a new installation of Portal Server.

  1. Start the docker container. Replace <url> with the public URL intended for the server, <server name> with the server name used in the license and specify the actual path to the license file in the volume mount.

    Windows cmd:

    docker run ^
        --name=simian-portal-server ^
        --env=SIMIAN_PORTAL_EXTERNAL_URL=https://<url> ^
        --env=SIMIAN_NGINX_SERVER_NAME=<server name> ^
        -p 443:443 ^
        -p 80:80 ^
        -v C:/path/to/your-license-file.txt:/var/simian_portal/license.txt ^
        -d docker-registry.monkeyproof.lan/simian-portal:latest

    Linux bash:

    docker run \
        --name=simian-portal-server \
        --env=SIMIAN_PORTAL_EXTERNAL_URL=https://<url> \
        --env=SIMIAN_NGINX_SERVER_NAME=<server name> \
        -p 443:443 \
        -p 80:80 \
        -v /absolute/path/to/your-license-file.txt:/var/simian_portal/license.txt \
        -d docker-registry.monkeyproof.lan/simian-portal:latest
  2. Verify that the server is running by opening a browser and navigating to https://<url>.

    1. You will probably get a security warning because the HTTPS certificate cannot be validated. Accept the risk and continue.
    2. The login page should now be shown. Log in with username admin and password admin.


The Simian Portal server can be configured using environment variables that can be specified as arguments of the docker run command using the --env flag.

See https://docs.docker.com for more information on specifying environment variables in Docker.


The default Nginx configuration, runs a HTTPS webserver with a generated openssl certificate. To provide your own certificate, mount it at /etc/nginx/ssl/simian_suite_portal.crt (see Volume Mappings).

SIMIAN_NGINX_SERVER_NAMENginx server namelocalhost
SIMIAN_NGINX_CLIENT_MAX_BODY_SIZEMaximum request body size256m
SIMIAN_NGINX_CONNECT_TIMEOUTTime-out for connecting [s]5
SIMIAN_NGINX_SEND_TIMEOUTTime-out for sending request [s]60
SIMIAN_NGINX_READ_TIMEOUTTime-out for response [s]3600


SIMIAN_PHP_MEMORY_LIMITMaximum memory usage of the PHP process512M
SIMIAN_PHP_POST_MAX_SIZEMaximum request body size256M
SIMIAN_PHP_TIMEZONEPHP server time zoneEurope/Amsterdam
SIMIAN_PHP_UPLOAD_MAX_FILESIZEMaximum file upload size128M


SIMIAN_PORTAL_EXTERNAL_URLExternal URL (add the port when not using defaults 80 or 443)https://localhost
SIMIAN_PORTAL_LOGOLogo to show on the login page etc. 1simian-logo-icon.svg
SIMIAN_PORTAL_FAVICONLogo to show on the tabs 1simian-logo-icon-circle.svg
SIMIAN_PORTAL_NAVBAR_LOGOLogo to show in the portal navigation bar 1simian-logo-icon-light.svg
SIMIAN_PORTAL_TITLETitle to show in the portal navigation barSimian Portal
SIMIAN_PORTAL_SUBTITLESubtitle to show in the portal navigation bar<undefined>
SIMIAN_ENABLE_CHECKMakes the check.php page public0

Authentication Modes

The portal currently supports four authentication modes that can be selected by setting SIMIAN_PORTAL_AUTH_TYPE. The four modes are:

  1. anonymous: Anonymous mode allows users to use the portal and applications without authentication. When a session expires it cannot be restored and data may be lost.
  2. managed: Basic user management included in the portal. See Managed.
  3. ldap: Authentication against Microsoft Active Directory. See LDAP.
  4. azure_ad: Authentication against Azure Active Directory. See Azure AD.
SIMIAN_PORTAL_AUTH_TYPEThe used authentication methodmanaged


Anonymous mode allows access to every user without authentication. Set SIMIAN_PORTAL_AUTH_TYPE to anonymous to enable anonymous mode.

Note: Anonymous mode is for testing purposes only. It should not be used in production.


The managed mode provides basic stand-alone user management in the admin portal. Users can be created, added to groups in the admin portal and can be invited via email.

Set SIMIAN_PORTAL_AUTH_TYPE to managed to enable managed mode.

To store the groups and users configurations in a permanent location (outside the docker container), mount a folder at /var/simian_portal/config/users (see Volume Mappings).

In order to send the invitation emails, PHPMailer must be configured using the settings SIMIAN_MAIL_*, or by providing a custom PHPMailer configuration file (see Advanced).

Users in the admin group have access to the Admin Portal. To aid initial configuration a user admin with password admin is available in the default configuration. It is recommended to invite yourself as member of the admin group and after successful login remove the default admin user.

SIMIAN_MAIL_FROM_ADDRESSThe from address for sending the invite<undefined>
SIMIAN_MAIL_FROM_NAMEThe from name for sending the inviteSimian Portal
SIMIAN_MAIL_SMTP_HOSTSMTP server address<undefined>
SIMIAN_RESET_ADMIN_PASSWORDMakes reset_admin_password.php public0

Note: reset_admin_password.php allows all users to reset the admin password. Do not forget to disable after use.


The Portal Server can be configured to authenticate against Microsoft Active Directory. LDAP integration is enabled by setting the SIMIAN_PORTAL_AUTH_TYPE to ldap.

The connection with the LDAP server is set up using the standard PHP LDAP plugin and can be configured using the settings in the table below.

The default configuration has TLS enabled for secure communications. Mount the Certificate Authority file in /var/simian_portal/config/certs/ca-cert.crt such that the certificate of the LDAP server can be validated (see Volume Mappings).

In case a more advanced LDAP options are required, a custom config.php is needed to provide them (see Advanced). More information about configuring the PHP LDAP plugin can be found here https://www.php.net/manual/en/ldap.constants.php.

SIMIAN_PORTAL_LDAP_AUTH_TIMEOUTAuthentication timeout1800
SIMIAN_PORTAL_LDAP_HOSTHostname of the LDAP server<undefined>
SIMIAN_PORTAL_LDAP_USER_DOMAINYour microsoft domain name.<undefined>
SIMIAN_PORTAL_LDAP_BASE_DNTop level from where searches are being done in the LDAP server<undefined>
SIMIAN_PORTAL_LDAP_USERS_DNDistinguished name where searches will be exected for user<undefined>
SIMIAN_PORTAL_LDAP_USER_NAME_ATTRIBUTEUser attribute containing the name used for authenticationsAMAccountName
SIMIAN_PORTAL_LDAP_USER_PHOTO_ATTRIBUTEAttribute containing the user photothumbnailphoto
SIMIAN_PORTAL_LDAP_USER_DISPLAYNAME_ATTRIBUTEAttribute containing the user display namedisplayname
SIMIAN_PORTAL_LDAP_GROUP_NAME_ATTRIBUTEAttribute being searched for to identify user membershipsAMAccountName
SIMIAN_PORTAL_LDAP_READONLY_USERRead-only user 2<undefined>
SIMIAN_PORTAL_LDAP_READONLY_PASSWORDRead-only user password 2<undefined>
SIMIAN_PORTAL_LDAP_PORTAL_PARENT_GROUPSDirect subgroups are selectable in application configurations 3[]
SIMIAN_PORTAL_LDAP_PORTAL_ADMIN_GROUPSList of groups with admin portal access 3[]

The LDAP integration only uses user credentials for authentication. All other communication, e.g. for retrieval of user details and querying group membership, happens with a read-only LDAP user with username SIMIAN_PORTAL_LDAP_READONLY_USER and password SIMIAN_PORTAL_LDAP_READONLY_PASSWORD.


The value must be a list of strings, e.g: ['admin', 'consulting']. Leave unspecified to not restrict groups.

Azure AD

The Azure AD authorization mode allows users to authenticate using their Microsoft Azure AD account. When the user is already signed in, the authorization happens without user interaction. Otherwise, the user is redirected to the Microsoft login page.

Azure integration is enabled by setting the SIMIAN_PORTAL_AUTH_TYPE to azure_ad.

SIMIAN_PORTAL_AZURE_AD_TENANT_IDAzure Active Directory Tenant ID 4<undefined>
SIMIAN_PORTAL_AZURE_AD_CLIENT_IDClient application ID provided by Azure<undefined>
SIMIAN_PORTAL_AZURE_AD_CLIENT_SECRETClient Secret provided by Azure 5<undefined>
SIMIAN_PORTAL_AZURE_AD_CERT_THUMBPRINTThumbprint for certificate uploaded to Azure 6<undefined>
SIMIAN_PORTAL_AZURE_AD_PORTAL_ADMIN_GROUPSDirect subgroups are selectable in application configurations 7[]
SIMIAN_PORTAL_AZURE_AD_PORTAL_PARENT_GROUPSList of groups with user portal access 7[]

With Multitenant apps you can use "common" as Tenant ID, but using specific endpoint is recommended when possible.


Remember that this expires someday unless you have set it not to do so. When using private key and certificate for authentication, the client secret must not be set.


The private key corresponding to the certificate must be volume mapped to /var/simian_portal/config/certs/portal.key.


The value must be a list of strings, e.g: ['f2884a1c-62e8-425c-b32a-25881f375823', 'ea2d7058-a486-46c5-bc4b-7c7fc14db767']. Leave unspecified to not restrict groups.

Volume Mappings

Volume mappings can be used to (persistently) store files outside the Docker container. This has multiple advantages:

  • Settings are available for back-up.
  • Settings persist when upgrading the Simian Portal server to a newer version.

Volume mappings can be specified using the --volume flag of the docker command.

The -v or --volume option consists of three fields, separated by colon characters (:). The fields must be in the correct order, and the meaning of each field is not immediately obvious.

  • In the case of named volumes, the first field is the name of the volume, and is unique on a given host machine. For anonymous volumes, the first field is omitted.
  • The second field is the path where the file or directory are mounted in the container.
  • The third field is optional, and is a comma-separated list of options, such as ro.

See https://docs.docker.com for more information on specifying volume mappings in Docker.

Recommended volume mappings are:

  • Nginx logs: $PORTAL_ROOT/logs/nginx:/var/log/nginx
  • PHP logs: $PORTAL_ROOT/logs/php:/var/simian_portal/log:
  • Application configurations: $PORTAL_ROOT/userconfig/persistent/config/configurations:/var/simian_portal/config/configurations
  • Users and groups configurations (managed mode): $PORTAL_ROOT/userconfig/persistent/config/users:/var/simian_portal/config/users
  • Front-end versions: $PORTAL_ROOT/userconfig/persistent/apps:/var/simian_portal/public/apps
  • PHP sessions: $PORTAL_ROOT/userconfig/persistent/userSessionsData:/var/simian_portal/userSessionsData

Volume mappings can also be used to provide certificates for SSL.

  • path/to/my/certs/certs.crt:/etc/nginx/ssl/simian_suite_portal.crt
  • path/to/my/certs/key.key:/etc/nginx/ssl/simian_suite_portal.key
  • path/to/my/certs/cacert.pem:/etc/ssl/certs/cacert.pem


If the settings provided in this chapter are not sufficient, it is possible to provide custom configuration files. These files need to be mounted in the correct locations.

NameDescriptionDefaultMount volume
SIMIAN_CUSTOM_NGINX_CONFUse custom nginx.conf0/etc/nginx/nginx.conf
SIMIAN_CUSTOM_PHP_INIUse custom php.ini0/etc/php81/conf.d/custom.ini
SIMIAN_CUSTOM_CONFIG_PHPUse custom config.php0/var/simian_portal/config/config.php
SIMIAN_CUSTOM_MAIL_CONFIG_PHPUse custom mail_config.php0/var/simian_portal/config/mail_config.php



Note: Prior to upgrading the webserver, it is strongly recommended to notify the users about the scheduled maintenance and urge them to close their sessions. All sessions will be removed during the upgrade.

  1. Prevent user interaction (if possible) - starting in v1.5.0 the Maintenance Mode option in the Admin Portal can be used for this purpose.
  2. Verify that there are no busy instances (no *.busy in the userSessionData) - starting in v1.5.0 the Instances Management panel in the Admin Portal can be used for this purpose.
  3. Stop the webserver.
  4. Remove the contents of the userSessionData directory.

Note: The Instances Management functionality in the Admin Portal is able to close and cleanup non-busy sessions and notify the back-end servers. When user session folders are deleted manually, artifacts may remain on the back-end server(s).

Upgrade Webserver

  1. Pull the new image from the Docker registry: docker pull.
  2. Start the docker container from the updated image.

Azure AD Configuration

For the purpose of this guide:

ConceptValue / Meaning
Azure AD Enterprise Application NameSimian Portal
Simian PortalThe Simian server product by Monkeyproof Solutions that serves to manage and make available Simian Apps to users.
External Portal URLThe URL the Simian Portal is being served at to the users, in this document:
Simian User PortalThe part of the Simian Portal that lists applications for users, typically hosted on:
Simian Admin PortalThe part of the Simian Portal that allows for admin tasks, typically hosted on:
Simian App(lication)A MATLAB or Python application deployed on the Simian Portal

Starting points

  • Simian Portal Authentication and Authorization with Azure AD is based on the Azure AD OAuth2 Client Credentials flow.

    Client Secret and Client Certificate credentials are supported.

    Additional measures may be applied to Azure AD Enterprise Applications such as conditional access. These are strictly Azure AD side settings that are not relevant to the functioninality of Simian Portal and therefore beyond the scope and support of Simian Portal Azure AD configuration.

  • The Simian Portal Azure AD Enterprise Application requires the following delegated API Permissions:

    • User.Read
    • Group.Read.All
    • GroupMember.Read.All

    Delegated permission means that a user needs to be signed-in in order for Simian Portal to be able to access Azure AD information.

  • For Azure AD Enterprise Application authentication (in general thus not Simian Portal specific) users must be either:

    • Directly assigned to the Azure AD Enterprise Application, or
    • A direct member of a group assigned to the Azure AD Enterprise Application.
  • For the configuration of the Azure AD Enterprise Application the following information is required:

    • The External Portal URL of the Simian Portal.
    • A certificate and private key if Simian Portal authentication is to be configured for Client Certificate credentials.
  • For the configuration of Simian Portal the following Azure AD information must be collected from Azure AD:

    • Tennant ID
    • Client ID
    • Client Secret, OR Client Certificate Thumbprint
    • Object ID(s) of Portal Parent Group(s)
    • Object ID(s) of Portal Admin Group(s)

Configuring Simian Portal Access in Azure AD

The following sections provide instructions for setting up Azure AD for integration with Simian Portal for authentication and authorization.

Tenant ID

On the Azure Active Directory admin center, go to

Tenant ID

Take note of the the Tenant ID and use it to specify either:

  • Docker: the SIMIAN_PORTAL_AZURE_AD_TENANT_ID environment variable.
  • config.php: the $azure_ad_config['ad_tenant'] variable.

Azure AD Enterprise Application

The first step is to create an Azure AD Enterprise Application. This application is the Azure counterpart of the Simian Portal in PHP.

To define the Azure AD Enterprise Application go to

Enterprise applications

New application

Create your own application

and specify the name of the application

Application name

and click the Create button.

After a few moments, the application overview is opened.

Application ID

Take note of the Application ID and use it to specify either:

  • Docker: the SIMIAN_PORTAL_AZURE_AD_CLIENT_ID environment variable.
  • config.php: the $azure_ad_config['client_id'] variable.

Setup Identification

In order for the Simian Portal PHP server to access the authentication service, it needs to identify itself using credentials, which can be either:

  • a client secret (less secure)
  • a certificate with a private key (more secure)

Please refer to Azure AD documentation for the exact differences.

To setup a credentials, go to


and click the application registration link.

application registration

Then, click

Certificates & secrets

to reach the certificates & secrets page.

Client secrets

Client Secret

To identify using a certificate, skip this section.

To configure a client secret, click

New client secret

fill in the description

Create secret

and click the Add button. A new secret is added to the list.

New secret

Take note of the value (not the Secret ID) immediately after creation, it is shown only once and use it to specify either:

  • Docker: the SIMIAN_PORTAL_AZURE_AD_CLIENT_SECRET environment variable.
  • config.php: the $azure_ad_config['client_secret'] variable.

The setup for identification using a secret is now complete. Skip the next section.

Certificate and Private Key

To configure identification via a certificate, first obtain or create a certificate with a private key.

There are many ways to create certificates and the preferred method may vary depending on company policies. Check with the responsible department in your organization.

Example (self signed certificate):

(This should work on any Windows system that has Git installed. The equivalent openssl command can be issued on a linux system that has openssl installed.)

"C:\Program Files\Git\usr\bin\openssl.exe" req ^
	-new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 ^
	-keyout portal.key ^
	-out portal.crt

The next step is to upload the certificate. Go to the certificates tab

Certificates tab

and click

Upload certificate

choose the certificate file to upload and specify a description

Certificate specifications

and click the Add button. The uploaded certificate is added to the list.

Certificate thumbprint

Take note of the thumbprint (note: columns are resizable if it is not fully visible) and use it to specify either:

  • Docker: the SIMIAN_PORTAL_AZURE_AD_CERT_THUMBPRINT environment variable.
  • config.php: the $azure_ad_config['cert_thumbprint'] variable.

The matching private key must be specified through either:

  • Docker: by means of a volume mapping of the private key file on the host to /var/simian_portal/config/certs/portal.key.
  • config.php: the $azure_ad_config['cert_private_key'] variable.

Configure Authentication in the Azure AD Enterprise Application

Go to


and click

Add a platform

and choose to create a Web application

Web application

and specify the Redirect URI of the portal, which must match the external url configured in either:

  • Docker: the SIMIAN_PORTAL_EXTERNAL_URL environment variable.
  • config.php: the $portal['external_url'] variable.

Configure Web

Optionally, you may want to specify the Front-channel logout URL (the external url + /logout). Then, click the Configure button.

Next, in the Advanced Settings, enable Allow public client flows.

Advanced settings

Then, click the Save button.

Set the API Permissions

Go to

API permissions

Add a permission

and choose

Microsoft Graph

followed by

Delegated permissions

Then, select Group.Read.All, GroupMember.Read.All and User.Read and click the Add permissions button.

Grant consent by clicking

Grant admin consent for MSFT

and confirm.

User Groups

User groups can be used to manage which users are granted access to:

  • The Simian User Portal
  • The Simian Admin Portal
  • Individual Simian Apps

In order to determine whether access is granted, the following rules are applied:

Simian Portal Sign in

  • To be able to sign in to the Simian Portal the user must be either:
    • Directly assigned to the Azure Application, or
    • A direct members of a Groups assigned to the Azure Application.

Simian Admin portal access

  • Users that are (in)direct members of Admin Group(s) configured with either:

    • Docker: the SIMIAN_PORTAL_AZURE_AD_PORTAL_ADMIN_GROUPS environment variable.
    • config.php: the $azure_ad_config['portal_admin_groups'] variable.

    have access to the admin portal.

Simian Application access

  • Groups that are direct members of the Portal Parent Group(s) configured with either:

    • Docker: the SIMIAN_PORTAL_AZURE_AD_PORTAL_PARENT_GROUPS environment variable.
    • config.php: the $azure_ad_config['portal_parent_groups'] variable.

    are listed for Simian App access control purposes in the admin portal.

  • Users that are (in)direct members of groups configured in the Simian Apps configuration via the Simian Admin Portal have access to the respective Simian Apps.

NOTE: Azure AD Group ObjectID(s) are used for configuration purposes.

Suggested Azure AD set up

Per limitation of Azure AD Enterprose Applications only users directly assigned to the Azure AD Enterprise Application, or users that are a direct member of a group assigned to the Azure AD Enterprise Application can sign in. This causes some level of double book keeping to be necessary.

There are multiple approaches to configure Azure AD Enterprise Applications. Below the suggested approach with its pros and cons is given.

Assign only the Portal Parent Group(s) to Azure Application:

  • Advantages:
    • Only add Portal Parent Group to the Azure AD Application once. After that it is not necessary to touch the Azure Application.
    • Portal access is arranged in one place by adding users as direct member to a Portal Parent Group.
    • Portal Parent Group(s) give(s) instant overview of which users can sign in.
    • Access to Simian Apps can be granted through (in)direct membership of user groups.
  • Disadvantages:
    • All Simian Portal users must be a direct member of the Portal Parent Group, AND must be (in)direct member of user groups that grant access to Simian Apps.
Assign Portal Parent Group to Azure AD Enterprise Application

Assign Portal Parent Group to Azure AD Enterprise Application

  1. Configure the Portal Parent Group.
  2. Assign the Portal Parent Group to the Azure Application.
  3. Add all Portal Users - including Portal Admin Users - to the Portal Parent Group.
  4. Add Portal User Groups, to the Portal Parent Group.
  5. Add Portal Users to Portal User Groups as desired.
  6. Configure the Portal Admin Group.
  7. Add Portal Users to Portal Admin Group as desired.
  8. Optionally add Portal Admin Group to the Portal Parent Group (The Portal Admin Group can then be assigned to Simian App(s)).

Assign Group(s) to the Azure AD Enterprise Application

Go to

Enterprise applications

and select the Simian Portal Azure AD Enterprise Application. Then, go to

Users and groups

Assigne user/group

and click None Selected.

Select the groups that you want to assign (the Portal Parent Group in the suggested Azure AD set up)

Users and groups

and click the Select button. Then, to confirm, click the Assign button. Make sure that the Role assigned is Default Access.

NGINX configuration

The below is a sample nginx.conf configuration that can be used as a starting point for a custom configuration.


worker_processes                4;

error_log                       /var/log/nginx/error.log;

events {
    worker_connections          1024;

http {
    include                     mime.types;
    default_type                application/octet-stream;
    sendfile                    on;

    # No NGINX version information
    server_tokens               off;
    # No PHP (version) information
    fastcgi_hide_header         X-Powered-By;

    # SSL
    ssl_protocols               TLSv1.3;
    ssl_prefer_server_ciphers   off;

    # Compression
    gzip                        on;
    gzip_vary                   on;
    gzip_min_length             1024;
    gzip_proxied                expired no-cache no-store private auth;
    gzip_types                  text/plain text/css text/xml text/javascript application/x-javascript application/javascript application/xml application/json;
    gzip_disable                "MSIE [1-6]\.";

    fastcgi_keep_conn           off;
    fastcgi_connect_timeout     5s;
    fastcgi_send_timeout        60s;
    fastcgi_read_timeout        3600s;

    # POST
    client_max_body_size        256m;

    # Headers
    add_header                  X-Content-Type-Options nosniff;
    add_header                  Content-Security-Policy "default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline'; trusted-types angular dompurify 'allow-duplicates';";
    add_header                  X-XSS-Protection "1; mode=block";
    add_header                  X-Frame-Options "SAMEORIGIN";
    add_header                  Referrer-Policy "strict-origin";
    add_header                  Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    include                     /etc/nginx/configs/nginx.*.conf;


# HTTP server
server {
    listen          80;
    server_name     localhost;

    include         /etc/nginx/configs/local.conf;


server {    
    listen          80;
    server_name     localhost;
    return          301 https://localhost$request_uri;


server {    
    listen                      443 ssl;
    server_name                 localhost;

    ssl_certificate             /etc/nginx/ssl/simian_suite_portal.crt;
    ssl_certificate_key         /etc/nginx/ssl/simian_suite_portal.key;

    ssl_session_cache           shared:SSL:1m;
    ssl_session_timeout         5m;

    ssl_ciphers                 HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    include                     /etc/nginx/configs/local.conf;


root                    /var/simian_portal/public;

# cache static frontend version content "forever" (rather one year) 
location ~* ^/apps/browser-v[0-9\.]+(\-rc\d+)?-prod/.+\.(js|css|jpg|jpeg|png|gif|ico|swf|woff|woff2)$ {
    expires             1y;
    etag                off;
    if_modified_since   off;
    add_header          Pragma "public";
    add_header          Cache-Control "public, no-transform";

# cache static portal content for one day 
location ~* ^/(libs|doc|css|js)/.+\.(html|svg|js|css|jpg|jpeg|png|gif|ico|swf|woff|woff2)$ {
    expires             1d;
    etag                off;
    if_modified_since   off;
    add_header          Pragma "public";
    add_header          Cache-Control "public, no-transform";

location / {
    index               index.html index.php;
    try_files           $uri $uri/ /index.php$is_args$args;

location ~ \.php$ {
    if ($request_uri ~* "^(.*/)index\.php$") {
        return 301 $1;

    fastcgi_pass        unix:/run/docker.sock;
    include             fastcgi_params;
    fastcgi_index       index.php;
    fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;

# redirect server error pages to the static page /50x.html
error_page              500 502 503 504 /50x.html;
location = /50x.html {
    root                html;

# deny access to .htaccess files, if Apache's document root concurs with nginx's one
location ~ /\.ht {
    deny                all;

PHP Configuration

The below is a sample php.ini that can be used as a start point for customization.


; IonCube Loader extension ;

;zend_extension=C:\Program Files\PHP\ioncube_loader_win_8.1.dll

; Resource Limits ;

; Maximum execution time of each script, in seconds
; https://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 300

; Maximum amount of time each script may spend parsing request data. It's a good
; idea to limit this time on productions servers in order to eliminate unexpectedly
; long running scripts.
; Note: This directive is hardcoded to -1 for the CLI SAPI
; Default Value: -1 (Unlimited)
; Development Value: 60 (60 seconds)
; Production Value: 60 (60 seconds)
; https://php.net/max-input-time
max_input_time = 300

; Maximum amount of memory a script may consume
; https://php.net/memory-limit
memory_limit = 512M

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; https://php.net/post-max-size
post_max_size = 256M

; File Uploads ;

; Whether to allow HTTP file uploads.
; https://php.net/file-uploads
file_uploads = On

; Maximum allowed size for uploaded files.
; https://php.net/upload-max-filesize
upload_max_filesize = 128M

; Dynamic Extensions ;

; If you wish to have an extension loaded automatically, use the following
; syntax:
;   extension=modulename
; For example:
;   extension=mysqli
; When the extension library to load is not located in the default extension
; directory, You may specify an absolute path to the library file:
;   extension=/path/to/extension/mysqli.so
; Note : The syntax used in previous PHP versions ('extension=<ext>.so' and
; 'extension='php_<ext>.dll') is supported for legacy reasons and may be
; deprecated in a future PHP major version. So, when it is possible, please
; move to the new ('extension=<ext>) syntax.
; Notes for Windows environments :
; - Many DLL files are located in the extensions/ (PHP 4) or ext/ (PHP 5+)
;   extension folders as well as the separate PECL DLL download (PHP 5+).
;   Be sure to appropriately set the extension_dir directive.
;extension=exif      ; Must be after mbstring as it depends on it

; Module Settings ;

; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Europe/Amsterdam

; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = "/etc/ssl/certs/cacert.pem"

; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context
; option.

Mail Configuration

The mail configuration uses PHPMailer.



// PHPMailer
// https://github.com/PHPMailer/PHPMailer/wiki
use PHPMailer\PHPMailer\PHPMailer;

$mail = new PHPMailer;

$mail->SMTPDebug = 0;
$mail->Debugoutput = 'html';
$mail->Host = 'your.smtp.server';
$mail->Port = 25;
$mail->SMTPAuth = false;
$mail->SMTPAutoTLS = false;
$mail->SMTPSecure = false;
$mail->setFrom('noreply@your.portal.server', 'Your Portal Server');
// END PHPMailer


The graph below shows an overview of the supported version combinations of the Simian Suite components.

The arrows in the graph indicate required dependencies, e.g.: when running portal v0.3.1, front-end v0.6.3 needs to be installed for it to function. Similarly, if one of the application back-ends uses v1.5.0, front-end v0.7.0 is required. Any other front-end versions may be installed as desired.