docker-entrypoint.sh 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #!/bin/bash
  2. ## EMQ docker image start script
  3. # Huang Rui <vowstar@gmail.com>
  4. # EMQ X Team <support@emqx.io>
  5. ## Shell setting
  6. if [[ -n "$DEBUG" ]]; then
  7. set -ex
  8. else
  9. set -e
  10. fi
  11. shopt -s nullglob
  12. ## Local IP address setting
  13. LOCAL_IP=$(hostname -i | grep -oE '((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])\.){3}(25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])' | head -n 1)
  14. ## EMQ Base settings and plugins setting
  15. # Base settings in /opt/emqx/etc/emqx.conf
  16. # Plugin settings in /opt/emqx/etc/plugins
  17. _EMQX_HOME='/opt/emqx'
  18. if [[ -z "$EMQX_NAME" ]]; then
  19. EMQX_NAME="$(hostname)"
  20. export EMQX_NAME
  21. fi
  22. if [[ -z "$EMQX_HOST" ]]; then
  23. if [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then
  24. EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"}
  25. EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX"
  26. elif [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then
  27. EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'}
  28. EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX")
  29. else
  30. EMQX_HOST="$LOCAL_IP"
  31. fi
  32. export EMQX_HOST
  33. fi
  34. if [[ -z "$EMQX_WAIT_TIME" ]]; then
  35. export EMQX_WAIT_TIME=5
  36. fi
  37. if [[ -z "$EMQX_NODE_NAME" ]]; then
  38. export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST"
  39. fi
  40. # Set hosts to prevent cluster mode failed
  41. if [[ -z "$EMQX_NODE__PROCESS_LIMIT" ]]; then
  42. export EMQX_NODE__PROCESS_LIMIT=2097152
  43. fi
  44. if [[ -z "$EMQX_NODE__MAX_PORTS" ]]; then
  45. export EMQX_NODE__MAX_PORTS=1048576
  46. fi
  47. if [[ -z "$EMQX_NODE__MAX_ETS_TABLES" ]]; then
  48. export EMQX_NODE__MAX_ETS_TABLES=2097152
  49. fi
  50. if [[ -z "$EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS" ]]; then
  51. export EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS=64
  52. fi
  53. if [[ -z "$EMQX_LISTENER__TCP__EXTERNAL__MAX_CONNECTIONS" ]]; then
  54. export EMQX_LISTENER__TCP__EXTERNAL__MAX_CONNECTIONS=1024000
  55. fi
  56. if [[ -z "$EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS" ]]; then
  57. export EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS=32
  58. fi
  59. if [[ -z "$EMQX_LISTENER__SSL__EXTERNAL__MAX_CONNECTIONS" ]]; then
  60. export EMQX_LISTENER__SSL__EXTERNAL__MAX_CONNECTIONS=102400
  61. fi
  62. if [[ -z "$EMQX_LISTENER__WS__EXTERNAL__ACCEPTORS" ]]; then
  63. export EMQX_LISTENER__WS__EXTERNAL__ACCEPTORS=16
  64. fi
  65. if [[ -z "$EMQX_LISTENER__WS__EXTERNAL__MAX_CONNECTIONS" ]]; then
  66. export EMQX_LISTENER__WS__EXTERNAL__MAX_CONNECTIONS=102400
  67. fi
  68. if [[ -z "$EMQX_LISTENER__WSS__EXTERNAL__ACCEPTORS" ]]; then
  69. export EMQX_LISTENER__WSS__EXTERNAL__ACCEPTORS=16
  70. fi
  71. if [[ -z "$EMQX_LISTENER__WSS__EXTERNAL__MAX_CONNECTIONS" ]]; then
  72. export EMQX_LISTENER__WSS__EXTERNAL__MAX_CONNECTIONS=102400
  73. fi
  74. # Fix issue #42 - export env EMQX_DASHBOARD__DEFAULT_USER__PASSWORD to configure
  75. # 'dashboard.default_user.password' in etc/plugins/emqx_dashboard.conf
  76. if [[ -n "$EMQX_ADMIN_PASSWORD" ]]; then
  77. export EMQX_DASHBOARD__DEFAULT_USER__PASSWORD=$EMQX_ADMIN_PASSWORD
  78. fi
  79. # echo value of $VAR hiding secrets if any
  80. # SYNOPSIS
  81. # echo_value KEY VALUE
  82. echo_value() {
  83. # get MASK_CONFIG
  84. MASK_CONFIG_FILTER="$MASK_CONFIG_FILTER|password|passwd|key|token|secret"
  85. FORMAT_MASK_CONFIG_FILTER=$(echo "$MASK_CONFIG_FILTER" | sed -r -e 's/^[^A-Za-z0-9_]+//' -e 's/[^A-Za-z0-9_]+$//' -e 's/[^A-Za-z0-9_]+/|/g')
  86. local key=$1
  87. local value=$2
  88. # check if contains sensitive value
  89. if echo "$key" | grep -iqwE "$FORMAT_MASK_CONFIG_FILTER"; then
  90. echo "$key=***secret***"
  91. else
  92. echo "$key=$value"
  93. fi
  94. }
  95. # fill config on specific file if the key exists
  96. # SYNOPSIS
  97. # try_fill_config FILE KEY VALUE
  98. try_fill_config() {
  99. local file=$1
  100. local key=$2
  101. local value=$3
  102. local escaped_key
  103. # shellcheck disable=SC2001
  104. escaped_key=$(echo "$key" | sed 's/[^a-zA-Z0-9_]/\\&/g')
  105. local escaped_value
  106. escaped_value=$(echo "$value" | sed 's/[\/&]/\\&/g')
  107. if grep -qE "^[#[:space:]]*$escaped_key\s*=" "$file"; then
  108. echo_value "$key" "$value"
  109. if [[ -z "$value" ]]; then
  110. echo "$(sed -r "s/^[#[:space:]]*($escaped_key)\s*=\s*(.*)/# \1 = \2/" "$file")" > "$file"
  111. else
  112. echo "$(sed -r "s/^[#[:space:]]*($escaped_key)\s*=\s*(.*)/\1 = $escaped_value/" "$file")" > "$file"
  113. fi
  114. # Check if config has a numbering system, but no existing configuration line in file
  115. elif echo "$key" | grep -qE '\.\d+|\d+\.'; then
  116. if [[ -n "$value" ]]; then
  117. local template
  118. template="$(echo "$escaped_key" | sed -r -e 's/\\\.[0-9]+/\\.[0-9]+/g' -e 's/[0-9]+\\\./[0-9]+\\./g')"
  119. if grep -qE "^[#[:space:]]*$template\s*=" "$file"; then
  120. echo_value "$key" "$value"
  121. echo "$(sed '$a'\\ "$file")" > "$file"
  122. echo "$key = $value" >> "$file"
  123. fi
  124. fi
  125. fi
  126. }
  127. # Catch all EMQX_ prefix environment variable and match it in configure file
  128. CONFIG_FILE="$_EMQX_HOME/etc/emqx.conf"
  129. CONFIG_PLUGINS="$_EMQX_HOME/etc/plugins"
  130. for VAR in $(compgen -e); do
  131. # Config normal keys such like node.name = emqx@127.0.0.1
  132. if echo "$VAR" | grep -q '^EMQX_'; then
  133. VAR_NAME=$(echo "$VAR" | sed -e 's/^EMQX_//' -e 's/__/./g' | tr '[:upper:]' '[:lower:]' | tr -d '[:cntrl:]')
  134. VAR_VALUE=$(echo "${!VAR}" | tr -d '[:cntrl:]')
  135. # Config in emqx.conf
  136. try_fill_config "$CONFIG_FILE" "$VAR_NAME" "$VAR_VALUE"
  137. # Config in plugins/*
  138. for CONFIG_PLUGINS_FILE in "$CONFIG_PLUGINS"/*; do
  139. try_fill_config "$CONFIG_PLUGINS_FILE" "$VAR_NAME" "$VAR_VALUE"
  140. done
  141. fi
  142. done
  143. # fill tuples on specific file
  144. # SYNOPSIS
  145. # fill_tuples FILE [ELEMENTS ...]
  146. fill_tuples() {
  147. local file=$1
  148. local elements=${*:2}
  149. for var in $elements; do
  150. if grep -qE "\{\s*$var\s*,\s*(true|false)\s*\}\s*\." "$file"; then
  151. echo "$(sed -r "s/\{\s*($var)\s*,\s*(true|false)\s*\}\s*\./{\1, true}./1" "$file")" > "$file"
  152. elif grep -q "$var\s*\." "$file"; then
  153. # backward compatible.
  154. echo "$(sed -r "s/($var)\s*\./{\1, true}./1" "$file")" > "$file"
  155. else
  156. echo "$(sed '$a'\\ "$file")" > "$file"
  157. echo "{$var, true}." >> "$file"
  158. fi
  159. done
  160. }
  161. ## EMQX Plugin load settings
  162. # Plugins loaded by default
  163. LOADED_PLUGINS="$_EMQX_HOME/data/loaded_plugins"
  164. if [[ -n "$EMQX_LOADED_PLUGINS" ]]; then
  165. EMQX_LOADED_PLUGINS=$(echo "$EMQX_LOADED_PLUGINS" | tr -d '[:cntrl:]' | sed -r -e 's/^[^A-Za-z0-9_]+//g' -e 's/[^A-Za-z0-9_]+$//g' -e 's/[^A-Za-z0-9_]+/ /g')
  166. echo "EMQX_LOADED_PLUGINS=$EMQX_LOADED_PLUGINS"
  167. # Parse module names and place `{module_name, true}.` tuples in `loaded_plugins`.
  168. fill_tuples "$LOADED_PLUGINS" "$EMQX_LOADED_PLUGINS"
  169. fi
  170. ## EMQX Modules load settings
  171. # Modules loaded by default
  172. LOADED_MODULES="$_EMQX_HOME/data/loaded_modules"
  173. if [[ -n "$EMQX_LOADED_MODULES" ]]; then
  174. EMQX_LOADED_MODULES=$(echo "$EMQX_LOADED_MODULES" | tr -d '[:cntrl:]' | sed -r -e 's/^[^A-Za-z0-9_]+//g' -e 's/[^A-Za-z0-9_]+$//g' -e 's/[^A-Za-z0-9_]+/ /g')
  175. echo "EMQX_LOADED_MODULES=$EMQX_LOADED_MODULES"
  176. # Parse module names and place `{module_name, true}.` tuples in `loaded_modules`.
  177. fill_tuples "$LOADED_MODULES" "$EMQX_LOADED_MODULES"
  178. fi
  179. exec "$@"