Browse Source

NET-147 full config for nm-quick.sh (#2291)

* - moved all vars to config
- compose override
- use the config in compose, caddy
- aligned local / remote setup
- proper docker cleanup
- support for a relative installation path

* - config handling
- error handling / env cleanups
- reduced compose files
- misc

* fixed debugs

* fixed UI_IMAGE_TAG / IMAGE_TAG
Tobias Cudnik 2 years ago
parent
commit
3ad47f17ec

+ 4 - 73
compose/docker-compose-emqx.yml

@@ -1,86 +1,17 @@
 version: "3.4"
 
 services:
-  netmaker:
-    container_name: netmaker
-    image: gravitl/netmaker:v0.19.0
-    restart: on-failure
-    volumes:
-      - dnsconfig:/root/config/dnsconfig
-      - sqldata:/root/data
-    environment:
-      BROKER_ENDPOINT: "wss://broker.NETMAKER_BASE_DOMAIN/mqtt"
-      BROKER_TYPE: "emqx"
-      EMQX_REST_ENDPOINT: "http://mq:18083"
-      SERVER_NAME: "NETMAKER_BASE_DOMAIN"
-      STUN_LIST: "stun.NETMAKER_BASE_DOMAIN:3478,stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302"
-      SERVER_HOST: "SERVER_PUBLIC_IP"
-      SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
-      COREDNS_ADDR: "SERVER_PUBLIC_IP"
-      DNS_MODE: "on"
-      SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN"
-      NETCLIENT_AUTO_UPDATE: "enabled"
-      API_PORT: "8081"
-      MASTER_KEY: "REPLACE_MASTER_KEY"
-      CORS_ALLOWED_ORIGIN: "*"
-      DISPLAY_KEYS: "on"
-      DATABASE: "sqlite"
-      NODE_ID: "netmaker-server-1"
-      SERVER_BROKER_ENDPOINT: "ws://mq:8083/mqtt"
-      STUN_PORT: "3478"      
-      VERBOSITY: "1"
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
-      MQ_USERNAME: "REPLACE_MQ_USERNAME"
-      DEFAULT_PROXY_MODE: "off"
-    ports:
-      - "3478:3478/udp"
-  netmaker-ui:
-    container_name: netmaker-ui
-    image: gravitl/netmaker-ui:v0.19.0
-    depends_on:
-      - netmaker
-    links:
-      - "netmaker:api"
-    restart: always
-    environment:
-      BACKEND_URL: "https://api.NETMAKER_BASE_DOMAIN"
-  caddy:
-    image: caddy:2.6.2
-    container_name: caddy
-    restart: unless-stopped
-    volumes:
-      - /root/Caddyfile:/etc/caddy/Caddyfile
-      - /root/certs:/root/certs
-      - caddy_data:/data
-      - caddy_conf:/config
-    ports:
-      - "80:80"
-      - "443:443"
-  coredns:
-    container_name: coredns
-    image: coredns/coredns
-    command: -conf /root/dnsconfig/Corefile
-    depends_on:
-      - netmaker
-    restart: always
-    volumes:
-      - dnsconfig:/root/dnsconfig
   mq:
     container_name: mq
     image: emqx/emqx:5.0.9
     restart: unless-stopped
     environment:
-      EMQX_NAME: "emqx"
-      EMQX_DASHBOARD__DEFAULT_PASSWORD: "REPLACE_MQ_PASSWORD"
-      EMQX_DASHBOARD__DEFAULT_USERNAME: "REPLACE_MQ_USERNAME"
+      - EMQX_NAME: "emqx"
+      - EMQX_DASHBOARD__DEFAULT_PASSWORD=${MQ_PASSWORD}
+      - EMQX_DASHBOARD__DEFAULT_USERNAME=${MQ_USERNAME}
     ports:
       - "1883:1883" # MQTT
       - "8883:8883" # SSL MQTT
       - "8083:8083" # Websockets
       - "18083:18083" # Dashboard/REST_API
-volumes:
-  caddy_data: {}
-  caddy_conf: {}
-  sqldata: {}
-  dnsconfig: {}
-  mosquitto_logs: {}
+

+ 22 - 123
compose/docker-compose.ee.yml

@@ -1,109 +1,29 @@
 version: "3.4"
 
 services:
-  netmaker:
-    container_name: netmaker
-    image: gravitl/netmaker:REPLACE_SERVER_IMAGE_TAG
-    restart: on-failure
-    volumes:
-      - dnsconfig:/root/config/dnsconfig
-      - sqldata:/root/data
-    environment:
-      BROKER_ENDPOINT: "wss://broker.NETMAKER_BASE_DOMAIN"
-      SERVER_NAME: "NETMAKER_BASE_DOMAIN"
-      STUN_LIST: "stun.NETMAKER_BASE_DOMAIN:3478,stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302"
-      SERVER_HOST: "SERVER_PUBLIC_IP"
-      SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
-      COREDNS_ADDR: "SERVER_PUBLIC_IP"
-      DNS_MODE: "on"
-      SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN"
-      NETCLIENT_AUTO_UPDATE: "enabled"
-      API_PORT: "8081"
-      MASTER_KEY: "REPLACE_MASTER_KEY"
-      CORS_ALLOWED_ORIGIN: "*"
-      DISPLAY_KEYS: "on"
-      DATABASE: "sqlite"
-      NODE_ID: "netmaker-server-1"
-      SERVER_BROKER_ENDPOINT: "ws://mq:1883"
-      MQ_USERNAME: "REPLACE_MQ_USERNAME"
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
-      STUN_PORT: "3478"
-      VERBOSITY: "1"
-      METRICS_EXPORTER: "on"
-      LICENSE_KEY: "YOUR_LICENSE_KEY"
-      NETMAKER_ACCOUNT_ID: "YOUR_ACCOUNT_ID"
-      DEFAULT_PROXY_MODE: "off"
-      TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
-      TURN_SERVER_API_HOST: "https://turnapi.NETMAKER_BASE_DOMAIN"
-      TURN_PORT: "3479"
-      TURN_USERNAME: "REPLACE_TURN_USERNAME"
-      TURN_PASSWORD: "REPLACE_TURN_PASSWORD"
-      USE_TURN: "true"
-    ports:
-      - "3478:3478/udp"
-  netmaker-ui:
-    container_name: netmaker-ui
-    image: gravitl/netmaker-ui:REPLACE_UI_IMAGE_TAG
-    depends_on:
-      - netmaker
-    links:
-      - "netmaker:api"
-    restart: always
-    environment:
-      BACKEND_URL: "https://api.NETMAKER_BASE_DOMAIN"
-  caddy:
-    image: caddy:2.6.2
-    container_name: caddy
-    restart: unless-stopped
-    volumes:
-      - /root/Caddyfile:/etc/caddy/Caddyfile
-      - /root/certs:/root/certs
-      - caddy_data:/data
-      - caddy_conf:/config
-    ports:
-      - "80:80"
-      - "443:443"
-  coredns:
-    container_name: coredns
-    image: coredns/coredns
-    command: -conf /root/dnsconfig/Corefile
-    depends_on:
-      - netmaker
-    restart: always
-    volumes:
-      - dnsconfig:/root/dnsconfig
-  mq:
-    container_name: mq
-    image: eclipse-mosquitto:2.0.15-openssl
-    depends_on:
-      - netmaker
-    restart: unless-stopped
-    command: ["/mosquitto/config/wait.sh"]
-    environment:
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
-      MQ_USERNAME: "REPLACE_MQ_USERNAME"
-    volumes:
-      - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
-      - /root/wait.sh:/mosquitto/config/wait.sh
-      - mosquitto_logs:/mosquitto/log
+
   prometheus:
     container_name: prometheus
     image: gravitl/netmaker-prometheus:latest
+    env_file: ./netmaker.env
     environment:
-      NETMAKER_METRICS_TARGET: "netmaker-exporter.NETMAKER_BASE_DOMAIN"
-      LICENSE_KEY: "YOUR_LICENSE_KEY"
+      # config-dependant vars
+      - NETMAKER_METRICS_TARGET=netmaker-exporter.${NM_DOMAIN}
     restart: always
     volumes:
       - prometheus_data:/prometheus
     depends_on:
       - netmaker
+
   grafana:
     container_name: grafana
     image: gravitl/netmaker-grafana:latest
+    env_file: ./netmaker.env
     environment:
-      PROMETHEUS_HOST: "prometheus.NETMAKER_BASE_DOMAIN"
-      NETMAKER_METRICS_TARGET: "netmaker-exporter.NETMAKER_BASE_DOMAIN"
-      LICENSE_KEY: "YOUR_LICENSE_KEY"
+      # config-dependant vars
+      # TODO unify with netmaker-exporter
+      - PROMETHEUS_HOST=prometheus.${NM_DOMAIN}
+      - NETMAKER_METRICS_TARGET=netmaker-exporter.${NM_DOMAIN}
     volumes:
       - grafana_data:/var/lib/grafana
     restart: always
@@ -112,43 +32,22 @@ services:
     depends_on:
       - prometheus
       - netmaker
+
   netmaker-exporter:
     container_name: netmaker-exporter
     image: gravitl/netmaker-exporter:latest
+    env_file: ./netmaker.env
+    environment:
+      # config-dependant vars
+      # TODO unify with grafana
+      - PROMETHEUS_HOST=https://prometheus.${NM_DOMAIN}
+      # The domain/host IP indicating the mq broker address
+      - BROKER_ENDPOINT=wss://broker.${NM_DOMAIN}
+      - API_PORT=${EXPORTER_API_PORT}
     restart: always
     depends_on:
       - netmaker
-    environment:
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
-      MQ_USERNAME: "REPLACE_MQ_USERNAME"
-      SERVER_BROKER_ENDPOINT: "ws://mq:1883"
-      BROKER_ENDPOINT: "wss://broker.NETMAKER_BASE_DOMAIN"
-      PROMETHEUS: "on"
-      VERBOSITY: "1"
-      API_PORT: "8085"
-      LICENSE_KEY: "YOUR_LICENSE_KEY"
-      PROMETHEUS_HOST: https://prometheus.NETMAKER_BASE_DOMAIN
-  turn:
-    container_name: turn
-    image: gravitl/turnserver:v1.0.0
-    network_mode: "host"
-    volumes:
-      - turn_server:/etc/config
-    environment:
-      DEBUG_MODE: "off"
-      VERBOSITY: "1"
-      TURN_PORT: "3479"
-      TURN_API_PORT: "8089"
-      CORS_ALLOWED_ORIGIN: "*"
-      TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
-      USERNAME: "REPLACE_TURN_USERNAME"
-      PASSWORD: "REPLACE_TURN_PASSWORD"
+
 volumes:
-  caddy_data: {}
-  caddy_conf: {}
-  sqldata: {}
-  dnsconfig: {}
-  mosquitto_logs: {}
-  prometheus_data: {}
-  grafana_data: {}
-  turn_server: {}
+  prometheus_data: { }
+  grafana_data: { }

+ 0 - 122
compose/docker-compose.reference.yml

@@ -1,122 +0,0 @@
-version: "3.4"
-
-services:
-  netmaker: # The Primary Server for running Netmaker
-    container_name: netmaker
-    image: gravitl/netmaker:REPLACE_SERVER_IMAGE_TAG
-    restart: on-failure
-    volumes: # Volume mounts necessary for sql, coredns, and mqtt
-      - dnsconfig:/root/config/dnsconfig
-      - sqldata:/root/data
-      - shared_certs:/etc/netmaker
-    environment: # Necessary capabilities to set iptables when running in container
-      BROKER_ENDPOINT: "wss://broker.NETMAKER_BASE_DOMAIN" # The domain/host IP indicating the mq broker address
-      SERVER_NAME: "NETMAKER_BASE_DOMAIN" # The base domain of netmaker
-      SERVER_HOST: "SERVER_PUBLIC_IP" # Set to public IP of machine.
-      SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN" # Overrides SERVER_HOST if set. Useful for making HTTP available via different interfaces/networks.
-      NETCLIENT_AUTO_UPDATE: "enabled" # Enable auto update of netclient ? ENUM:- enabled,disabled | default: enabled
-      SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
-      COREDNS_ADDR: "SERVER_PUBLIC_IP" # Address of the CoreDNS server. Defaults to SERVER_HOST
-      DNS_MODE: "on" # Enables DNS Mode, meaning all nodes will set hosts file for private dns settings.
-      API_PORT: "8081" # The HTTP API port for Netmaker. Used for API calls / communication from front end. If changed, need to change port of BACKEND_URL for netmaker-ui.
-      REST_BACKEND: "on" # Enables the REST backend (API running on API_PORT at SERVER_HTTP_HOST). Change to "off" to turn off.
-      DISABLE_REMOTE_IP_CHECK: "off" # If turned "on", Server will not set Host based on remote IP check. This is already overridden if SERVER_HOST is set. Turned "off" by default.
-      TELEMETRY: "on" # Whether or not to send telemetry data to help improve Netmaker. Switch to "off" to opt out of sending telemetry.
-      MASTER_KEY: "REPLACE_MASTER_KEY" # The admin master key for accessing the API. Change this in any production installation.
-      CORS_ALLOWED_ORIGIN: "*" # The "allowed origin" for API requests. Change to restrict where API requests can come from with comma-separated URLs. ex:- https://dashboard.netmaker.domain1.com,https://dashboard.netmaker.domain2.com
-      DISPLAY_KEYS: "on" # Show keys permanently in UI (until deleted) as opposed to 1-time display.
-      DATABASE: "sqlite" # Database to use - sqlite, postgres, or rqlite
-      NODE_ID: "netmaker-server-1" # used for HA - identifies this server vs other servers
-      SERVER_BROKER_ENDPOINT: ""ws://mq:1883""  # the address of the mq server. If running from docker compose it will be "mq". Otherwise, need to input address. If using "host networking", it will find and detect the IP of the mq container.
-      MQ_USERNAME: "REPLACE_MQ_USERNAME" # the username to set for MQ access
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD" # the password to set for MQ access
-      STUN_PORT: "3478" # the reachable port of STUN on the server
-      VERBOSITY: "1" # logging verbosity level - 1, 2, or 3
-      # this section is for OAuth
-      AUTH_PROVIDER: "" # "<azure-ad|github|google|oidc>"
-      CLIENT_ID: "" # "<client id of your oauth provider>"
-      CLIENT_SECRET: "" # "<client secret of your oauth provider>"
-      FRONTEND_URL: "" # "https://dashboard.<netmaker base domain>"
-      AZURE_TENANT: "" # "<only for azure, you may optionally specify the tenant for the OAuth>"
-      OIDC_ISSUER: "" # https://oidc.yourprovider.com - URL of oidc provider
-      DEFAULT_PROXY_MODE: "off" # if ON, all new clients will enable proxy by default if OFF, all new clients will disable proxy by default, if AUTO, stick with the existing logic for NAT detection
-      TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN" # domain for your turn server
-      TURN_SERVER_API_HOST: "https://turnapi.NETMAKER_BASE_DOMAIN" # domain of the turn api server
-      TURN_PORT: "3479" #  port to access turn server
-      TURN_USERNAME: "REPLACE_TURN_USERNAME"  # the username to set for turn api access
-      TURN_PASSWORD: "REPLACE_TURN_PASSWORD" #  the password to set for turn api access
-      USE_TURN: "true" #config for using turn, accepts either true/false
-    ports:
-      - "3478:3478/udp" # the stun port
-  netmaker-ui:  # The Netmaker UI Component
-    container_name: netmaker-ui
-    image: gravitl/netmaker-ui:REPLACE_UI_IMAGE_TAG
-    depends_on:
-      - netmaker
-    links:
-      - "netmaker:api"
-    restart: always
-    environment:
-      BACKEND_URL: "https://api.NETMAKER_BASE_DOMAIN" # URL where UI will send API requests. Change based on SERVER_HOST, SERVER_HTTP_HOST, and API_PORT
-  caddy: # The reverse proxy that manages traffic for Netmaker
-    image: caddy:2.6.2
-    container_name: caddy
-    restart: unless-stopped
-    volumes:
-      - /root/Caddyfile:/etc/caddy/Caddyfile # Config file for Caddy
-      - /root/certs:/root/certs
-      - caddy_data:/data
-      - caddy_conf:/config
-    ports:
-      - "80:80"
-      - "443:443"
-  coredns: # The DNS Server. CoreDNS can be removed unless doing special advanced use cases
-    container_name: coredns
-    image: coredns/coredns
-    command: -conf /root/dnsconfig/Corefile
-    depends_on:
-      - netmaker
-    restart: always
-    volumes:
-      - dnsconfig:/root/dnsconfig
-  mq: # the mqtt broker for netmaker
-    container_name: mq
-    image: eclipse-mosquitto:2.0.15-openssl
-    depends_on:
-      - netmaker
-    restart: unless-stopped
-    command: ["/mosquitto/config/wait.sh"]
-    environment:
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD" # must be same value as in netmaker env 
-      MQ_USERNAME: "REPLACE_MQ_USERNAME" # must be same value as in netmaker env
-    volumes:
-      - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
-      - /root/wait.sh:/mosquitto/config/wait.sh
-      - mosquitto_logs:/mosquitto/log
-    ports:
-      - "1883:1883"
-      - "8883:8883"
-  turn:
-    container_name: turn
-    image: gravitl/turnserver:v1.0.0
-    network_mode: "host"
-    volumes:
-      - turn_server:/etc/config
-    environment:
-      DEBUG_MODE: "off"
-      VERBOSITY: "1"
-      TURN_PORT: "3479"
-      TURN_API_PORT: "8089"
-      CORS_ALLOWED_ORIGIN: "*"
-      TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
-      USERNAME: "REPLACE_TURN_USERNAME"
-      PASSWORD: "REPLACE_TURN_PASSWORD"
-      USE_TURN: "true"
-volumes:
-  caddy_data: {} # runtime data for caddy
-  caddy_conf: {} # configuration file for Caddy
-  shared_certs: {} # netmaker certs generated for MQ comms - used by nodes/servers
-  sqldata: {} # storage for embedded sqlite
-  dnsconfig: {} # storage for coredns
-  mosquitto_logs: {} # storage for mqtt logs
-  turn_server: {}

+ 52 - 54
compose/docker-compose.yml

@@ -1,71 +1,69 @@
 version: "3.4"
 
 services:
+
   netmaker:
     container_name: netmaker
-    image: gravitl/netmaker:REPLACE_SERVER_IMAGE_TAG
+    image: gravitl/netmaker:$SERVER_IMAGE_TAG
+    env_file: ./netmaker.env
     restart: on-failure
     volumes:
       - dnsconfig:/root/config/dnsconfig
       - sqldata:/root/data
     environment:
-      BROKER_ENDPOINT: "wss://broker.NETMAKER_BASE_DOMAIN"
-      SERVER_NAME: "NETMAKER_BASE_DOMAIN"
-      STUN_LIST: "stun.NETMAKER_BASE_DOMAIN:3478,stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302"
-      SERVER_HOST: "SERVER_PUBLIC_IP"
-      SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
-      COREDNS_ADDR: "SERVER_PUBLIC_IP"
-      DNS_MODE: "on"
-      SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN"
-      NETCLIENT_AUTO_UPDATE: "enabled"
-      API_PORT: "8081"
-      MASTER_KEY: "REPLACE_MASTER_KEY"
-      CORS_ALLOWED_ORIGIN: "*"
-      DISPLAY_KEYS: "on"
-      DATABASE: "sqlite"
-      NODE_ID: "netmaker-server-1"
-      SERVER_BROKER_ENDPOINT: "ws://mq:1883"
-      VERBOSITY: "1"
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
-      MQ_USERNAME: "REPLACE_MQ_USERNAME"
-      STUN_PORT: "3478"
-      DEFAULT_PROXY_MODE: "off"
-      TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
-      TURN_SERVER_API_HOST: "https://turnapi.NETMAKER_BASE_DOMAIN"
-      TURN_PORT: "3479"
-      TURN_USERNAME: "REPLACE_TURN_USERNAME"
-      TURN_PASSWORD: "REPLACE_TURN_PASSWORD"
-      USE_TURN: "true"
+      # config-dependant vars
+      - STUN_LIST=stun.${NM_DOMAIN}:${STUN_PORT},stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302
+      # The domain/host IP indicating the mq broker address
+      - BROKER_ENDPOINT=wss://broker.${NM_DOMAIN}
+      # The base domain of netmaker
+      - SERVER_NAME=${NM_DOMAIN}
+      - SERVER_API_CONN_STRING=api.${NM_DOMAIN}:443
+      # Address of the CoreDNS server. Defaults to SERVER_HOST
+      - COREDNS_ADDR=${SERVER_HOST}
+      # Overrides SERVER_HOST if set. Useful for making HTTP available via different interfaces/networks.
+      - SERVER_HTTP_HOST=api.${NM_DOMAIN}
+      # domain for your turn server
+      - TURN_SERVER_HOST=turn.${NM_DOMAIN}
+      # domain of the turn api server
+      - TURN_SERVER_API_HOST=https://turnapi.${NM_DOMAIN}
     ports:
       - "3478:3478/udp"
+
   netmaker-ui:
     container_name: netmaker-ui
-    image: gravitl/netmaker-ui:REPLACE_UI_IMAGE_TAG
+    image: gravitl/netmaker-ui:$UI_IMAGE_TAG
+    env_file: ./netmaker.env
+    environment:
+      # config-dependant vars
+      # URL where UI will send API requests. Change based on SERVER_HOST, SERVER_HTTP_HOST, and API_PORT
+      BACKEND_URL: "https://api.${NM_DOMAIN}"
     depends_on:
       - netmaker
     links:
       - "netmaker:api"
     restart: always
-    environment:
-      BACKEND_URL: "https://api.NETMAKER_BASE_DOMAIN"
+
   caddy:
     image: caddy:2.6.2
     container_name: caddy
+    env_file: ./netmaker.env
     restart: unless-stopped
     extra_hosts:
       - "host.docker.internal:host-gateway"
     volumes:
-      - /root/Caddyfile:/etc/caddy/Caddyfile
-      - /root/certs:/root/certs
+      - ./Caddyfile:/etc/caddy/Caddyfile
+      - ./certs:/root/certs
       - caddy_data:/data
       - caddy_conf:/config
     ports:
       - "80:80"
       - "443:443"
+
   coredns:
     container_name: coredns
     image: coredns/coredns
     command: -conf /root/dnsconfig/Corefile
+    env_file: ./netmaker.env
     depends_on:
       - netmaker
     restart: always
@@ -74,36 +72,36 @@ services:
   mq:
     container_name: mq
     image: eclipse-mosquitto:2.0.15-openssl
+    env_file: ./netmaker.env
     depends_on:
       - netmaker
     restart: unless-stopped
-    command: ["/mosquitto/config/wait.sh"]
-    environment:
-      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
-      MQ_USERNAME: "REPLACE_MQ_USERNAME"
+    command: [ "/mosquitto/config/wait.sh" ]
     volumes:
-      - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
-      - /root/wait.sh:/mosquitto/config/wait.sh
+      - ./mosquitto.conf:/mosquitto/config/mosquitto.conf
+      - ./wait.sh:/mosquitto/config/wait.sh
       - mosquitto_logs:/mosquitto/log
+      - mosquitto_data:/mosquitto/data
+
   turn:
     container_name: turn
     image: gravitl/turnserver:v1.0.0
+    env_file: ./netmaker.env
+    environment:
+      # config-dependant vars
+      - USERNAME=${TURN_USERNAME}
+      - PASSWORD=${TURN_PASSWORD}
+      # domain for your turn server
+      - TURN_SERVER_HOST=turn.${NM_DOMAIN}
     network_mode: "host"
     volumes:
       - turn_server:/etc/config
-    environment:
-      DEBUG_MODE: "off"
-      VERBOSITY: "1"
-      TURN_PORT: "3479"
-      TURN_API_PORT: "8089"
-      CORS_ALLOWED_ORIGIN: "*"
-      TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
-      USERNAME: "REPLACE_TURN_USERNAME"
-      PASSWORD: "REPLACE_TURN_PASSWORD"
+
 volumes:
-  caddy_data: {}
-  caddy_conf: {}
-  sqldata: {}
-  dnsconfig: {}
-  mosquitto_logs: {}
-  turn_server: {}
+  caddy_data: { } # runtime data for caddy
+  caddy_conf: { } # configuration file for Caddy
+  sqldata: { }
+  dnsconfig: { } # storage for coredns
+  mosquitto_logs: { } # storage for mqtt logs
+  mosquitto_data: { } # storage for mqtt data
+  turn_server: { }

+ 9 - 9
docker/Caddyfile

@@ -1,10 +1,10 @@
 # Dashboard
-https://dashboard.NETMAKER_BASE_DOMAIN {
+https://dashboard.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	# Apply basic security headers
 	header {
-		# Enable cross origin access to *.NETMAKER_BASE_DOMAIN
-		Access-Control-Allow-Origin *.NETMAKER_BASE_DOMAIN
+		# Enable cross origin access to *.{$NM_DOMAIN}
+		Access-Control-Allow-Origin *.{$NM_DOMAIN}
 		# Enable HTTP Strict Transport Security (HSTS)
 		Strict-Transport-Security "max-age=31536000;"
 		# Enable cross-site filter (XSS) and tell browser to block detected attacks
@@ -21,31 +21,31 @@ https://dashboard.NETMAKER_BASE_DOMAIN {
 }
 
 # API
-https://api.NETMAKER_BASE_DOMAIN {
+https://api.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy http://netmaker:8081
 }
 
 # STUN
