NOISSUE - Add docker-compose for MQTT cluster (#841)

* Add MQTT cluster configs

Signed-off-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com>

* Bump worker_connections value in nginx.conf

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Revert config.toml

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Fix cluster

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Move non-ssl server into the same directive

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Fix cluster

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Remove unnecessary comments

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Organize docker-compose and nginx conf files

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Correct nginx.conf for mTLS and aux changes

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Fix NginX conf trailing slash in proxy_pass

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Fix path for MQTT

Signed-off-by: drasko <drasko.draskovic@gmail.com>

* Fix minorstuff in gitignore and comments

Signed-off-by: drasko <drasko.draskovic@gmail.com>
This commit is contained in:
Drasko DRASKOVIC
2019-09-12 16:55:24 +02:00
committed by Nikola Marčetić
parent 4870119270
commit 3b19292966
24 changed files with 383 additions and 704 deletions
+6 -5
View File
@@ -1,14 +1,15 @@
# Docker: Environment variables in Compose
## NGINX
## NginX
MF_NGINX_HTTP_PORT=80
MF_NGINX_SSL_PORT=443
MF_NGINX_MQTT_PORT=8883
MF_NGINX_MQTT_PORT=1883
MF_NGINX_MQTTS_PORT=8883
## NATS
MF_NATS_URL=nats://nats:4222
## REDIS
## Redis
MF_REDIS_TCP_PORT=6379
## UI
@@ -60,9 +61,9 @@ MF_HTTP_ADAPTER_PORT=8185
### MQTT
MF_MQTT_ADAPTER_LOG_LEVEL=debug
MF_MQTT_ADAPTER_PORT=1883
MF_MQTT_ADAPTER_WS_PORT=8880
MF_MQTT_ADAPTER_WS_PORT=8080
### COAP
### CoAP
MF_COAP_ADAPTER_LOG_LEVEL=debug
MF_COAP_ADAPTER_PORT=5683
+21 -1
View File
@@ -1,2 +1,22 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
# Set your private global .gitignore:
# https://digitalfortress.tech/tricks/creating-a-global-gitignore/
# Mainflux
build
site/
# MQTT
mqtt/verne/gpb
mqtt/verne/grpc
mqtt/verne/grpc_client
# Docker
docker/nginx/snippets/mqtt-upstream.conf
docker/nginx/snippets/mqtt-ws-upstream.conf
# Tools
tools/mqtt-bench/mqtt-bench
tools/provision/mfconn.toml
tools/provision/provision
+9 -9
View File
@@ -1,7 +1,5 @@
## Copyright (c) 2015-2019
## Mainflux
##
## SPDX-License-Identifier: Apache-2.0
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
BUILD_DIR = build
SERVICES = users things http normalizer ws coap lora influxdb-writer influxdb-reader mongodb-writer mongodb-reader cassandra-writer cassandra-reader postgres-writer postgres-reader cli bootstrap
@@ -148,16 +146,18 @@ rundev:
cd scripts && ./run.sh
run:
docker-compose -f docker/docker-compose.yml up
docker-compose -f docker/docker-compose.yml -f docker/aedes.yml up
runui:
$(MAKE) -C ui run
runlora:
docker-compose -f docker/docker-compose.yml up -d
docker-compose -f docker/addons/influxdb-writer/docker-compose.yml up -d
docker-compose -f docker/addons/lora-adapter/docker-compose.yml up
docker-compose \
-f docker/docker-compose.yml \
-f docker/aedes.yml up \
-f docker/addons/influxdb-writer/docker-compose.yml \
-f docker/addons/lora-adapter/docker-compose.yml up \
# Run all Mainflux core services except distributed tracing system - Jaeger. Recommended on gateways:
rungw:
MF_JAEGER_URL= docker-compose -f docker/docker-compose.yml up --scale jaeger=0
MF_JAEGER_URL= docker-compose -f docker/docker-compose.yml -f docker/aedes.yml up --scale jaeger=0
+45
View File
@@ -0,0 +1,45 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
version: "3.7"
volumes:
mainflux-mqtt-redis-volume:
services:
nginx:
depends_on:
- mqtt-adapter
mqtt-redis:
image: redis:5.0-alpine
container_name: mainflux-mqtt-redis
restart: on-failure
networks:
- mainflux-base-net
volumes:
- mainflux-mqtt-redis-volume:/data
mqtt-adapter:
image: mainflux/mqtt:latest
container_name: mainflux-mqtt
depends_on:
- things
- nats
- mqtt-redis
restart: on-failure
environment:
MF_MQTT_ADAPTER_LOG_LEVEL: ${MF_MQTT_ADAPTER_LOG_LEVEL}
MF_MQTT_INSTANCE_ID: mqtt-adapter-1
MF_MQTT_ADAPTER_PORT: ${MF_MQTT_ADAPTER_PORT}
MF_MQTT_ADAPTER_WS_PORT: ${MF_MQTT_ADAPTER_WS_PORT}
MF_MQTT_ADAPTER_REDIS_HOST: mqtt-redis
MF_MQTT_ADAPTER_ES_HOST: es-redis
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_URL: things:${MF_THINGS_AUTH_GRPC_PORT}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- 18831:${MF_MQTT_ADAPTER_PORT}
- 8881:${MF_MQTT_ADAPTER_WS_PORT}
networks:
- mainflux-base-net
-272
View File
@@ -1,272 +0,0 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
version: "3"
networks:
mainflux-base-net:
driver: bridge
volumes:
mainflux-users-db-volume:
mainflux-things-db-volume:
mainflux-mqtt-redis-volume:
mainflux-things-redis-volume:
mainflux-es-redis-volume:
services:
nginx:
image: nginx:1.16.0-alpine
container_name: mainflux-nginx
restart: on-failure
volumes:
- ./nginx/nginx-${AUTH-key}.conf:/etc/nginx/nginx.conf.template
- ./nginx/entrypoint.sh:/entrypoint.sh
- ./ssl/authorization.js:/etc/nginx/authorization.js
- ./ssl/certs/mainflux-server.crt:/etc/ssl/certs/mainflux-server.crt
- ./ssl/certs/ca.crt:/etc/ssl/certs/ca.crt
- ./ssl/certs/mainflux-server.key:/etc/ssl/private/mainflux-server.key
- ./ssl/dhparam.pem:/etc/ssl/certs/dhparam.pem
ports:
- ${MF_NGINX_HTTP_PORT}:${MF_NGINX_HTTP_PORT}
- ${MF_NGINX_SSL_PORT}:${MF_NGINX_SSL_PORT}
- ${MF_NGINX_MQTT_PORT}:${MF_NGINX_MQTT_PORT}
networks:
- mainflux-base-net
environment:
MF_UI_PORT: ${MF_UI_PORT}
command: /entrypoint.sh
nats:
image: nats:1.3.0
container_name: mainflux-nats
restart: on-failure
networks:
- mainflux-base-net
users-db:
image: postgres:10.8-alpine
container_name: mainflux-users-db
restart: on-failure
environment:
POSTGRES_USER: ${MF_USERS_DB_USER}
POSTGRES_PASSWORD: ${MF_USERS_DB_PASS}
POSTGRES_DB: ${MF_USERS_DB}
networks:
- mainflux-base-net
volumes:
- mainflux-users-db-volume:/var/lib/postgresql/data
users:
image: mainflux/users:latest
container_name: mainflux-users
depends_on:
- users-db
expose:
- ${MF_USERS_GRPC_PORT}
restart: on-failure
environment:
MF_USERS_LOG_LEVEL: ${MF_USERS_LOG_LEVEL}
MF_USERS_DB_HOST: users-db
MF_USERS_DB_PORT: ${MF_USERS_DB_PORT}
MF_USERS_DB_USER: ${MF_USERS_DB_USER}
MF_USERS_DB_PASS: ${MF_USERS_DB_PASS}
MF_USERS_DB: ${MF_USERS_DB}
MF_USERS_HTTP_PORT: ${MF_USERS_HTTP_PORT}
MF_USERS_GRPC_PORT: ${MF_USERS_GRPC_PORT}
MF_USERS_SECRET: ${MF_USERS_SECRET}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- ${MF_USERS_HTTP_PORT}:${MF_USERS_HTTP_PORT}
networks:
- mainflux-base-net
things-db:
image: postgres:10.8-alpine
container_name: mainflux-things-db
restart: on-failure
environment:
POSTGRES_USER: ${MF_THINGS_DB_USER}
POSTGRES_PASSWORD: ${MF_THINGS_DB_PASS}
POSTGRES_DB: ${MF_THINGS_DB}
networks:
- mainflux-base-net
volumes:
- mainflux-things-db-volume:/var/lib/postgresql/data
things-redis:
image: redis:5.0-alpine
container_name: mainflux-things-redis
restart: on-failure
networks:
- mainflux-base-net
volumes:
- mainflux-things-redis-volume:/data
things:
image: mainflux/things:latest
container_name: mainflux-things
depends_on:
- things-db
- users
restart: on-failure
environment:
MF_THINGS_LOG_LEVEL: ${MF_THINGS_LOG_LEVEL}
MF_THINGS_DB_HOST: things-db
MF_THINGS_DB_PORT: ${MF_THINGS_DB_PORT}
MF_THINGS_DB_USER: ${MF_THINGS_DB_USER}
MF_THINGS_DB_PASS: ${MF_THINGS_DB_PASS}
MF_THINGS_DB: ${MF_THINGS_DB}
MF_THINGS_CACHE_URL: things-redis:${MF_REDIS_TCP_PORT}
MF_THINGS_ES_URL: es-redis:${MF_REDIS_TCP_PORT}
MF_THINGS_HTTP_PORT: ${MF_THINGS_HTTP_PORT}
MF_THINGS_AUTH_HTTP_PORT: ${MF_THINGS_AUTH_HTTP_PORT}
MF_THINGS_AUTH_GRPC_PORT: ${MF_THINGS_AUTH_GRPC_PORT}
MF_USERS_URL: users:${MF_USERS_GRPC_PORT}
MF_THINGS_SECRET: ${MF_THINGS_SECRET}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- ${MF_THINGS_HTTP_PORT}:${MF_THINGS_HTTP_PORT}
- ${MF_THINGS_AUTH_HTTP_PORT}:${MF_THINGS_AUTH_HTTP_PORT}
- ${MF_THINGS_AUTH_GRPC_PORT}:${MF_THINGS_AUTH_GRPC_PORT}
networks:
- mainflux-base-net
jaeger:
image: jaegertracing/all-in-one:1.13
container_name: mainflux-jaeger
ports:
- ${MF_JAEGER_PORT}:${MF_JAEGER_PORT}/udp
- ${MF_JAEGER_FRONTEND}:${MF_JAEGER_FRONTEND}
- ${MF_JAEGER_COLLECTOR}:${MF_JAEGER_COLLECTOR}
- ${MF_JAEGER_CONFIGS}:${MF_JAEGER_CONFIGS}
networks:
- mainflux-base-net
normalizer:
image: mainflux/normalizer:latest
container_name: mainflux-normalizer
restart: on-failure
depends_on:
- nats
environment:
MF_NORMALIZER_LOG_LEVEL: ${MF_NORMALIZER_LOG_LEVEL}
MF_NATS_URL: ${MF_NATS_URL}
MF_NORMALIZER_PORT: ${MF_NORMALIZER_PORT}
ports:
- ${MF_NORMALIZER_PORT}:${MF_NORMALIZER_PORT}
networks:
- mainflux-base-net
ws-adapter:
image: mainflux/ws:latest
container_name: mainflux-ws
depends_on:
- things
- nats
restart: on-failure
environment:
MF_WS_ADAPTER_LOG_LEVEL: ${MF_WS_ADAPTER_LOG_LEVEL}
MF_WS_ADAPTER_PORT: ${MF_WS_ADAPTER_PORT}
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_URL: things:${MF_THINGS_AUTH_GRPC_PORT}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- ${MF_WS_ADAPTER_PORT}:${MF_WS_ADAPTER_PORT}
networks:
- mainflux-base-net
http-adapter:
image: mainflux/http:latest
container_name: mainflux-http
depends_on:
- things
- nats
restart: on-failure
environment:
MF_HTTP_ADAPTER_LOG_LEVEL: debug
MF_HTTP_ADAPTER_PORT: ${MF_HTTP_ADAPTER_PORT}
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_URL: things:${MF_THINGS_AUTH_GRPC_PORT}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- ${MF_HTTP_ADAPTER_PORT}:${MF_HTTP_ADAPTER_PORT}
networks:
- mainflux-base-net
es-redis:
image: redis:5.0-alpine
container_name: mainflux-es-redis
restart: on-failure
networks:
- mainflux-base-net
volumes:
- mainflux-es-redis-volume:/data
mqtt-redis:
image: redis:5.0-alpine
container_name: mainflux-mqtt-redis
restart: on-failure
networks:
- mainflux-base-net
volumes:
- mainflux-mqtt-redis-volume:/data
mqtt-adapter:
image: mainflux/mqtt-verne:latest
container_name: mainflux-mqtt
depends_on:
- things
- nats
- mqtt-redis
restart: on-failure
environment:
MF_MQTT_ADAPTER_LOG_LEVEL: ${MF_MQTT_ADAPTER_LOG_LEVEL}
MF_MQTT_INSTANCE_ID: mqtt-adapter-1
MF_MQTT_ADAPTER_PORT: ${MF_MQTT_ADAPTER_PORT}
MF_MQTT_ADAPTER_WS_PORT: ${MF_MQTT_ADAPTER_WS_PORT}
MF_MQTT_ADAPTER_REDIS_URL: tcp://mqtt-redis:${MF_REDIS_TCP_PORT}
MF_MQTT_ADAPTER_ES_URL: tcp://es-redis:${MF_REDIS_TCP_PORT}
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_AUTH_GRPC_URL: http://things:${MF_THINGS_AUTH_GRPC_PORT}
DOCKER_VERNEMQ_PLUGINS__VMQ_PASSWD: "off"
DOCKER_VERNEMQ_PLUGINS__VMQ_ACL: "off"
DOCKER_VERNEMQ_PLUGINS__MFX_AUTH: "on"
DOCKER_VERNEMQ_PLUGINS__MFX_AUTH__PATH: /mainflux/_build/default
DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL: warning
MF_MQTT_VERNEMQ_GRPC_POOL_SIZE: 1000
ports:
- ${MF_MQTT_ADAPTER_PORT}:${MF_MQTT_ADAPTER_PORT}
- ${MF_MQTT_ADAPTER_WS_PORT}:${MF_MQTT_ADAPTER_WS_PORT}
networks:
- mainflux-base-net
coap-adapter:
image: mainflux/coap:latest
container_name: mainflux-coap
depends_on:
- things
- nats
restart: on-failure
environment:
MF_COAP_ADAPTER_LOG_LEVEL: ${MF_COAP_ADAPTER_LOG_LEVEL}
MF_COAP_ADAPTER_PORT: ${MF_COAP_ADAPTER_PORT}
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_URL: things:${MF_THINGS_AUTH_GRPC_PORT}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- ${MF_COAP_ADAPTER_PORT}:${MF_COAP_ADAPTER_PORT}/udp
- ${MF_COAP_ADAPTER_PORT}:${MF_COAP_ADAPTER_PORT}/tcp
networks:
- mainflux-base-net
ui:
image: mainflux/ui:latest
container_name: mainflux-ui
restart: on-failure
ports:
- ${MF_UI_PORT}:${MF_UI_PORT}
networks:
- mainflux-base-net
environment:
MF_UI_PORT: ${MF_UI_PORT}
+12 -44
View File
@@ -1,12 +1,7 @@
###
# Copyright (c) 2015-2017 Mainflux
#
# Mainflux is licensed under an Apache license, version 2.0 license.
# All rights not explicitly granted in the Apache license, version 2.0 are reserved.
# See the included LICENSE file for more details.
###
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
version: "3"
version: "3.7"
networks:
mainflux-base-net:
@@ -15,7 +10,6 @@ networks:
volumes:
mainflux-users-db-volume:
mainflux-things-db-volume:
mainflux-mqtt-redis-volume:
mainflux-things-redis-volume:
mainflux-es-redis-volume:
@@ -27,6 +21,7 @@ services:
volumes:
- ./nginx/nginx-${AUTH-key}.conf:/etc/nginx/nginx.conf.template
- ./nginx/entrypoint.sh:/entrypoint.sh
- ./nginx/snippets:/etc/nginx/snippets
- ./ssl/authorization.js:/etc/nginx/authorization.js
- ./ssl/certs/mainflux-server.crt:/etc/ssl/certs/mainflux-server.crt
- ./ssl/certs/ca.crt:/etc/ssl/certs/ca.crt
@@ -36,11 +31,17 @@ services:
- ${MF_NGINX_HTTP_PORT}:${MF_NGINX_HTTP_PORT}
- ${MF_NGINX_SSL_PORT}:${MF_NGINX_SSL_PORT}
- ${MF_NGINX_MQTT_PORT}:${MF_NGINX_MQTT_PORT}
- ${MF_NGINX_MQTTS_PORT}:${MF_NGINX_MQTTS_PORT}
networks:
- mainflux-base-net
environment:
MF_UI_PORT: ${MF_UI_PORT}
env_file:
- ../.env
command: /entrypoint.sh
depends_on:
- things
- users
- http-adapter
- ws-adapter
nats:
image: nats:1.3.0
@@ -208,39 +209,6 @@ services:
volumes:
- mainflux-es-redis-volume:/data
mqtt-redis:
image: redis:5.0-alpine
container_name: mainflux-mqtt-redis
restart: on-failure
networks:
- mainflux-base-net
volumes:
- mainflux-mqtt-redis-volume:/data
mqtt-adapter:
image: mainflux/mqtt:latest
container_name: mainflux-mqtt
depends_on:
- things
- nats
- mqtt-redis
restart: on-failure
environment:
MF_MQTT_ADAPTER_LOG_LEVEL: ${MF_MQTT_ADAPTER_LOG_LEVEL}
MF_MQTT_INSTANCE_ID: mqtt-adapter-1
MF_MQTT_ADAPTER_PORT: ${MF_MQTT_ADAPTER_PORT}
MF_MQTT_ADAPTER_WS_PORT: ${MF_MQTT_ADAPTER_WS_PORT}
MF_MQTT_ADAPTER_REDIS_HOST: mqtt-redis
MF_MQTT_ADAPTER_ES_HOST: es-redis
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_URL: things:${MF_THINGS_AUTH_GRPC_PORT}
MF_JAEGER_URL: ${MF_JAEGER_URL}
ports:
- ${MF_MQTT_ADAPTER_PORT}:${MF_MQTT_ADAPTER_PORT}
- ${MF_MQTT_ADAPTER_WS_PORT}:${MF_MQTT_ADAPTER_WS_PORT}
networks:
- mainflux-base-net
coap-adapter:
image: mainflux/coap:latest
container_name: mainflux-coap
+16 -3
View File
@@ -1,9 +1,22 @@
#!/bin/ash
if [ -n "$MF_UI_PORT" ]; then
sed -e "s/MF_UI_PORT/$MF_UI_PORT/" /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
if [ -z "$MF_MQTT_CLUSTER" ]
then
envsubst '${MF_MQTT_ADAPTER_PORT}' < /etc/nginx/snippets/mqtt-upstream-single.conf > /etc/nginx/snippets/mqtt-upstream.conf
envsubst '${MF_MQTT_ADAPTER_WS_PORT}' < /etc/nginx/snippets/mqtt-ws-upstream-single.conf > /etc/nginx/snippets/mqtt-ws-upstream.conf
else
sed -e "s/MF_UI_PORT/3000/" /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
envsubst '${MF_MQTT_ADAPTER_PORT}' < /etc/nginx/snippets/mqtt-upstream-cluster.conf > /etc/nginx/snippets/mqtt-upstream.conf
envsubst '${MF_MQTT_ADAPTER_WS_PORT}' < /etc/nginx/snippets/mqtt-ws-upstream-cluster.conf > /etc/nginx/snippets/mqtt-ws-upstream.conf
fi
envsubst '
${MF_USERS_HTTP_PORT}
${MF_THINGS_HTTP_PORT}
${MF_THINGS_HTTP_PORT}
${MF_HTTP_ADAPTER_PORT}
${MF_WS_ADAPTER_PORT}
${MF_UI_PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
cp /etc/nginx/nginx.conf /etc/nginx/snippets
exec nginx -g "daemon off;"
+38 -138
View File
@@ -1,18 +1,18 @@
#
# Copyright (c) 2018
# Mainflux
#
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
#
# This is the default Mainflux NGINX configuration.
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# Explanation: https://serverfault.com/questions/787919/optimal-value-for-nginx-worker-connections
# We'll keep 10k connections per core (assuming one worker per core)
worker_connections 10000;
}
http {
@@ -31,27 +31,16 @@ http {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Include single-node or multiple-node (cluster) upstream
include snippets/mqtt-ws-upstream.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
# These paths are set to its default values as
# a volume in the docker/docker-compose.yml file.
ssl_certificate /etc/ssl/certs/mainflux-server.crt;
ssl_certificate_key /etc/ssl/private/mainflux-server.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling off;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
include snippets/ssl.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
@@ -64,155 +53,66 @@ http {
# Proxy pass to users service
location ~ ^/(users|tokens) {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://users:8180;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
proxy_pass http://users:${MF_USERS_HTTP_PORT};
}
# Proxy pass to things service
location ~ ^/(things|channels) {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
include snippets/proxy-headers.conf;
add_header Access-Control-Expose-Headers Location;
proxy_pass http://things:8182;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
proxy_pass http://things:${MF_THINGS_HTTP_PORT};
}
location /version {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://things:8182;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
proxy_pass http://things:${MF_THINGS_HTTP_PORT};
}
# Proxy pass to mainflux-http-adapter
location /http/ {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://http-adapter:8185/;
include snippets/proxy-headers.conf;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
# Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
# If the proxy_pass directive is specified with a URI, then when a request is passed to the server,
# the part of a normalized request URI matching the location is replaced by a URI specified in the directive
proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/;
}
# Proxy pass to mainflux-ws-adapter
location /ws/ {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
proxy_pass http://ws-adapter:8186/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
include snippets/ws-upgrade.conf;
proxy_pass http://ws-adapter:${MF_WS_ADAPTER_PORT}/;
}
# Proxy pass to mainflux-mqtt-adapter over WS
location /mqtt {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
proxy_pass http://mqtt-adapter:8880/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
location /mqtt/ {
include snippets/proxy-headers.conf;
include snippets/ws-upgrade.conf;
proxy_pass http://mqtt_ws_cluster/;
}
location / {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://ui:MF_UI_PORT/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
proxy_pass http://ui:${MF_UI_PORT};
}
}
}
# MQTT
stream {
# Include single-node or multiple-node (cluster) upstream
include snippets/mqtt-upstream.conf;
server {
listen 1883;
listen [::]:1883;
listen 8883 ssl;
listen [::]:8883 ssl;
# These paths are set to its default values as
# a volume in the docker/docker-compose.yml file.
ssl_certificate /etc/ssl/certs/mainflux-server.crt;
ssl_certificate_key /etc/ssl/private/mainflux-server.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
include snippets/ssl.conf;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
proxy_pass mqtt-adapter:1883;
proxy_pass mqtt_cluster;
}
}
}
+44 -167
View File
@@ -1,23 +1,26 @@
#
# Copyright (c) 2018
# Mainflux
#
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
#
# This is the Mainflux NGINX configuration for mututal authentication based on X.509 certifiactes.
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
pid /run/nginx.pid;
load_module /etc/nginx/modules/ngx_stream_js_module.so;
load_module /etc/nginx/modules/ngx_http_js_module.so;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# Explanation: https://serverfault.com/questions/787919/optimal-value-for-nginx-worker-connections
# We'll keep 10k connections per core (assuming one worker per core)
worker_connections 10000;
}
http {
js_include authorization.js;
js_set $auth_key setKey;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
@@ -30,8 +33,8 @@ http {
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
js_include authorization.js;
js_set $auth_key setKey;
# Include single-node or multiple-node (cluster) upstream
include snippets/mqtt-ws-upstream.conf;
server {
listen 80 default_server;
@@ -39,24 +42,7 @@ http {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
# These paths are set to its default values as
# a volume in the docker/docker-compose.yml file.
ssl_certificate /etc/ssl/certs/mainflux-server.crt;
ssl_certificate_key /etc/ssl/private/mainflux-server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client optional;
ssl_verify_depth 2;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling off;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
include snippets/ssl.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
@@ -69,154 +55,53 @@ http {
# Proxy pass to users service
location ~ ^/(users|tokens) {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://users:8180;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
proxy_pass http://users:${MF_USERS_HTTP_PORT};
}
# Proxy pass to things service
location ~ ^/(things|channels) {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
include snippets/proxy-headers.conf;
add_header Access-Control-Expose-Headers Location;
proxy_pass http://things:8182;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
proxy_pass http://things:${MF_THINGS_HTTP_PORT};
}
location /version {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://things:8182;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
proxy_pass http://things:${MF_THINGS_HTTP_PORT};
}
# Proxy pass to mainflux-http-adapter
location /http/ {
if ($ssl_client_verify != SUCCESS) {
return 403;
}
if ($auth_key = '') {
return 403;
}
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
include snippets/verify-ssl-client.conf;
include snippets/proxy-headers.conf;
proxy_set_header Authorization $auth_key;
proxy_pass http://http-adapter:8185/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
# Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
# If the proxy_pass directive is specified with a URI, then when a request is passed to the server,
# the part of a normalized request URI matching the location is replaced by a URI specified in the directive
proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/;
}
# Proxy pass to mainflux-ws-adapter
location /ws/ {
if ($ssl_client_verify != SUCCESS) {
return 403;
}
if ($auth_key = '') {
return 403;
}
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
proxy_pass http://ws-adapter:8186/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/verify-ssl-client.conf;
include snippets/proxy-headers.conf;
include snippets/ws-upgrade.conf;
proxy_pass http://ws-adapter:${MF_WS_ADAPTER_PORT}/;
}
# Proxy pass to mainflux-mqtt-adapter over WS
location /mqtt {
if ($ssl_client_verify != SUCCESS) {
return 403;
}
if ($auth_key = '') {
return 403;
}
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
proxy_pass http://mqtt-adapter:8880/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
location /mqtt/ {
include snippets/verify-ssl-client.conf;
include snippets/proxy-headers.conf;
include snippets/ws-upgrade.conf;
proxy_pass http://mqtt_ws_cluster/;
}
location / {
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
proxy_pass http://ui:MF_UI_PORT/;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
include snippets/proxy-headers.conf;
proxy_pass http://ui:${MF_UI_PORT};
}
}
@@ -227,30 +112,22 @@ http {
# MQTT
stream {
# Include JS script for mTLS
js_include authorization.js;
# Include single-node or multiple-node (cluster) upstream
include snippets/mqtt-upstream.conf;
server {
listen 1883;
listen [::]:1883;
listen 8883 ssl;
listen [::]:8883 ssl;
# These paths are set to its default values as
# a volume in the docker/docker-compose.yml file.
ssl_certificate /etc/ssl/certs/mainflux-server.crt;
ssl_certificate_key /etc/ssl/private/mainflux-server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
include snippets/ssl.conf;
js_preread authenticate;
proxy_pass mqtt-adapter:1883;
proxy_pass mqtt_cluster;
}
}
@@ -0,0 +1,9 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
upstream mqtt_cluster {
least_conn;
server mqtt-adapter-1:${MF_MQTT_ADAPTER_PORT};
server mqtt-adapter-2:${MF_MQTT_ADAPTER_PORT};
server mqtt-adapter-3:${MF_MQTT_ADAPTER_PORT};
}
@@ -0,0 +1,6 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
upstream mqtt_cluster {
server mqtt-adapter:${MF_MQTT_ADAPTER_PORT};
}
@@ -0,0 +1,9 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
upstream mqtt_ws_cluster {
least_conn;
server mqtt-adapter-1:${MF_MQTT_ADAPTER_WS_PORT};
server mqtt-adapter-2:${MF_MQTT_ADAPTER_WS_PORT};
server mqtt-adapter-3:${MF_MQTT_ADAPTER_WS_PORT};
}
@@ -0,0 +1,6 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
upstream mqtt_ws_cluster {
server mqtt-adapter:${MF_MQTT_ADAPTER_WS_PORT};
}
+15
View File
@@ -0,0 +1,15 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
proxy_redirect off;
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 X-Forwarded-Proto $scheme;
# Allow OPTIONS method CORS
if ($request_method = OPTIONS) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
+16
View File
@@ -0,0 +1,16 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
# These paths are set to its default values as
# a volume in the docker/docker-compose.yml file.
ssl_certificate /etc/ssl/certs/mainflux-server.crt;
ssl_certificate_key /etc/ssl/private/mainflux-server.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
@@ -0,0 +1,9 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
if ($ssl_client_verify != SUCCESS) {
return 403;
}
if ($auth_key = '') {
return 403;
}
+9
View File
@@ -0,0 +1,9 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
+72
View File
@@ -0,0 +1,72 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
version: "3.7"
x-mqtt-adapter: &mqtt-adapter
image: mainflux/mqtt-verne:latest
depends_on:
- things
- nats
restart: on-failure
environment: &mqtt-adapter-env
MF_MQTT_ADAPTER_LOG_LEVEL: ${MF_MQTT_ADAPTER_LOG_LEVEL}
MF_MQTT_INSTANCE_ID: mqtt-adapter-1
MF_MQTT_ADAPTER_ES_URL: tcp://es-redis:${MF_REDIS_TCP_PORT}
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_AUTH_GRPC_URL: http://things:${MF_THINGS_AUTH_GRPC_PORT}
DOCKER_VERNEMQ_PLUGINS__VMQ_PASSWD: "off"
DOCKER_VERNEMQ_PLUGINS__VMQ_ACL: "off"
DOCKER_VERNEMQ_PLUGINS__MFX_AUTH: "on"
DOCKER_VERNEMQ_PLUGINS__MFX_AUTH__PATH: /mainflux/_build/default
DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL: debug
MF_MQTT_VERNEMQ_GRPC_POOL_SIZE: 1000
networks:
- mainflux-base-net
services:
nginx:
environment:
MF_MQTT_CLUSTER: 1
depends_on:
- mqtt-adapter-1
- mqtt-adapter-2
- mqtt-adapter-3
mqtt-adapter-1:
<< : *mqtt-adapter
container_name: mainflux-mqtt-1
ports:
- 18831:${MF_MQTT_ADAPTER_PORT}
- 8891:${MF_MQTT_ADAPTER_WS_PORT}
- 7777:8888
mqtt-adapter-2:
<< : *mqtt-adapter
container_name: mainflux-mqtt-2
environment:
<< : *mqtt-adapter-env
DOCKER_VERNEMQ_COMPOSE: 1
DOCKER_VERNEMQ_DISCOVERY_NODE: mqtt-adapter-1
ports:
- 18832:1883
- 8892:8080
- 7778:8888
depends_on:
- mqtt-adapter-1
mqtt-adapter-3:
<< : *mqtt-adapter
container_name: mainflux-mqtt-3
environment:
<< : *mqtt-adapter-env
DOCKER_VERNEMQ_COMPOSE: 1
DOCKER_VERNEMQ_DISCOVERY_NODE: mqtt-adapter-1
ports:
- 18833:1883
- 8893:8080
- 7779:8888
depends_on:
- mqtt-adapter-1
+35
View File
@@ -0,0 +1,35 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
version: "3.7"
services:
nginx:
depends_on:
- mqtt-adapter
mqtt-adapter:
image: mainflux/mqtt-verne:latest
container_name: mainflux-mqtt
depends_on:
- things
- nats
restart: on-failure
environment:
MF_MQTT_ADAPTER_LOG_LEVEL: ${MF_MQTT_ADAPTER_LOG_LEVEL}
MF_MQTT_INSTANCE_ID: mqtt-adapter-1
MF_MQTT_ADAPTER_ES_URL: tcp://es-redis:${MF_REDIS_TCP_PORT}
MF_NATS_URL: ${MF_NATS_URL}
MF_THINGS_AUTH_GRPC_URL: http://things:${MF_THINGS_AUTH_GRPC_PORT}
DOCKER_VERNEMQ_PLUGINS__VMQ_PASSWD: "off"
DOCKER_VERNEMQ_PLUGINS__VMQ_ACL: "off"
DOCKER_VERNEMQ_PLUGINS__MFX_AUTH: "on"
DOCKER_VERNEMQ_PLUGINS__MFX_AUTH__PATH: /mainflux/_build/default
DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL: debug
MF_MQTT_VERNEMQ_GRPC_POOL_SIZE: 1000
ports:
- 18831:${MF_MQTT_ADAPTER_PORT}
- 8881:${MF_MQTT_ADAPTER_WS_PORT}
- 7777:8888
networks:
- mainflux-base-net
-7
View File
@@ -1,7 +0,0 @@
{
"extends": ["airbnb-base/legacy"],
"rules": {
"func-names": ["error", "never"],
"indent": ["error", 4]
}
}
-51
View File
@@ -1,51 +0,0 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
package-lock.json
# Visual Studio files
*.sln
*.njsproj
# Vim files
# swap
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
# session
Session.vim
# temporary
.netrwhist
*~
# auto-generated tag files
tags
# Go sources
./src
# Go tests
*.test
# Binary
mainflux-mqtt
+4 -1
View File
@@ -1,3 +1,6 @@
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
FROM erlang:21-alpine AS builder
WORKDIR /mainflux
@@ -5,6 +8,6 @@ COPY ./mqtt/verne .
RUN apk add --no-cache git && \
./rebar3 compile
FROM vernemq/vernemq:1.8.0-alpine
FROM vernemq/vernemq:1.9.2-alpine
WORKDIR /mainflux
COPY --from=builder --chown=10000:10000 /mainflux .
+2 -6
View File
@@ -1,10 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2018
# Mainflux
#
# Copyright (c) Mainflux
# SPDX-License-Identifier: Apache-2.0
#
###
# Runs all Mainflux microservices (must be previously built and installed).
@@ -58,7 +54,7 @@ MF_NORMALIZER_LOG_LEVEL=INFO MF_NORMALIZER_PORT=8184 MF_NATS_URL=localhost:4222
# Switch to top dir to find *.proto stuff when running MQTT broker
cd ..
MF_MQTT_ADAPTER_LOG_LEVEL=info MF_THINGS_URL=localhost:8183 node mqtt/mqtt.js &
MF_MQTT_ADAPTER_LOG_LEVEL=info MF_THINGS_URL=localhost:8183 node mqtt/aedes/mqtt.js &
cd -
###