Skip to main content

Deploy LinTO Platform Server

Just make sure...

LinTO Platform Server stack is meant to get deployed on a Docker Swarm cluster. Please read thouroughly the infrastructure setup guide and the following documentation BEFORE you run the startup script.

If you fancy using kubernetes, or other containers orchestration tools, you might adapt this proposal for your needs... Won't be too much of a hassle as this stack relies mainly on Traefik edge-router which can be deployed as an Ingress controler for K8s.

The benefit we try to raise by chosing Docker Swarm is to stick as much as we can to standard Docker / Docker Compose deployements. We hope that it would be more convinient for LinTO contributors, hackers and makers that wants to quickly deploy LinTO's tooling. Read more about those choices here

LinTO Platform Server Stack deployment tool

The tool is available here, linto-platform-stack. Please, clone this on a manager node of your Docker Swarm cluster !

This tool tries to solve all the burden of deploying LinTO's server components with our proposed Docker images (quite a complicated task otherwise...)

It mainly consists of a bash script,, that feeds Docker Swarm with the provided YML Docker Compose files. The script will also generate files in a shared folder made available on every node of the swarm cluster. Almost every user setups are wrapped in a single environement variable declarative file.

The whole point here is to rationalize all your deployement in two quick steps:

  1. Copy the template : cp dockerenv_template .dockerenv
  2. Configure the service stack options by filling-up all the mandatory environement variables in .dockerenv
  3. Run the script on a manager node of your cluster

Simple, isn't it ?

Note: [-- command args] have command arguments

    -f | --force-pull     Force all image to be pull
-r | --restart Hard restart of the stack

Repo's structure explained

├── config
│   ├── bls # Node-Red seeds
│   │   └── flowsStorage.json
│   ├── mongoseeds # MongoDB user creation
│   │   └── admin-users.js
│   ├── mosquitto # Mosquitto MQTT broker parameters
│   │   ├──
│   │   ├── mosquitto.conf
│   │   └── mosquitto_nologin.conf
│   ├── servicemanager # linto-stt-service-manager inits
│   │   ├── init.js
│   │   ├── swagger.yml
│   │   └── user.js
│   ├── tock # Tock routing overrides
│   │   └── scripts
│   │   ├──
│   │   └──
│   └── traefik # Traefik dynamic configuration files. All in this folder gets loaded when Traefik starts
│   ├── http-auth.toml
│   ├── ssl-redirect.toml
│   ├── stt-manager-path.toml
│   └── tock-path.toml
├── devcerts # Put here your cert.pem and key.pem for SSL termination
│   ├── cert.pem
│   └── key.pem
├── docs # This doc
│   └──
├── optional-stack-files # Some tools that you might start on your docker cluster
│   ├── monitoring_stack.yml
│   └── network_tool.yml
├── scripts # LinTO Platform backup and restore tools
│   ├──
│   ├──
│   ├──
│   ├──
│   └──
├── stack-files # Service declaration
│   ├── linto-docker-visualizer.yml
│   ├── linto-edge-router.yml
│   ├── linto-mongo-migration.yml
│   ├── linto-mqtt-broker.yml
│   ├── linto-platform-admin.yml
│   ├── linto-platform-bls.yml
│   ├── linto-platform-mongo.yml
│   ├── linto-platform-overwatch.yml
│   ├── linto-platform-redis.yml
│   ├── linto-platform-stt-service-manager.yml
│   └── linto-platform-tock.yml
└── # Startup script for the whole stack

NOTE : The tool's repository has to get cloned on a manager node of your Docker Swarm cluster as running the script should only happen in a manager node of your cluster.

LinTO server components - A whole stack of services

LinTO Platform pre-compiled Docker images for Linux docker orchestrated infrastructures are available in our Docker Hub registry. LinTO's DockerHub

NOTE : Our deployments currently uses Debian GNU/Linux 10 (buster) machines with Docker Swarm version 19.03.8

Every Docker image available from the hub is compiled by us from our corresponding GitHub repository with a Jenkins CI task.

i.e : linto-platform-admin docker image is built upon linto-platform-admin source repository

Docker Swarm Services configured and deployed by this tool

linto-edge-routerIngress service for your LinTO platform.Traefik 2+
linto-docker-visualizerA quick monitor of your Docker Swarm Clusterdockersamples/vizualizer
linto-mqtt-brokerMQTT server for LinTO clients connectivityeclipse-mosquitto
linto-platform-redisWeb servers sessions backendredis
linto-tock-nlp-api, linto-tock-nlu-web, linto-tock-mongo, linto-tock-mongo-setup, linto-tock-build_worker, linto-tock-ducklingThe Open Conversation Kit - LinTO's server-side NLU EngineVoyage SNCF's Tock
linto-platform-mongo, linto-platform-mongodb-migrationMongoDB Datatabase and migrations, stores most of LinTO Platform's business logicMongoDB, linto-platform-mongodb-migration
linto-platform-stt-service-manager, linto-platform-stt-service-manager-mongodbWeb API that abstracts the cluster's API in order to spawn service instances of Speech To Text transcription workersMongoDB, linto-platform-stt-service-manager, linto-platform-stt-standalone-worker
linto-platform-adminThe main web interface of the LinTO Platform. Monitor your fleet of voice-enabled endpoints, create workflows, deploy skills...linto-platform-admin
linto-platform-overwatchLinTO Platform's watchtower, provides authentication, persists connected clients MQTT transactions...linto-platform-overwatch
linto-platform-blsBLS stands for Business Logic Server, this is mainly a wrapper for Node-RED. This service is the server-side runtime that executes LinTO skills and actionslinto-platform-bls, IBM's Node-RED