-https://stun.NETMAKER_BASE_DOMAIN {
+https://stun.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy netmaker:3478
 }
 
 # TURN
-https://turn.NETMAKER_BASE_DOMAIN {
+https://turn.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy host.docker.internal:3479
 }
 
 # TURN API
-https://turnapi.NETMAKER_BASE_DOMAIN {
+https://turnapi.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
-    reverse_proxy http://host.docker.internal:8089
+	reverse_proxy http://host.docker.internal:8089
 }
 
 # MQ
-wss://broker.NETMAKER_BASE_DOMAIN {
+wss://broker.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy ws://mq:8883 # For EMQX websockets use `reverse_proxy ws://mq:8083`
 }

+ 11 - 11
docker/Caddyfile-EE

@@ -1,10 +1,10 @@
 # Dashboard
-https://dashboard.NETMAKER_BASE_DOMAIN {
+https://dashboard.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	# Apply basic security headers
 	header {
-		# Enable cross origin access to *.NETMAKER_BASE_DOMAIN
-		Access-Control-Allow-Origin *.NETMAKER_BASE_DOMAIN
+		# Enable cross origin access to *.{$NM_DOMAIN}
+		Access-Control-Allow-Origin *.{$NM_DOMAIN}
 		# Enable HTTP Strict Transport Security (HSTS)
 		Strict-Transport-Security "max-age=31536000;"
 		# Enable cross-site filter (XSS) and tell browser to block detected attacks
@@ -21,49 +21,49 @@ https://dashboard.NETMAKER_BASE_DOMAIN {
 }
 
 # Netmaker Exporter
-https://netmaker-exporter.NETMAKER_BASE_DOMAIN {
+https://netmaker-exporter.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy http://netmaker-exporter:8085
 }
 
 # Prometheus
-https://prometheus.NETMAKER_BASE_DOMAIN {
+https://prometheus.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy http://prometheus:9090
 }
 
 # Grafana
-https://grafana.NETMAKER_BASE_DOMAIN {
+https://grafana.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy http://grafana:3000
 }
 
 # API
-https://api.NETMAKER_BASE_DOMAIN {
+https://api.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy http://netmaker:8081
 }
 
 # STUN
-https://stun.NETMAKER_BASE_DOMAIN {
+https://stun.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy netmaker:3478
 }
 
 # TURN
-https://turn.NETMAKER_BASE_DOMAIN {
+https://turn.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy host.docker.internal:3479
 }
 
 # TURN API
-https://turnapi.NETMAKER_BASE_DOMAIN {
+https://turnapi.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy http://host.docker.internal:8089
 }
 
 # MQ
-wss://broker.NETMAKER_BASE_DOMAIN {
+wss://broker.{$NM_DOMAIN} {
 	tls /root/certs/fullchain.pem /root/certs/privkey.pem
 	reverse_proxy ws://mq:8883
 }

+ 82 - 0
scripts/netmaker.env