NOTE : Some services are persistant while some others, like database migrations, will fire once when the stack is started and then stop gracefuly.

NOTE : Some services are bound (constrained) to specific nodes in your cluster, we therefore might use specific docker labels attached to cluster nodes ( i.e : ip=ingress label described further in this documentation).

NOTE : Mongo DB databases volumes are explicitly bound to the cluster manager node, this is our default setup as we want to prevent database file getting sharded on the cluster shared volume. In a production setup you might edit the corresponding YML compose files and invent your own node labels to deploy the databases wherever you want to.

Web interfaces

Once deployed, some services provides web interfaces to start interacting with the platform.

linto-edge-routerTraefik Dashboardhttp(s)://LINTO_STACK_DOMAIN:4480:4443/dashboard/#/Yes
linto-docker-visualizerCluster Vizualizer Dashboardhttp(s)://LINTO_STACK_DOMAIN/viz/Yes
linto-platform-adminThe platform's main web Interfacehttp(s)://LINTO_STACK_DOMAIN/No
linto-platform-stt-service-managerSwagger client to start spawning Speech To text serviceshttp(s)://LINTO_STACK_DOMAIN/stt-manager/api-docYes

NOTE : Protected column refers to the LINTO_STACK_HTTP_USE_AUTH environement variable. If set to true, the corresponding route will get protected with an HTTP basic auth middleware. This is useful for production as you don't want these routes publicly available.

NOTE : Some port variations appears in the linto-edge-router dashboard route and relates to your choice for SSL termination. This choice is set up by the LINTO_STACK_USE_SSL environement variable. This weird thingy is due to a Traefik limitation as the dashboard can't benefit from a base-path routing.

NOTE : linto-platform-admin Web interface will propose links to other Web interfaces (node Red, Tock...)

Ready ? Let's deploy LinTO Platform !

Identify and target the cluster node that will receive the inbound trafic.

  1. On a manager node, firstly list nodes and check hostnames :
docker node ls
  1. Add this specific label :
docker node update --label-add ip=ingress {Hostname_Of_The_Node_In_Your_Swarm_Cluster}
  1. Create a Docker Swarm local network to enable communication between services
docker network create \
-d overlay \
--attachable \

LinTO Platform stack on a local network

You might choose to start the stack on your Linux Laptop right ahead. As we want you to also benefit from SSL termination when thoroughly testing the platform without a costly server deployment, we suggest you to use a self signed certificate :

  1. Check this splendid tool : MkCert and install it
  2. Generate self-signed certs for the chosen LINTO_STACK_DOMAIN i.e :
mkcert ""
  1. Move the cert and key .pem file to the devcerts folder of this repo. Name it cert.pem and key.pem
  2. Update your /etc/hosts accordingly to the chosen domain (or use some dns resolver like dnsmasq)
  3. configure you local network DNS to resolve LINTO_STACK_DOMAIN if you want to connect LinTO clients to the local LinTO Platform.

You shall now benefit from a 100% SSL experience on your browser.

LinTO Platform stack on a publicly available Web Server

The LINTO_STACK_USE_ACME paired with LINTO_STACK_USE_SSL environement variables, once set to true, will handle Let's encrypt transactions for you.

If you want to benefit from a free ACME SSL certificate issued by Let's Encrypt, simply set this vars to true and don't forget, at least, to point your DNS provider towards the external public IP of your cluster node that has the ip=ingress (use an A record maybe ?)

If you don't want to use Let's Encrypt, you shall of course bind-mount the SSL certificates you already own in the linto-edge-router service before deploying the stack.

Start and stop the stack

Once all environement variables configured in .dockerenv (double check that), simply invoke the script on a manager node of your swarm cluster. This will create a Docker stack named linto_stack

NOTE : All Docker services we described will get prefixed with this.

If you want to shutdown the stack, simply use Docker commands

docker stack rm linto_stack

If you want to update services, you might simply reinvoke the script

Environement Variable Configuration

NOTE : All of this is set up in the declarative hidden file .dockerenv at the root of the linto-platform-stack repository.