@@ -0,0 +1,82 @@
+# Email used for SSL certificates
+NM_EMAIL=
+# The base domain of netmaker
+NM_DOMAIN=
+# Public IP of machine
+SERVER_HOST=
+# The admin master key for accessing the API. Change this in any production installation.
+MASTER_KEY=
+# The username to set for turn api access
+TURN_USERNAME=
+# The password to set for turn api access
+TURN_PASSWORD=
+# The username to set for MQ access
+MQ_USERNAME=
+# The password to set for MQ access
+MQ_PASSWORD=
+INSTALL_TYPE=
+NETMAKER_ACCOUNT_ID=
+LICENSE_KEY=
+SERVER_IMAGE_TAG=
+UI_IMAGE_TAG=
+# used for HA - identifies this server vs other servers
+NODE_ID="netmaker-server-1"
+METRICS_EXPORTER="off"
+PROMETHEUS="off"
+# Enables DNS Mode, meaning all nodes will set hosts file for private dns settings
+DNS_MODE="on"
+# Enable auto update of netclient ? ENUM:- enabled,disabled | default=enabled
+NETCLIENT_AUTO_UPDATE="enabled"
+# The HTTP API port for Netmaker. Used for API calls / communication from front end.
+# If changed, need to change port of BACKEND_URL for netmaker-ui.
+API_PORT="8081"
+EXPORTER_API_PORT="8085"
+# The "allowed origin" for API requests. Change to restrict where API requests can come from with comma-separated
+# URLs. ex:- https://dashboard.netmaker.domain1.com,https://dashboard.netmaker.domain2.com
+CORS_ALLOWED_ORIGIN="*"
+# Show keys permanently in UI (until deleted) as opposed to 1-time display.
+DISPLAY_KEYS="on"
+# Database to use - sqlite, postgres, or rqlite
+DATABASE="sqlite"
+# The address of the mq server. If running from docker compose it will be "mq". Otherwise, need to input address.
+# If using "host networking", it will find and detect the IP of the mq container.
+SERVER_BROKER_ENDPOINT="ws://mq:1883"
+# The reachable port of STUN on the server
+STUN_PORT="3478"
+# Logging verbosity level - 1, 2, or 3
+VERBOSITY="1"
+# If ON, all new clients will enable proxy by default
+# If OFF, all new clients will disable proxy by default
+# If AUTO, stick with the existing logic for NAT detection
+DEFAULT_PROXY_MODE="off"
+# Port to access turn server
+TURN_PORT="3479"
+# Config for using turn, accepts either true/false
+USE_TURN="true"
+DEBUG_MODE="off"
+TURN_API_PORT="8089"
+# Enables the REST backend (API running on API_PORT at SERVER_HTTP_HOST).
+# Change to "off" to turn off.
+REST_BACKEND="on"
+# If turned "on", Server will not set Host based on remote IP check.
+# This is already overridden if SERVER_HOST is set. Turned "off" by default.
+DISABLE_REMOTE_IP_CHECK="off"
+# Whether or not to send telemetry data to help improve Netmaker. Switch to "off" to opt out of sending telemetry.
+TELEMETRY="on"
+###
+#
+# OAuth section
+#
+###
+# "<azure-ad|github|google|oidc>"
+AUTH_PROVIDER=
+# "<client id of your oauth provider>"
+CLIENT_ID=
+# "<client secret of your oauth provider>"
+CLIENT_SECRET=
+# "https://dashboard.<netmaker base domain>"
+FRONTEND_URL=
+# "<only for azure, you may optionally specify the tenant for the OAuth>"
+AZURE_TENANT=
+# https://oidc.yourprovider.com - URL of oidc provider
+OIDC_ISSUER=