Env variableDescriptionExample
LINTO_SHARED_MOUNTShared mount path on every cluster's node~/linto_shared_mount/
LINTO_STACK_USE_SSLEnable, disable SSLtrue, false
LINTO_STACK_USE_ACMEEnable, disable Let's encrypttrue, false
LINTO_STACK_DOMAINDeployed domain of the stackdev.linto.local
LINTO_STACK_HTTP_USE_AUTHEnable, disable Basic HTTP protection on some critical routestrue, false
LINTO_STACK_HTTP_USERThe HTTP basic auth useruser
LINTO_STACK_HTTP_PASSWORDThe HTTP basic auth password you wanna usepassword
LINTO_STACK_IMAGE_TAGYou might use latest or latest-unstable images from our Docker Hublatest / latest-unstable
Node JS APplication
TZTime-zone valueEurope/Paris
LINTO_STACK_ADMIN_HTTP_PORTLeave it 80 unless you want some tweaking80
LINTO_STACK_ADMIN_API_WHITELIST_DOMAINSCORS auhtorized domains list (separator ','), shall match your LINTO_STACK_DOMAIN at leasthttp://dev.linto.local,http://my-domain.coml
Redis session store for webapps
LINTO_STACK_REDIS_SESSION_SERVICERedis store service host/urllinto-platform-stack-redis
MQTT Broker for LinTO clients
LINTO_STACK_MQTT_HOSTMQTT broker hostlinto-mqtt-broker
LINTO_STACK_MQTT_USE_LOGINEnable/Disable MQTT broker authenticationtrue,false
LINTO_STACK_MQTT_DEFAULT_HW_SCOPEMQTT broker scope for static linto devices, any stringblk
LINTO_STACK_MQTT_PASSWORDMQTT broker passwordpassword
LINTO_STACK_MQTT_KEEP_ALIVETCP keep alive in seconds60
LINTO_STACK_MQTT_OVER_WSMQTT accesible over websockets or secure wstrue, false
LINTO_STACK_MQTT_OVER_WS_ENDPOINTmqtt over ws/wss endpoint/mqtt
LINTO_STACK_MONGODB_SERVICEMongoDb service host/urllinto-platform-mongo
LINTO_STACK_MONGODB_PORTMongoDb service port27017
LINTO_STACK_MONGODB_DBNAMEMongoDb service database namelinto-stack
LINTO_STACK_MONGODB_USE_LOGINEnable/Disable MongoDb service authenticationtrue,false
LINTO_STACK_MONGODB_USERMongoDb service usernameuser
LINTO_STACK_MONGODB_PASSWORDMongoDb service usernamepassword
LINTO_STACK_MONGODB_VOLUME_NAMEVolume name for mongodbmongodb-admin
LINTO_STACK_MONGODB_TARGET_VERSIONMongodb version for migration backup1,2,3
Business Logic Server
LINTO_STACK_BLS_SERVICEBLS service host/urllinto-platform-bls
LINTO_STACK_BLS_USE_LOGINEnable/disable BLS authenticationtrue
LINTO_STACK_BLS_USERBLS service usernameusername
LINTO_STACK_BLS_PASSWORDBLS service passwordpassword
LINTO_STACK_BLS_SERVICE_UI_PATHUser interface path/redui
Tock NLU
LINTO_STACK_TOCK_SERVICETock service host/urllinto-tock-nlu-web
LINTO_STACK_TOCK_NLP_APITock NLP service host/urllinto-tock-nlp-api
LINTO_STACK_MONGODB_TOCK_VOLUME_NAMEMongodb volume name for tock servicelinto-tock-mongo
LINTO_STACK_TOCK_SERVICE_UI_PATHTOck user interface path/tock
LINTO_STACK_TOCK_ENVRunning environement type(more log on dev)dev,prod
LINTO_STACK_TOCK_PASSWORDTock user passwordpassword
LINTO_STACK_TOCK_TAGDocker image version19.9.3
STT Service manager
LINTO_STACK_STT_SERVICE_MANAGER_SERVICESTT-manager service hostlinto-platform-stt-service-manager
LINTO_STACK_STT_SERVICE_MANAGER_MONGODB_HOSTSTT-manager mongodb hostlinto-platform-stt-service-manager-mongodb
LINTO_STACK_STT_SERVICE_MANAGER_MONGODB_REQUIRE_LOGINEnable/Disable MongoDb service authenticationtrue,false
LINTO_STACK_STT_SERVICE_MANAGER_VOLUME_NAMEMongodb volume name for STT-manager servicestt-service-manager
LinSTT Service
LINTO_STACK_LINSTT_IMAGEDocker image to uselintoai/linto-platform-stt-standalone-worker
LINTO_STACK_LINSTT_NETWORKDocker network to connectlinto-net
LINTO_STACK_OVERWATCH_LOGS_MONGODBEnable/Disable mongodb logstrue,false
LINTO_STACK_OVERWATCH_BASE_PATHAPI rest path location/overwatch
LINTO_STACK_OVERWATCH_AUTH_TYPEEnable auth type modulebasic,ldap,passthrough,...

Final words

To adapt the following tools to your needs, when you want let's say to deploy some service "à la carte", you might check what's going on in the stack-files folder of this repo (YML sources for the Docker Services).