+ 4 - 4
scripts/nm-certs.sh

@@ -64,8 +64,8 @@ sudo docker run -it --rm --name certbot \
 	--entrypoint "/opt/certbot/certbot-entry.sh" \
 	certbot/certbot
 
-# clean up TODO enable
-#rm "$SCRIPT_DIR/certbot-entry.sh"
+# clean up
+rm "$SCRIPT_DIR/certbot-entry.sh"
 
 # check if successful
 if [ ! -f "$CERT_DIR"/fullchain.pem ]; then
@@ -84,8 +84,8 @@ fi
 
 # copy for mounting
 mkdir -p certs
-cp -L "$CERT_DIR/fullchain.pem" /root/certs/fullchain.pem
-cp -L "$CERT_DIR/privkey.pem" /root/certs/privkey.pem
+cp -L "$CERT_DIR/fullchain.pem" "$SCRIPT_DIR/certs/fullchain.pem"
+cp -L "$CERT_DIR/privkey.pem" "$SCRIPT_DIR/certs/privkey.pem"
 
 echo "SSL certificates ready"
 

+ 196 - 96
scripts/nm-quick.sh

@@ -148,13 +148,13 @@ set_buildinfo() {
 # install_yq - install yq if not present
 install_yq() {
 	if ! command -v yq &>/dev/null; then
-		wget -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_$(dpkg --print-architecture)
+		wget -qO /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_$(dpkg --print-architecture)
 		chmod +x /usr/bin/yq
 	fi
 	set +e
 	if ! command -v yq &>/dev/null; then
 		set -e
-		wget -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_amd64
+		wget -qO /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_amd64
 		chmod +x /usr/bin/yq
 	fi
 	set -e
@@ -172,21 +172,44 @@ setup_netclient() {
 	netclient uninstall
 	set -e
 
-	wget -O netclient https://github.com/gravitl/netclient/releases/download/$LATEST/netclient-linux-amd64
+	# TODO arm support
+	wget -qO netclient https://github.com/gravitl/netclient/releases/download/$LATEST/netclient-linux-amd64
 	chmod +x netclient
 	./netclient install
+	echo "Register token: $TOKEN"
 	netclient register -t $TOKEN
 
-	echo "waiting for client to become available"
-	wait_seconds 10
+	echo "waiting for netclient to become available"
+	local found=false
+	local file=/etc/netclient/nodes.yml
+	for ((a = 1; a <= 90; a++)); do
+		if [ -f "$file" ]; then
+			found=true
+			break
+		fi
+		sleep 1
+	done
+
+	if [ "$found" = false ]; then
+		echo "Error - $file not present"
+		exit 1
+	fi
 }
 
 # configure_netclient - configures server's netclient as a default host and an ingress gateway
 configure_netclient() {
 
 	NODE_ID=$(sudo cat /etc/netclient/nodes.yml | yq -r .netmaker.commonnode.id)
+	if [ "$NODE_ID" = "" ] || [ "$NODE_ID" = "null" ]; then
+		echo "Error obtaining NODE_ID for the new network"
+		exit 1
+	fi
 	echo "register complete. New node ID: $NODE_ID"
 	HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id)
+	if [ "$HOST_ID" = "" ] || [ "$HOST_ID" = "null" ]; then
+		echo "Error obtaining HOST_ID for the new network"
+		exit 1
+	fi
 	echo "making host a default"
 	echo "Host ID: $HOST_ID"
 	# set as a default host
@@ -200,7 +223,15 @@ configure_netclient() {
 # setup_nmctl - pulls nmctl and makes it executable
 setup_nmctl() {
 
-	wget -O /usr/bin/nmctl https://github.com/gravitl/netmaker/releases/download/$LATEST/nmctl-linux-amd64
+	# TODO arm support
+	local URL="https://github.com/gravitl/netmaker/releases/download/$LATEST/nmctl-linux-amd64"
+	echo "Downloading nmctl..."
+	wget -qO /usr/bin/nmctl "$URL"
+
+	if [ ! -f /usr/bin/nmctl ]; then
+		echo "Error downloading nmctl from '$URL'"
+		exit 1
+	fi
 
 	chmod +x /usr/bin/nmctl
 	echo "using server api.$NETMAKER_BASE_DOMAIN"
@@ -247,48 +278,107 @@ confirm() { (
 save_config() { (
 	echo "Saving the config to $CONFIG_PATH"
 	touch "$CONFIG_PATH"
-	# email
-	if grep -q "^NM_EMAIL=" "$CONFIG_PATH"; then
-		sed -i "s/NM_EMAIL=.*/NM_EMAIL=$EMAIL/" "$CONFIG_PATH"
+	save_config_item NM_EMAIL "$EMAIL"
+	save_config_item NM_DOMAIN "$NETMAKER_BASE_DOMAIN"
+	save_config_item UI_IMAGE_TAG "$IMAGE_TAG"
+	if [ "$BUILD_TYPE" = "local" ]; then
+		save_config_item UI_IMAGE_TAG "$LATEST"
+	else
+		save_config_item UI_IMAGE_TAG "$IMAGE_TAG"
+	fi
+	# version-specific entries
+	if [ "$INSTALL_TYPE" = "ee" ]; then
+		save_config_item NETMAKER_ACCOUNT_ID "$ACCOUNT_ID"
+		save_config_item LICENSE_KEY "$LICENSE_KEY"
+		save_config_item METRICS_EXPORTER "on"
+		save_config_item PROMETHEUS "on"
+		if [ "$BUILD_TYPE" = "version" ]; then
+			save_config_item SERVER_IMAGE_TAG "$IMAGE_TAG-ee"
+		else
+			save_config_item SERVER_IMAGE_TAG "$IMAGE_TAG"
+		fi
 	else
-		echo "NM_EMAIL=$EMAIL" >>"$CONFIG_PATH"
+		save_config_item METRICS_EXPORTER "off"
+		save_config_item PROMETHEUS "off"
+		save_config_item SERVER_IMAGE_TAG "$IMAGE_TAG"
+	fi
+	# copy entries from the previous config
+	local toCopy=("SERVER_HOST" "MASTER_KEY" "TURN_USERNAME" "MQ_USERNAME" "MQ_PASSWORD"
+		"INSTALL_TYPE" "NODE_ID" "METRICS_EXPORTER" "PROMETHEUS" "DNS_MODE" "NETCLIENT_AUTO_UPDATE" "API_PORT"
+		"CORS_ALLOWED_ORIGIN" "DISPLAY_KEYS" "DATABASE" "SERVER_BROKER_ENDPOINT" "STUN_PORT" "VERBOSITY"
+		"DEFAULT_PROXY_MODE" "TURN_PORT" "USE_TURN" "DEBUG_MODE" "TURN_API_PORT" "REST_BACKEND" "DISABLE_REMOTE_IP_CHECK"
+		"TELEMETRY" "AUTH_PROVIDER" "CLIENT_ID" "CLIENT_SECRET" "FRONTEND_URL" "AZURE_TENANT" "OIDC_ISSUER"
+		"EXPORTER_API_PORT")
+	for name in "${toCopy[@]}"; do
+		save_config_item $name "${!name}"
+	done
+	# preserve debug entries
+	if test -n "$NM_SKIP_BUILD"; then
+		save_config_item NM_SKIP_BUILD "$NM_SKIP_BUILD"
+	fi
+	if test -n "$NM_SKIP_CLONE"; then
+		save_config_item NM_SKIP_CLONE "$NM_SKIP_CLONE"
 	fi
-	# domain
-	if grep -q "^NM_DOMAIN=" "$CONFIG_PATH"; then
-		sed -i "s/NM_DOMAIN=.*/NM_DOMAIN=$NETMAKER_BASE_DOMAIN/" "$CONFIG_PATH"
+	if test -n "$NM_SKIP_DEPS"; then
+		save_config_item NM_SKIP_DEPS "$NM_SKIP_DEPS"
+	fi
+); }
+
+save_config_item() { (
+	local NAME="$1"
+	local VALUE="$2"
+	# echo "NAME $NAME"
+	# echo "VALUE $VALUE"
+	if grep -q "^$NAME=" "$CONFIG_PATH"; then
+		# TODO escape | in the value
+		sed -i "s|$NAME=.*|$NAME='$VALUE'|" "$CONFIG_PATH"
 	else
-		echo "NM_DOMAIN=$NETMAKER_BASE_DOMAIN" >>"$CONFIG_PATH"
+		echo "$NAME=\"$VALUE\"" >>"$CONFIG_PATH"
 	fi
 ); }
 
 # local_install_setup - builds artifacts based on specified branch locally to use in install
 local_install_setup() { (
-	rm -rf netmaker-tmp
-	mkdir netmaker-tmp
-	cd netmaker-tmp
-	git clone --single-branch --depth=1 --branch=$BUILD_TAG https://www.github.com/gravitl/netmaker
+	if test -z "$NM_SKIP_CLONE"; then
+		rm -rf netmaker-tmp
+		mkdir netmaker-tmp
+		cd netmaker-tmp
+		git clone --single-branch --depth=1 --branch=$BUILD_TAG https://www.github.com/gravitl/netmaker
+	else
+		cd netmaker-tmp
+		echo "Skipping git clone on NM_SKIP_CLONE"
+	fi
 	cd netmaker
 	if test -z "$NM_SKIP_BUILD"; then
 		docker build --no-cache --build-arg version=$IMAGE_TAG -t gravitl/netmaker:$IMAGE_TAG .
 	else
 		echo "Skipping build on NM_SKIP_BUILD"
 	fi
+	cp compose/docker-compose.yml "$SCRIPT_DIR/docker-compose.yml"
 	if [ "$INSTALL_TYPE" = "ee" ]; then
-		cp compose/docker-compose.ee.yml /root/docker-compose.yml
-		cp docker/Caddyfile-EE /root/Caddyfile
+		cp compose/docker-compose.ee.yml "$SCRIPT_DIR/docker-compose.override.yml"
+		cp docker/Caddyfile-EE "$SCRIPT_DIR/Caddyfile"
 	else
-		cp compose/docker-compose.yml /root/docker-compose.yml
-		cp docker/Caddyfile /root/Caddyfile
+		cp docker/Caddyfile "$SCRIPT_DIR/Caddyfile"
 	fi
-	cp scripts/nm-certs.sh /root/nm-certs.sh
-	cp docker/mosquitto.conf /root/mosquitto.conf
-	cp docker/wait.sh /root/wait.sh
+	cp scripts/nm-certs.sh "$SCRIPT_DIR/nm-certs.sh"
+	cp scripts/netmaker.env "$SCRIPT_DIR/netmaker.env"
+	ln -fs "$SCRIPT_DIR/netmaker.env" "$SCRIPT_DIR/.env"
+	cp docker/mosquitto.conf "$SCRIPT_DIR/mosquitto.conf"
+	cp docker/wait.sh "$SCRIPT_DIR/wait.sh"
 	cd ../../
-	rm -rf netmaker-tmp
+	if test -z "$NM_SKIP_CLONE"; then
+		rm -rf netmaker-tmp
+	fi
 ); }
 
 # install_dependencies - install necessary packages to run netmaker
 install_dependencies() {
+
+	if test -n "$NM_SKIP_DEPS"; then
+		return
+	fi
+
 	echo "checking dependencies..."
 
 	OS=$(uname)
@@ -399,9 +489,7 @@ set_install_vars() {
 	fi
 
 	NETMAKER_BASE_DOMAIN=nm.$(echo $IP_ADDR | tr . -).nip.io
-	# TODO dead code?
-	# COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
-	SERVER_PUBLIC_IP=$IP_ADDR
+	SERVER_HOST=$IP_ADDR
 	MASTER_KEY=$(
 		tr -dc A-Za-z0-9 </dev/urandom | head -c 30
 		echo ''
@@ -409,7 +497,7 @@ set_install_vars() {
 	DOMAIN_TYPE=""
 	echo "-----------------------------------------------------"
 	echo "Would you like to use your own domain for netmaker, or an auto-generated domain?"
-	echo "To use your own domain, add a Wildcard DNS record (e.x: *.netmaker.example.com) pointing to $SERVER_PUBLIC_IP"
+	echo "To use your own domain, add a Wildcard DNS record (e.x: *.netmaker.example.com) pointing to $SERVER_HOST"
 	echo "IMPORTANT: Due to the high volume of requests, the auto-generated domain has been rate-limited by the certificate provider."
 	echo "For this reason, we STRONGLY RECOMMEND using your own domain. Using the auto-generated domain may lead to a failed installation due to rate limiting."
 	echo "-----------------------------------------------------"
@@ -425,7 +513,7 @@ set_install_vars() {
 				break
 				;;
 			2)
-				read -p "Enter Custom Domain (make sure  *.domain points to $SERVER_PUBLIC_IP first): " domain
+				read -p "Enter Custom Domain (make sure  *.domain points to $SERVER_HOST first): " domain
 				NETMAKER_BASE_DOMAIN=$domain
 				echo "using $NETMAKER_BASE_DOMAIN"
 				DOMAIN_TYPE="custom"
@@ -456,7 +544,7 @@ set_install_vars() {
 	echo "-----------------------------------------------------"
 
 	if [[ "$DOMAIN_TYPE" == "custom" ]]; then
-		echo "before continuing, confirm DNS is configured correctly, with records pointing to $SERVER_PUBLIC_IP"
+		echo "before continuing, confirm DNS is configured correctly, with records pointing to $SERVER_HOST"
 		confirm
 	fi
 
@@ -603,7 +691,7 @@ set_install_vars() {
 	echo "-----------------------------------------------------------------"
 	echo "        domain: $NETMAKER_BASE_DOMAIN"
 	echo "         email: $EMAIL"
-	echo "     public ip: $SERVER_PUBLIC_IP"
+	echo "     public ip: $SERVER_HOST"
 	if [ "$INSTALL_TYPE" = "ee" ]; then
 		echo "       license: $LICENSE_KEY"
 		echo "    account id: $ACCOUNT_ID"
@@ -612,9 +700,11 @@ set_install_vars() {
 	echo "Confirm Settings for Installation"
 	echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
 
-	confirm
+	if [ ! "$BUILD_TYPE" = "local" ]; then
+		IMAGE_TAG="$LATEST"
+	fi
 
-	save_config
+	confirm
 }
 
 # install_netmaker - sets the config files and starts docker-compose
@@ -626,55 +716,38 @@ install_netmaker() {
 
 	wait_seconds 3
 
-	# TODO extract wgets to setup(), mirror local_setup()
 	echo "Pulling config files..."
 
-	COMPOSE_URL="https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/compose/docker-compose.yml"
-	CADDY_URL="https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/docker/Caddyfile"
-	if [ "$INSTALL_TYPE" = "ee" ]; then
-		COMPOSE_URL="https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/compose/docker-compose.ee.yml"
-		CADDY_URL="https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/docker/Caddyfile-EE"
-	fi
+	if [ "$BUILD_TYPE" = "local" ]; then
+		local_install_setup
+	else
+		local BASE_URL="https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG"
 
-	if [ ! "$BUILD_TYPE" = "local" ]; then
-		wget -qO /root/docker-compose.yml $COMPOSE_URL
-		wget -qO /root/Caddyfile $CADDY_URL
-		wget -qO /root/mosquitto.conf "https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/docker/mosquitto.conf"
-		wget -qO /root/nm-certs.sh "https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/scripts/nm-certs.sh"
-		wget -qO /root/wait.sh "https://raw.githubusercontent.com/gravitl/netmaker/$BUILD_TAG/docker/wait.sh"
+		local COMPOSE_URL="$BASE_URL/compose/docker-compose.yml"
+		local CADDY_URL="$BASE_URL/docker/Caddyfile"
+		if [ "$INSTALL_TYPE" = "ee" ]; then
+			local COMPOSE_OVERRIDE_URL="$BASE_URL/compose/docker-compose.ee.yml"
+			local CADDY_URL="$BASE_URL/docker/Caddyfile-EE"
+		fi
+		wget -qO "$SCRIPT_DIR"/docker-compose.yml $COMPOSE_URL
+		if test -n "$COMPOSE_OVERRIDE_URL"; then
+			wget -qO "$SCRIPT_DIR"/docker-compose.override.yml $COMPOSE_OVERRIDE_URL
+		fi
+		wget -qO "$SCRIPT_DIR"/Caddyfile "$CADDY_URL"
+		wget -qO "$SCRIPT_DIR"/netmaker.env "$BASE_URL/scripts/netmaker.env"
+		ln -fs "$SCRIPT_DIR/netmaker.env" "$SCRIPT_DIR/.env"
+		wget -qO "$SCRIPT_DIR"/mosquitto.conf "$BASE_URL/docker/mosquitto.conf"
+		wget -qO "$SCRIPT_DIR"/nm-certs.sh "$BASE_URL/scripts/nm-certs.sh"
+		wget -qO "$SCRIPT_DIR"/wait.sh "$BASE_URL/docker/wait.sh"
 	fi
 
-	chmod +x /root/wait.sh
+	chmod +x "$SCRIPT_DIR"/wait.sh
 	mkdir -p /etc/netmaker
 
-	echo "Setting docker-compose and Caddyfile..."
-
-	sed -i "s/SERVER_PUBLIC_IP/$SERVER_PUBLIC_IP/g" /root/docker-compose.yml
-	sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/Caddyfile
-	sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/docker-compose.yml
-	sed -i "s/REPLACE_MASTER_KEY/$MASTER_KEY/g" /root/docker-compose.yml
-	sed -i "s/YOUR_EMAIL/$EMAIL/g" /root/Caddyfile
-	sed -i "s/REPLACE_MQ_USERNAME/$MQ_USERNAME/g" /root/docker-compose.yml
-	sed -i "s/REPLACE_MQ_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml
-	sed -i "s/REPLACE_TURN_USERNAME/$TURN_USERNAME/g" /root/docker-compose.yml
-	sed -i "s/REPLACE_TURN_PASSWORD/$TURN_PASSWORD/g" /root/docker-compose.yml
-
-	if [ "$INSTALL_TYPE" = "ee" ]; then
-		sed -i "s~YOUR_LICENSE_KEY~$LICENSE_KEY~g" /root/docker-compose.yml
-		sed -i "s/YOUR_ACCOUNT_ID/$ACCOUNT_ID/g" /root/docker-compose.yml
-	fi
-
-	if [ "$BUILD_TYPE" = "version" ] && [ "$INSTALL_TYPE" = "ee" ]; then
-		sed -i "s/REPLACE_SERVER_IMAGE_TAG/$IMAGE_TAG-ee/g" /root/docker-compose.yml
-	else
-		sed -i "s/REPLACE_SERVER_IMAGE_TAG/$IMAGE_TAG/g" /root/docker-compose.yml
-	fi
+	save_config
 
-	if [ "$BUILD_TYPE" = "local" ]; then
-		sed -i "s/REPLACE_UI_IMAGE_TAG/$LATEST/g" /root/docker-compose.yml
-	else
-		sed -i "s/REPLACE_UI_IMAGE_TAG/$IMAGE_TAG/g" /root/docker-compose.yml
-	fi
+	# Fetch / update certs using certbot
+	"$SCRIPT_DIR"/nm-certs.sh
 
 	echo "Starting containers..."
 
@@ -683,7 +756,7 @@ install_netmaker() {
 	export COMPOSE_HTTP_TIMEOUT=120
 
 	# start docker and rebuild containers / networks
-	docker-compose -f /root/docker-compose.yml up -d --force-recreate
+	docker-compose -f "$SCRIPT_DIR"/docker-compose.yml up -d --force-recreate
 
 	wait_seconds 2
 
@@ -720,16 +793,28 @@ setup_mesh() {
 
 	wait_seconds 5
 
-	echo "Creating netmaker network (10.101.0.0/16)"
+	local networkCount=$(nmctl network list -o json | jq '. | length')
 
-	nmctl network create --name netmaker --ipv4_addr 10.101.0.0/16
+	# add a network if none present
+	if [ "$networkCount" -lt 1 ]; then
+		echo "Creating netmaker network (10.101.0.0/16)"
 
-	wait_seconds 5
+		# TODO causes "Error Status: 400 Response: {"Code":400,"Message":"could not find any records"}"
+		nmctl network create --name netmaker --ipv4_addr 10.101.0.0/16
+
+		wait_seconds 5
+	fi
 
-	echo "Creating netmaker enrollment key"
+	echo "Obtaining a netmaker enrollment key..."
 
-	tokenJson=$(nmctl enrollment_key create --unlimited --networks netmaker)
+	local tokenJson=$(nmctl enrollment_key create --unlimited --networks netmaker)
 	TOKEN=$(jq -r '.token' <<<${tokenJson})
+	if test -z "$TOKEN"; then
+		echo "Error creating an enrollment key"
+		exit 1
+	else
+		echo "Enrollment key ready"
+	fi
 
 	wait_seconds 3
 
@@ -745,6 +830,32 @@ print_success() {
 	echo "-----------------------------------------------------------------"
 }
 
+cleanup() {
+	# remove the existing netclient's instance from the existing network
+	if command -v nmctl >/dev/null 2>&1; then
+		local node_id=$(netclient list | jq '.[0].node_id' 2>/dev/null)
+		# trim doublequotes
+		node_id="${node_id//\"/}"
+		if test -n "$node_id"; then
+			echo "De-registering the existing netclient..."
+			nmctl node delete netmaker $node_id >/dev/null 2>&1
+		fi
+	fi
+
+	echo "Stopping all containers..."
+	local containers=("mq" "netmaker-ui" "coredns" "turn" "caddy" "netmaker" "netmaker-exporter" "prometheus" "grafana")
+	for name in "${containers[@]}"; do
+		local running=$(docker ps | grep -w "$name")
+		local exists=$(docker ps -a | grep -w "$name")
+		if test -n "$running"; then
+			docker stop "$name" 1>/dev/null
+		fi
+		if test -n "$exists"; then
+			docker rm "$name" 1>/dev/null
+		fi
+	done
+}
+
 # 1. print netmaker logo
 print_logo
 
@@ -759,25 +870,14 @@ install_dependencies
 # 4. install yq if necessary
 install_yq
 
-# 5. if running a local build, clone git and build artifacts
-if [ "$BUILD_TYPE" = "local" ]; then
-	local_install_setup
-fi
-
 set -e
 
 # 6. get user input for variables
 set_install_vars
 
-# stop
-for name in "mq" "netmaker-ui" "coredns" "turn" "caddy" "netmaker"; do
-	if test -n "$(docker ps | grep name)"; then
-		docker stop $name
-	fi
-done
-
-# Fetch / update certs using certbot
-"$SCRIPT_DIR"/nm-certs.sh
+set +e
+cleanup
+set -e
 
 # 7. get and set config files, startup docker-compose
 install_netmaker