├── .github └── workflows │ └── main.yaml ├── 4.4 ├── Dockerfile └── docker-entrypoint.sh ├── 5.0 ├── Dockerfile └── docker-entrypoint.sh ├── 5.1 ├── Dockerfile └── docker-entrypoint.sh ├── 5.2 ├── Dockerfile └── docker-entrypoint.sh ├── 5.3 ├── Dockerfile └── docker-entrypoint.sh ├── 5.4 ├── Dockerfile └── docker-entrypoint.sh ├── 5.5 ├── Dockerfile └── docker-entrypoint.sh ├── 5.6 ├── Dockerfile └── docker-entrypoint.sh ├── 5.7 ├── Dockerfile └── docker-entrypoint.sh ├── 5.8 ├── Dockerfile └── docker-entrypoint.sh ├── LICENSE ├── README.md └── update.sh /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: GitHub CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - 'main' 8 | schedule: 9 | - cron: 0 0 * * 0 10 | 11 | defaults: 12 | run: 13 | shell: 'bash -Eeuo pipefail {0}' 14 | 15 | jobs: 16 | main: 17 | runs-on: ubuntu-latest 18 | strategy: 19 | matrix: 20 | version: 21 | - '5.7' 22 | - '5.8' 23 | 24 | steps: 25 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 26 | - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 27 | - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 28 | - name: Docker login 29 | uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 30 | with: 31 | registry: ghcr.io 32 | username: ${{ github.actor }} 33 | password: ${{ github.token }} 34 | - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 35 | with: 36 | push: true 37 | pull: true 38 | no-cache: true 39 | platforms: linux/amd64,linux/arm64 40 | tags: ghcr.io/${{ github.repository }}:${{ matrix.version }} 41 | file: ${{ matrix.version }}/Dockerfile 42 | context: ${{ matrix.version }} 43 | - name: Check image 44 | timeout-minutes: 1 45 | run: | 46 | docker pull ghcr.io/${{ github.repository }}:${{ matrix.version }} 47 | docker run -d -p 18083:18083 --name emqx ghcr.io/${{ github.repository }}:${{ matrix.version }} 48 | while ! curl -fs 127.0.0.1:18083/status > /dev/null; do 49 | echo "waiting for emqx" 50 | sleep 1 51 | done 52 | if ! docker exec -i emqx emqx ping; then 53 | echo "emqx command not working" 54 | exit 1 55 | fi 56 | if ! docker exec -i emqx emqx ctl status; then 57 | echo "emqx ctl command not working" 58 | exit 1 59 | fi 60 | echo "================================================================" 61 | echo "emqx is running" 62 | -------------------------------------------------------------------------------- /4.4/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | RUN set -eu; \ 4 | apt-get update; \ 5 | apt-get install -y --no-install-recommends curl unzip ca-certificates; \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | RUN set -eu; \ 9 | groupadd -r -g 1000 emqx; \ 10 | useradd -r -m -u 1000 -g emqx emqx 11 | 12 | ENV EMQX_VERSION=4.4.19 13 | ENV OTP=otp24.3.4.2-1 14 | 15 | RUN set -eu; \ 16 | arch=$(dpkg --print-architecture); \ 17 | if [ ${arch} = "amd64" ]; then sha256="bf4192c64c9006733b30f96fe99506a0a3af115c7073995a044cc0e60230675e"; fi; \ 18 | if [ ${arch} = "arm64" ]; then sha256="7cd27d5112380fd4d81029b10ba862a050b0bba8af1eb90aac669189fc3053c0"; fi; \ 19 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 20 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 21 | pkg="emqx-${EMQX_VERSION}-${OTP}-${ID}${VERSION_ID}-${arch}.zip"; \ 22 | curl -f -O -L https://www.emqx.com/en/downloads/broker/${EMQX_VERSION}/${pkg}; \ 23 | echo "$(sha256sum $pkg)"; \ 24 | echo "$sha256 *$pkg" | sha256sum -c; \ 25 | unzip -q -d /opt $pkg; \ 26 | chgrp -Rf emqx /opt/emqx; \ 27 | chmod -Rf g+w /opt/emqx; \ 28 | chown -Rf emqx /opt/emqx; \ 29 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 30 | rm -rf $pkg 31 | 32 | WORKDIR /opt/emqx 33 | 34 | USER emqx 35 | 36 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 37 | 38 | # emqx will occupy these port: 39 | # - 1883 port for MQTT 40 | # - 8081 for mgmt API 41 | # - 8083 for WebSocket/HTTP 42 | # - 8084 for WSS/HTTPS 43 | # - 8883 port for MQTT(SSL) 44 | # - 11883 port for internal MQTT/TCP 45 | # - 18083 for dashboard 46 | # - 4369 epmd (Erlang-distrbution port mapper daemon) listener (deprecated) 47 | # - 4370 default Erlang distrbution port 48 | # - 5369 for gen_rpc port mapping 49 | # - 6369 6370 for distributed node 50 | EXPOSE 1883 8081 8083 8084 8883 11883 18083 4369 4370 5369 6369 6370 51 | 52 | COPY docker-entrypoint.sh /usr/bin/ 53 | 54 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 55 | 56 | CMD ["emqx", "foreground"] 57 | -------------------------------------------------------------------------------- /4.4/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## EMQ docker image start script 3 | # Huang Rui 4 | # EMQ X Team 5 | 6 | ## Shell setting 7 | if [[ -n "$DEBUG" ]]; then 8 | set -ex 9 | else 10 | set -e 11 | fi 12 | 13 | shopt -s nullglob 14 | 15 | ## EMQ Base settings and plugins setting 16 | # Base settings in /opt/emqx/etc/emqx.conf 17 | # Plugin settings in /opt/emqx/etc/plugins 18 | 19 | _EMQX_HOME='/opt/emqx' 20 | 21 | if [[ -z "$EMQX_NODE_NAME" ]]; then 22 | 23 | if [[ -z "$EMQX_NAME" ]]; then 24 | EMQX_NAME="$(hostname)" 25 | fi 26 | if [[ -z "$EMQX_HOST" ]]; then 27 | LOCAL_IP=$(hostname -i) 28 | if [[ "$EMQX_CLUSTER__DISCOVERY" == "dns" ]] && \ 29 | [[ "$EMQX_CLUSTER__DNS__TYPE" == "srv" ]] && \ 30 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 31 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 32 | elif [[ "$EMQX_CLUSTER__DISCOVERY" == "k8s" ]] && \ 33 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 34 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 35 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 36 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 37 | elif [[ "$EMQX_CLUSTER__DISCOVERY" == "k8s" ]] && \ 38 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 39 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 40 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 41 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 42 | else 43 | EMQX_HOST="$LOCAL_IP" 44 | fi 45 | export EMQX_HOST 46 | fi 47 | 48 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 49 | unset EMQX_NAME 50 | unset EMQX_HOST 51 | fi 52 | 53 | # Set hosts to prevent cluster mode failed 54 | 55 | if [[ -z "$EMQX_NODE__PROCESS_LIMIT" ]]; then 56 | export EMQX_NODE__PROCESS_LIMIT=2097152 57 | fi 58 | 59 | if [[ -z "$EMQX_NODE__MAX_PORTS" ]]; then 60 | export EMQX_NODE__MAX_PORTS=1048576 61 | fi 62 | 63 | if [[ -z "$EMQX_NODE__MAX_ETS_TABLES" ]]; then 64 | export EMQX_NODE__MAX_ETS_TABLES=2097152 65 | fi 66 | 67 | if [[ -z "$EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS" ]]; then 68 | export EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS=64 69 | fi 70 | 71 | if [[ -z "$EMQX_LISTENER__TCP__EXTERNAL__MAX_CONNECTIONS" ]]; then 72 | export EMQX_LISTENER__TCP__EXTERNAL__MAX_CONNECTIONS=1024000 73 | fi 74 | 75 | if [[ -z "$EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS" ]]; then 76 | export EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS=32 77 | fi 78 | 79 | if [[ -z "$EMQX_LISTENER__SSL__EXTERNAL__MAX_CONNECTIONS" ]]; then 80 | export EMQX_LISTENER__SSL__EXTERNAL__MAX_CONNECTIONS=102400 81 | fi 82 | 83 | if [[ -z "$EMQX_LISTENER__WS__EXTERNAL__ACCEPTORS" ]]; then 84 | export EMQX_LISTENER__WS__EXTERNAL__ACCEPTORS=16 85 | fi 86 | 87 | if [[ -z "$EMQX_LISTENER__WS__EXTERNAL__MAX_CONNECTIONS" ]]; then 88 | export EMQX_LISTENER__WS__EXTERNAL__MAX_CONNECTIONS=102400 89 | fi 90 | 91 | if [[ -z "$EMQX_LISTENER__WSS__EXTERNAL__ACCEPTORS" ]]; then 92 | export EMQX_LISTENER__WSS__EXTERNAL__ACCEPTORS=16 93 | fi 94 | 95 | if [[ -z "$EMQX_LISTENER__WSS__EXTERNAL__MAX_CONNECTIONS" ]]; then 96 | export EMQX_LISTENER__WSS__EXTERNAL__MAX_CONNECTIONS=102400 97 | fi 98 | 99 | # The default rpc port discovery 'stateless' is mostly for clusters 100 | # having static node names. So it's troulbe-free for multiple emqx nodes 101 | # running on the same host. 102 | # When start emqx in docker, it's mostly one emqx node in one container 103 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 104 | 105 | exec "$@" 106 | -------------------------------------------------------------------------------- /5.0/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | RUN set -eu; \ 4 | apt-get update; \ 5 | apt-get install -y --no-install-recommends curl ca-certificates procps; \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | RUN groupadd -r -g 1000 emqx; \ 9 | useradd -r -m -u 1000 -g emqx emqx; 10 | 11 | ENV EMQX_VERSION=5.0.26 12 | ENV AMD64_SHA256=00f954065fe7fd2f678f2e561578234240cc2cace49fb5cbb5aa7fb450825ffa 13 | ENV ARM64_SHA256=0b013f0b900e687c1ef3ed73bd6fef268b5492d12a3083ffd0d75c8e3935b4ae 14 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 15 | 16 | RUN set -eu; \ 17 | arch=$(dpkg --print-architecture); \ 18 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 19 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 20 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 21 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 22 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 23 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg} && \ 24 | echo "$sha256 *$pkg" | sha256sum -c && \ 25 | mkdir /opt/emqx && \ 26 | tar zxf $pkg -C /opt/emqx && \ 27 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 28 | chgrp -Rf emqx /opt/emqx && \ 29 | chmod -Rf g+w /opt/emqx && \ 30 | chown -Rf emqx /opt/emqx && \ 31 | ln -s /opt/emqx/bin/* /usr/local/bin/ && \ 32 | rm -f $pkg 33 | 34 | WORKDIR /opt/emqx 35 | 36 | USER emqx 37 | 38 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 39 | 40 | # emqx will occupy these port: 41 | # - 1883 port for MQTT 42 | # - 8083 for WebSocket/HTTP 43 | # - 8084 for WSS/HTTPS 44 | # - 8883 port for MQTT(SSL) 45 | # - 11883 port for internal MQTT/TCP 46 | # - 18083 for dashboard and API 47 | # - 4370 default Erlang distribution port 48 | # - 5369 for backplain gen_rpc 49 | EXPOSE 1883 8083 8084 8883 11883 18083 4370 5369 50 | 51 | COPY docker-entrypoint.sh /usr/bin/ 52 | 53 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 54 | 55 | CMD ["/opt/emqx/bin/emqx", "foreground"] 56 | -------------------------------------------------------------------------------- /5.0/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | if [[ -z "$EMQX_HOST" ]]; then 19 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 20 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 21 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 22 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 23 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 24 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 25 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 26 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 27 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 32 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 33 | else 34 | EMQX_HOST="$LOCAL_IP" 35 | fi 36 | export EMQX_HOST 37 | fi 38 | 39 | if [[ -z "$EMQX_NODE_NAME" ]]; then 40 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 41 | fi 42 | 43 | # The default rpc port discovery 'stateless' is mostly for clusters 44 | # having static node names. So it's troulbe-free for multiple emqx nodes 45 | # running on the same host. 46 | # When start emqx in docker, it's mostly one emqx node in one container 47 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 48 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /5.1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | RUN set -eu; \ 4 | apt-get update; \ 5 | apt-get install -y --no-install-recommends curl ca-certificates procps; \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | RUN groupadd -r -g 1000 emqx; \ 9 | useradd -r -m -u 1000 -g emqx emqx; 10 | 11 | ENV EMQX_VERSION=5.1.6 12 | ENV AMD64_SHA256=5c65f7538141e93d71d1dd7d088589339ef6a091b90f901604a2e0e004f5f4aa 13 | ENV ARM64_SHA256=ae832d29d6b4e7fa43f3bf04c8c9fad4c9047f079d1587d3ed2a3564d5ea8147 14 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 15 | 16 | RUN set -eu; \ 17 | arch=$(dpkg --print-architecture); \ 18 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 19 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 20 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 21 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 22 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 23 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 24 | echo "$sha256 *$pkg" | sha256sum -c; \ 25 | mkdir /opt/emqx; \ 26 | tar zxf $pkg -C /opt/emqx; \ 27 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 28 | chgrp -Rf emqx /opt/emqx; \ 29 | chmod -Rf g+w /opt/emqx; \ 30 | chown -Rf emqx /opt/emqx; \ 31 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 32 | rm -f $pkg 33 | 34 | WORKDIR /opt/emqx 35 | 36 | USER emqx 37 | 38 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 39 | 40 | # emqx will occupy these port: 41 | # - 1883 port for MQTT 42 | # - 8083 for WebSocket/HTTP 43 | # - 8084 for WSS/HTTPS 44 | # - 8883 port for MQTT(SSL) 45 | # - 11883 port for internal MQTT/TCP 46 | # - 18083 for dashboard and API 47 | # - 4370 default Erlang distribution port 48 | # - 5369 for backplain gen_rpc 49 | EXPOSE 1883 8083 8084 8883 11883 18083 4370 5369 50 | 51 | COPY docker-entrypoint.sh /usr/bin/ 52 | 53 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 54 | 55 | CMD ["/opt/emqx/bin/emqx", "foreground"] 56 | -------------------------------------------------------------------------------- /5.1/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | if [[ -z "$EMQX_HOST" ]]; then 19 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 20 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 21 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 22 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 23 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 24 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 25 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 26 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 27 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 32 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 33 | else 34 | EMQX_HOST="$LOCAL_IP" 35 | fi 36 | export EMQX_HOST 37 | fi 38 | 39 | if [[ -z "$EMQX_NODE_NAME" ]]; then 40 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 41 | fi 42 | 43 | # The default rpc port discovery 'stateless' is mostly for clusters 44 | # having static node names. So it's troulbe-free for multiple emqx nodes 45 | # running on the same host. 46 | # When start emqx in docker, it's mostly one emqx node in one container 47 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 48 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /5.2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | RUN set -eu; \ 4 | apt-get update; \ 5 | apt-get install -y --no-install-recommends ca-certificates procps; \ 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | RUN groupadd -r -g 1000 emqx; \ 9 | useradd -r -m -u 1000 -g emqx emqx; 10 | 11 | ENV EMQX_VERSION=5.2.1 12 | ENV AMD64_SHA256=359a12811e5e6725e4269d9484abd348effdde35c0f2af1f5b63cae790c73020 13 | ENV ARM64_SHA256=2e0a3e0b33669c9b6da488970a2f92d08d7bd0824295822b205b83461ba4728d 14 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 15 | 16 | RUN set -eu; \ 17 | apt-get update; \ 18 | apt-get install -y --no-install-recommends curl; \ 19 | rm -rf /var/lib/apt/lists/*; \ 20 | arch=$(dpkg --print-architecture); \ 21 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 22 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 23 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 24 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 25 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 26 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 27 | echo "$sha256 *$pkg" | sha256sum -c; \ 28 | mkdir /opt/emqx; \ 29 | tar zxf $pkg -C /opt/emqx; \ 30 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 31 | chgrp -Rf emqx /opt/emqx; \ 32 | chmod -Rf g+w /opt/emqx; \ 33 | chown -Rf emqx /opt/emqx; \ 34 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 35 | rm -f $pkg; \ 36 | apt-get purge -y --auto-remove curl 37 | 38 | WORKDIR /opt/emqx 39 | 40 | USER emqx 41 | 42 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 43 | 44 | # emqx will occupy these port: 45 | # - 1883 port for MQTT 46 | # - 8083 for WebSocket/HTTP 47 | # - 8084 for WSS/HTTPS 48 | # - 8883 port for MQTT(SSL) 49 | # - 11883 port for internal MQTT/TCP 50 | # - 18083 for dashboard and API 51 | # - 4370 default Erlang distribution port 52 | # - 5369 for backplain gen_rpc 53 | EXPOSE 1883 8083 8084 8883 11883 18083 4370 5369 54 | 55 | COPY docker-entrypoint.sh /usr/bin/ 56 | 57 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 58 | 59 | CMD ["/opt/emqx/bin/emqx", "foreground"] 60 | -------------------------------------------------------------------------------- /5.2/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | if [[ -z "$EMQX_HOST" ]]; then 19 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 20 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 21 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 22 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 23 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 24 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 25 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 26 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 27 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 32 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 33 | else 34 | EMQX_HOST="$LOCAL_IP" 35 | fi 36 | export EMQX_HOST 37 | fi 38 | 39 | if [[ -z "$EMQX_NODE_NAME" ]]; then 40 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 41 | fi 42 | 43 | # The default rpc port discovery 'stateless' is mostly for clusters 44 | # having static node names. So it's troulbe-free for multiple emqx nodes 45 | # running on the same host. 46 | # When start emqx in docker, it's mostly one emqx node in one container 47 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 48 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /5.3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | ENV EMQX_VERSION=5.3.2 4 | ENV AMD64_SHA256=d5948d4171f57e77756dd6c9eeb745c39e391e75aad3798fce445f44f5690be0 5 | ENV ARM64_SHA256=82b056bb1c1cd1f16e9d0719150fa8ac19c499d29563738bcd6984b3c395c6ac 6 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 7 | 8 | RUN set -eu; \ 9 | apt-get update; \ 10 | apt-get install -y --no-install-recommends ca-certificates procps curl; \ 11 | arch=$(dpkg --print-architecture); \ 12 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 13 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 14 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 15 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 16 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 17 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 18 | echo "$sha256 *$pkg" | sha256sum -c; \ 19 | mkdir /opt/emqx; \ 20 | tar zxf $pkg -C /opt/emqx; \ 21 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 22 | groupadd -r -g 1000 emqx; \ 23 | useradd -r -m -u 1000 -g emqx emqx; \ 24 | chgrp -Rf emqx /opt/emqx; \ 25 | chmod -Rf g+w /opt/emqx; \ 26 | chown -Rf emqx /opt/emqx; \ 27 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 28 | rm -f $pkg; \ 29 | apt-get purge -y --auto-remove curl; \ 30 | rm -rf /var/lib/apt/lists/* 31 | 32 | WORKDIR /opt/emqx 33 | 34 | USER emqx 35 | 36 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 37 | 38 | # emqx will occupy these port: 39 | # - 1883 port for MQTT 40 | # - 8083 for WebSocket/HTTP 41 | # - 8084 for WSS/HTTPS 42 | # - 8883 port for MQTT(SSL) 43 | # - 11883 port for internal MQTT/TCP 44 | # - 18083 for dashboard and API 45 | # - 4370 default Erlang distribution port 46 | # - 5369 for backplain gen_rpc 47 | EXPOSE 1883 8083 8084 8883 11883 18083 4370 5369 48 | 49 | COPY docker-entrypoint.sh /usr/bin/ 50 | 51 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 52 | 53 | CMD ["/opt/emqx/bin/emqx", "foreground"] 54 | -------------------------------------------------------------------------------- /5.3/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | if [[ -z "$EMQX_HOST" ]]; then 19 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 20 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 21 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 22 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 23 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 24 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 25 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 26 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 27 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 32 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 33 | else 34 | EMQX_HOST="$LOCAL_IP" 35 | fi 36 | export EMQX_HOST 37 | fi 38 | 39 | if [[ -z "$EMQX_NODE_NAME" ]]; then 40 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 41 | fi 42 | 43 | # The default rpc port discovery 'stateless' is mostly for clusters 44 | # having static node names. So it's troulbe-free for multiple emqx nodes 45 | # running on the same host. 46 | # When start emqx in docker, it's mostly one emqx node in one container 47 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 48 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /5.4/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | ENV EMQX_VERSION=5.4.1 4 | ENV AMD64_SHA256=c2087651d72f17999f52d73ff22cd8f23dc5fa5db8b5a90a8bc4a1410b03affb 5 | ENV ARM64_SHA256=6c53a68ae907f7b4a3cdcd4dbee4f839b07853695ac1c039b51fd97d993073bc 6 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 7 | 8 | RUN set -eu; \ 9 | apt-get update; \ 10 | apt-get install -y --no-install-recommends ca-certificates procps curl; \ 11 | arch=$(dpkg --print-architecture); \ 12 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 13 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 14 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 15 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 16 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 17 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 18 | echo "$sha256 *$pkg" | sha256sum -c; \ 19 | mkdir /opt/emqx; \ 20 | tar zxf $pkg -C /opt/emqx; \ 21 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 22 | groupadd -r -g 1000 emqx; \ 23 | useradd -r -m -u 1000 -g emqx emqx; \ 24 | chgrp -Rf emqx /opt/emqx; \ 25 | chmod -Rf g+w /opt/emqx; \ 26 | chown -Rf emqx /opt/emqx; \ 27 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 28 | rm -f $pkg; \ 29 | apt-get purge -y --auto-remove curl; \ 30 | rm -rf /var/lib/apt/lists/* 31 | 32 | WORKDIR /opt/emqx 33 | 34 | USER emqx 35 | 36 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 37 | 38 | # emqx will occupy these port: 39 | # - 1883 port for MQTT 40 | # - 8083 for WebSocket/HTTP 41 | # - 8084 for WSS/HTTPS 42 | # - 8883 port for MQTT(SSL) 43 | # - 18083 for dashboard and API 44 | # - 4370 default Erlang distribution port 45 | # - 5369 for backplain gen_rpc 46 | EXPOSE 1883 8083 8084 8883 18083 4370 5369 47 | 48 | COPY docker-entrypoint.sh /usr/bin/ 49 | 50 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 51 | 52 | CMD ["/opt/emqx/bin/emqx", "foreground"] 53 | -------------------------------------------------------------------------------- /5.4/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | if [[ -z "$EMQX_HOST" ]]; then 19 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 20 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 21 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 22 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 23 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 24 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 25 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 26 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 27 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 32 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 33 | else 34 | EMQX_HOST="$LOCAL_IP" 35 | fi 36 | export EMQX_HOST 37 | fi 38 | 39 | if [[ -z "$EMQX_NODE_NAME" ]]; then 40 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 41 | fi 42 | 43 | # The default rpc port discovery 'stateless' is mostly for clusters 44 | # having static node names. So it's troulbe-free for multiple emqx nodes 45 | # running on the same host. 46 | # When start emqx in docker, it's mostly one emqx node in one container 47 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 48 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /5.5/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11-slim 2 | 3 | ENV EMQX_VERSION=5.5.1 4 | ENV AMD64_SHA256=8bac2886987a632aab1c738aa3de28684b415d3b1e1f9489b458c819254673a6 5 | ENV ARM64_SHA256=8b962ad8beea50fb92dc0b93d2ab8a5064752147b70bbf46fd221bc4cc29c32d 6 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 7 | 8 | RUN set -eu; \ 9 | apt-get update; \ 10 | apt-get install -y --no-install-recommends ca-certificates procps curl; \ 11 | arch=$(dpkg --print-architecture); \ 12 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 13 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 14 | ID="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/\"//g')"; \ 15 | VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/\"//g')"; \ 16 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 17 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 18 | echo "$sha256 *$pkg" | sha256sum -c; \ 19 | mkdir /opt/emqx; \ 20 | tar zxf $pkg -C /opt/emqx; \ 21 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 22 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 23 | groupadd -r -g 1000 emqx; \ 24 | useradd -r -m -u 1000 -g emqx emqx; \ 25 | mkdir -p /opt/emqx/log /opt/emqx/data /opt/emqx/plugins; \ 26 | chown -R emqx:emqx /opt/emqx/log /opt/emqx/data /opt/emqx/plugins; \ 27 | rm -f $pkg; \ 28 | apt-get purge -y --auto-remove curl; \ 29 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 30 | 31 | WORKDIR /opt/emqx 32 | 33 | USER emqx 34 | 35 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 36 | 37 | # emqx will occupy these port: 38 | # - 1883 port for MQTT 39 | # - 8083 for WebSocket/HTTP 40 | # - 8084 for WSS/HTTPS 41 | # - 8883 port for MQTT(SSL) 42 | # - 18083 for dashboard and API 43 | # - 4370 default Erlang distribution port 44 | # - 5369 for backplain gen_rpc 45 | EXPOSE 1883 8083 8084 8883 18083 4370 5369 46 | 47 | COPY docker-entrypoint.sh /usr/bin/ 48 | 49 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 50 | 51 | CMD ["/opt/emqx/bin/emqx", "foreground"] 52 | -------------------------------------------------------------------------------- /5.5/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | ## EMQX_NODE_NAME or EMQX_NODE__NAME to indicate the full node name to be used by EMQX 19 | ## If both are set EMQX_NODE_NAME takes higher precedence than EMQX_NODE__NAME 20 | if [[ -z "${EMQX_NODE_NAME:-}" ]] && [[ -z "${EMQX_NODE__NAME:-}" ]]; then 21 | # No node name is provide from environment variables 22 | # try to resolve from other settings 23 | if [[ -z "$EMQX_HOST" ]]; then 24 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 25 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 26 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 27 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 32 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 33 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 34 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 35 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 36 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 37 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 38 | else 39 | EMQX_HOST="$LOCAL_IP" 40 | fi 41 | export EMQX_HOST 42 | fi 43 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 44 | fi 45 | 46 | # The default rpc port discovery 'stateless' is mostly for clusters 47 | # having static node names. So it's troulbe-free for multiple emqx nodes 48 | # running on the same host. 49 | # When start emqx in docker, it's mostly one emqx node in one container 50 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 51 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 52 | 53 | exec "$@" 54 | -------------------------------------------------------------------------------- /5.6/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:12-slim 2 | 3 | ENV EMQX_VERSION=5.6.1 4 | ENV AMD64_SHA256=a5be37660bfe6130bc159b934ed98ffcb9bef5519765491b4ed38d08ba304538 5 | ENV ARM64_SHA256=3f7f9b10d313f760af43e0a54cba2af4eb23ad3864b439196cb8b2903baf5651 6 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 7 | 8 | RUN set -eu; \ 9 | apt-get update; \ 10 | apt-get install -y --no-install-recommends ca-certificates procps curl; \ 11 | arch=$(dpkg --print-architecture); \ 12 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 13 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 14 | . /etc/os-release; \ 15 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 16 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 17 | echo "$sha256 *$pkg" | sha256sum -c; \ 18 | mkdir /opt/emqx; \ 19 | tar zxf $pkg -C /opt/emqx; \ 20 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 21 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 22 | groupadd -r -g 1000 emqx; \ 23 | useradd -r -m -u 1000 -g emqx emqx; \ 24 | chown -R emqx:emqx /opt/emqx; \ 25 | rm -f $pkg; \ 26 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 27 | 28 | WORKDIR /opt/emqx 29 | 30 | USER emqx 31 | 32 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 33 | 34 | # emqx will occupy these port: 35 | # - 1883 port for MQTT 36 | # - 8083 for WebSocket/HTTP 37 | # - 8084 for WSS/HTTPS 38 | # - 8883 port for MQTT(SSL) 39 | # - 18083 for dashboard and API 40 | # - 4370 default Erlang distribution port 41 | # - 5369 for backplain gen_rpc 42 | EXPOSE 1883 8083 8084 8883 18083 4370 5369 43 | 44 | COPY docker-entrypoint.sh /usr/bin/ 45 | 46 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 47 | 48 | CMD ["/opt/emqx/bin/emqx", "foreground"] 49 | -------------------------------------------------------------------------------- /5.6/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | ## EMQX_NODE_NAME or EMQX_NODE__NAME to indicate the full node name to be used by EMQX 19 | ## If both are set EMQX_NODE_NAME takes higher precedence than EMQX_NODE__NAME 20 | if [[ -z "${EMQX_NODE_NAME:-}" ]] && [[ -z "${EMQX_NODE__NAME:-}" ]]; then 21 | # No node name is provide from environment variables 22 | # try to resolve from other settings 23 | if [[ -z "$EMQX_HOST" ]]; then 24 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 25 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 26 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 27 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 32 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 33 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 34 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 35 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 36 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 37 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 38 | else 39 | EMQX_HOST="$LOCAL_IP" 40 | fi 41 | export EMQX_HOST 42 | fi 43 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 44 | fi 45 | 46 | # The default rpc port discovery 'stateless' is mostly for clusters 47 | # having static node names. So it's troulbe-free for multiple emqx nodes 48 | # running on the same host. 49 | # When start emqx in docker, it's mostly one emqx node in one container 50 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 51 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 52 | 53 | exec "$@" 54 | -------------------------------------------------------------------------------- /5.7/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:12-slim 2 | 3 | ENV EMQX_VERSION=5.7.2 4 | ENV AMD64_SHA256=1f32fb90ca5e7b3d2a447a82d4e3d22397e25bc97800bdcb1deb6d2a685c1c35 5 | ENV ARM64_SHA256=6bfa8c774a9f7b2957a6519e428c96d58ac4f748ddd0b40dd2b429d270fcf9c0 6 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 7 | 8 | RUN set -eu; \ 9 | apt-get update; \ 10 | apt-get install -y --no-install-recommends ca-certificates procps curl; \ 11 | arch=$(dpkg --print-architecture); \ 12 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 13 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 14 | . /etc/os-release; \ 15 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 16 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 17 | echo "$sha256 *$pkg" | sha256sum -c; \ 18 | mkdir /opt/emqx; \ 19 | tar zxf $pkg -C /opt/emqx; \ 20 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 21 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 22 | groupadd -r -g 1000 emqx; \ 23 | useradd -r -m -u 1000 -g emqx emqx; \ 24 | chown -R emqx:emqx /opt/emqx; \ 25 | rm -f $pkg; \ 26 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 27 | 28 | WORKDIR /opt/emqx 29 | 30 | USER emqx 31 | 32 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 33 | 34 | # emqx will occupy these port: 35 | # - 1883 port for MQTT 36 | # - 8083 for WebSocket/HTTP 37 | # - 8084 for WSS/HTTPS 38 | # - 8883 port for MQTT(SSL) 39 | # - 18083 for dashboard and API 40 | # - 4370 default Erlang distribution port 41 | # - 5369 for backplain gen_rpc 42 | EXPOSE 1883 8083 8084 8883 18083 4370 5369 43 | 44 | COPY docker-entrypoint.sh /usr/bin/ 45 | 46 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 47 | 48 | CMD ["/opt/emqx/bin/emqx", "foreground"] 49 | -------------------------------------------------------------------------------- /5.7/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | ## EMQX_NODE_NAME or EMQX_NODE__NAME to indicate the full node name to be used by EMQX 19 | ## If both are set EMQX_NODE_NAME takes higher precedence than EMQX_NODE__NAME 20 | if [[ -z "${EMQX_NODE_NAME:-}" ]] && [[ -z "${EMQX_NODE__NAME:-}" ]]; then 21 | # No node name is provide from environment variables 22 | # try to resolve from other settings 23 | if [[ -z "$EMQX_HOST" ]]; then 24 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 25 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 26 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 27 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 32 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 33 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 34 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 35 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 36 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 37 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 38 | else 39 | EMQX_HOST="$LOCAL_IP" 40 | fi 41 | export EMQX_HOST 42 | fi 43 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 44 | fi 45 | 46 | # The default rpc port discovery 'stateless' is mostly for clusters 47 | # having static node names. So it's troulbe-free for multiple emqx nodes 48 | # running on the same host. 49 | # When start emqx in docker, it's mostly one emqx node in one container 50 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 51 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 52 | 53 | exec "$@" 54 | -------------------------------------------------------------------------------- /5.8/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:12-slim 2 | 3 | ENV EMQX_VERSION=5.8.6 4 | ENV AMD64_SHA256=430f69c24c0d659a9ce2e902d018c6dd20565519925e0cc893980d824b0a952e 5 | ENV ARM64_SHA256=dcabedb9d3888e0fb6e8138da6ae3d8ef1afce1f85e4580f26f19d65115ed5c3 6 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 7 | 8 | RUN set -eu; \ 9 | apt-get update; \ 10 | apt-get install -y --no-install-recommends ca-certificates procps curl; \ 11 | arch=$(dpkg --print-architecture); \ 12 | if [ ${arch} = "amd64" ]; then sha256="$AMD64_SHA256"; fi; \ 13 | if [ ${arch} = "arm64" ]; then sha256="$ARM64_SHA256"; fi; \ 14 | . /etc/os-release; \ 15 | pkg="emqx-${EMQX_VERSION}-${ID}${VERSION_ID}-${arch}.tar.gz"; \ 16 | curl -f -O -L https://www.emqx.com/en/downloads/broker/v${EMQX_VERSION}/${pkg}; \ 17 | echo "$sha256 *$pkg" | sha256sum -c; \ 18 | mkdir /opt/emqx; \ 19 | tar zxf $pkg -C /opt/emqx; \ 20 | find /opt/emqx -name 'swagger*.js.map' -exec rm {} +; \ 21 | ln -s /opt/emqx/bin/* /usr/local/bin/; \ 22 | groupadd -r -g 1000 emqx; \ 23 | useradd -r -m -u 1000 -g emqx emqx; \ 24 | chown -R emqx:emqx /opt/emqx; \ 25 | rm -f $pkg; \ 26 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 27 | 28 | WORKDIR /opt/emqx 29 | 30 | USER emqx 31 | 32 | VOLUME ["/opt/emqx/log", "/opt/emqx/data"] 33 | 34 | # emqx will occupy these port: 35 | # - 1883 port for MQTT 36 | # - 8083 for WebSocket/HTTP 37 | # - 8084 for WSS/HTTPS 38 | # - 8883 port for MQTT(SSL) 39 | # - 18083 for dashboard and API 40 | # - 4370 default Erlang distribution port 41 | # - 5369 for backplain gen_rpc 42 | EXPOSE 1883 8083 8084 8883 18083 4370 5369 43 | 44 | COPY docker-entrypoint.sh /usr/bin/ 45 | 46 | ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] 47 | 48 | CMD ["/opt/emqx/bin/emqx", "foreground"] 49 | -------------------------------------------------------------------------------- /5.8/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Shell setting 4 | if [[ -n "$DEBUG" ]]; then 5 | set -ex 6 | else 7 | set -e 8 | fi 9 | 10 | shopt -s nullglob 11 | 12 | ## Local IP address setting 13 | 14 | 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) 15 | 16 | export EMQX_NAME="${EMQX_NAME:-emqx}" 17 | 18 | ## EMQX_NODE_NAME or EMQX_NODE__NAME to indicate the full node name to be used by EMQX 19 | ## If both are set EMQX_NODE_NAME takes higher precedence than EMQX_NODE__NAME 20 | if [[ -z "${EMQX_NODE_NAME:-}" ]] && [[ -z "${EMQX_NODE__NAME:-}" ]]; then 21 | # No node name is provide from environment variables 22 | # try to resolve from other settings 23 | if [[ -z "$EMQX_HOST" ]]; then 24 | if [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "dns" ]] && \ 25 | [[ "$EMQX_CLUSTER__DNS__RECORD_TYPE" == "srv" ]] && \ 26 | grep -q "$(hostname).$EMQX_CLUSTER__DNS__NAME" /etc/hosts; then 27 | EMQX_HOST="$(hostname).$EMQX_CLUSTER__DNS__NAME" 28 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 29 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && \ 30 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 31 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"} 32 | EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX" 33 | elif [[ "$EMQX_CLUSTER__DISCOVERY_STRATEGY" == "k8s" ]] && \ 34 | [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && \ 35 | [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then 36 | EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'} 37 | EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX") 38 | else 39 | EMQX_HOST="$LOCAL_IP" 40 | fi 41 | export EMQX_HOST 42 | fi 43 | export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST" 44 | fi 45 | 46 | # The default rpc port discovery 'stateless' is mostly for clusters 47 | # having static node names. So it's troulbe-free for multiple emqx nodes 48 | # running on the same host. 49 | # When start emqx in docker, it's mostly one emqx node in one container 50 | # i.e. use port 5369 (or per tcp_server_port | ssl_server_port config) for gen_rpc 51 | export EMQX_RPC__PORT_DISCOVERY="${EMQX_RPC__PORT_DISCOVERY:-manual}" 52 | 53 | exec "$@" 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EMQX 2 | 3 | ## Quick reference 4 | 5 | + **Where to get help**: 6 | 7 | or 8 | 9 | + **Where to file issues:** 10 | 11 | 12 | 13 | + **Supported architectures** 14 | 15 | `amd64`, `arm64v8` 16 | 17 | + **Supported Docker versions**: 18 | 19 | [the latest release](https://github.com/docker/docker-ce/releases/latest) 20 | 21 | ## What is EMQX 22 | 23 | [EMQX](https://emqx.io/) is the world's most scalable open-source MQTT broker with a high performance that connects 100M+ IoT devices in 1 cluster, while maintaining 1M message per second throughput and sub-millisecond latency. 24 | 25 | EMQX supports multiple open standard protocols like MQTT, HTTP, QUIC, and WebSocket. It's 100% compliant with MQTT 5.0 and 3.x standard, and secures bi-directional communication with MQTT over TLS/SSL and various authentication mechanisms. 26 | 27 | With the built-in powerful SQL-based rules engine, EMQX can extract, filter, enrich and transform IoT data in real-time. In addition, it ensures high availability and horizontal scalability with a masterless distributed architecture, and provides ops-friendly user experience and great observability. 28 | 29 | EMQX boasts more than 20K+ enterprise users across 50+ countries and regions, connecting 100M+ IoT devices worldwide, and is trusted by over 400 customers in mission-critical scenarios of IoT, IIoT, connected vehicles, and more, including over 70 Fortune 500 companies like HPE, VMware, Verifone, SAIC Volkswagen, and Ericsson. 30 | 31 | ## How to use this image 32 | 33 | ### Run EMQX 34 | 35 | Execute some command under this docker image 36 | 37 | ```console 38 | $ docker run -d --name emqx emqx/emqx:${tag} 39 | ``` 40 | 41 | For example 42 | 43 | ```console 44 | $ docker run -d --name emqx -p 18083:18083 -p 1883:1883 emqx/emqx:latest 45 | ``` 46 | 47 | The EMQX broker runs as Linux user `emqx` in the docker container. 48 | 49 | ### Configuration 50 | 51 | All EMQX Configuration in [`etc/emqx.conf`](https://github.com/emqx/emqx/blob/master/apps/emqx/etc/emqx.conf) can be configured via environment variables. 52 | 53 | By default, the environment variables with `EMQX_` prefix are mapped to key-value pairs in configuration files. 54 | 55 | You can change the prefix by overriding `HOCON_ENV_OVERRIDE_PREFIX`. 56 | 57 | Example: 58 | 59 | ```bash 60 | EMQX_LISTENERS__SSL__DEFAULT__ACCEPTORS <--> listeners.ssl.default.acceptors 61 | EMQX_ZONES__DEFAULT__MQTT__MAX_PACKET_SIZE <--> zones.default.mqtt.max_packet_size 62 | ``` 63 | 64 | + Prefix `EMQX_` is removed 65 | + All upper case letters is replaced with lower case letters 66 | + `__` is replaced with `.` 67 | 68 | If `HOCON_ENV_OVERRIDE_PREFIX=DEV_` is set: 69 | 70 | ```bash 71 | DEV_LISTENER__SSL__EXTERNAL__ACCEPTORS <--> listener.ssl.external.acceptors 72 | DEV_MQTT__MAX_PACKET_SIZE <--> mqtt.max_packet_size 73 | DEV_LISTENERS__TCP__DEFAULT__BIND <--> listeners.tcp.default.bind 74 | ``` 75 | 76 | For example, set MQTT TCP port to 1883 77 | 78 | ```console 79 | $ docker run -d --name emqx -e DEV_LISTENERS__TCP__DEFAULT__BIND=1883 -p 18083:18083 -p 1883:1883 emqx/emqx:latest 80 | ``` 81 | 82 | Please read more about EMQX configuration in the [official documentation](https://www.emqx.io/docs/en/v5.0/admin/cfg.html). 83 | 84 | #### EMQX node name configuration 85 | 86 | | Options | Default | Mapped | Description | 87 | | ---------------------------| ------------------ | ------------------------- | ------------------------------------- | 88 | | `EMQX_NAME` | container name | none | EMQX node short name | 89 | | `EMQX_HOST` | container IP | none | EMQX node host, IP or FQDN | 90 | 91 | These environment variables are used during container startup phase only in [docker-entrypoint.sh](./docker-entrypoint.sh). 92 | 93 | If `EMQX_NAME` and `EMQX_HOST` are set, and `EMQX_NODE_NAME` is not set, `EMQX_NODE_NAME=$EMQX_NAME@$EMQX_HOST`. 94 | Otherwise `EMQX_NODE_NAME` is taken verbatim. 95 | 96 | ### Cluster 97 | 98 | EMQX supports a variety of clustering methods, see our [documentation](https://www.emqx.io/docs/en/latest/deploy/cluster/intro.html) for details. 99 | 100 | Let's create a static node list cluster from docker-compose. 101 | 102 | + Create `docker-compose.yaml`: 103 | 104 | ```yaml 105 | version: '3' 106 | 107 | services: 108 | emqx1: 109 | image: emqx/emqx:latest 110 | environment: 111 | - "EMQX_NAME=emqx" 112 | - "EMQX_HOST=node1.emqx.io" 113 | - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static" 114 | - "EMQX_CLUSTER__STATIC__SEEDS=[emqx@node1.emqx.io, emqx@node2.emqx.io]" 115 | networks: 116 | emqx-bridge: 117 | aliases: 118 | - node1.emqx.io 119 | 120 | emqx2: 121 | image: emqx/emqx:latest 122 | environment: 123 | - "EMQX_NAME=emqx" 124 | - "EMQX_HOST=node2.emqx.io" 125 | - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static" 126 | - "EMQX_CLUSTER__STATIC__SEEDS=[emqx@node1.emqx.io, emqx@node2.emqx.io]" 127 | networks: 128 | emqx-bridge: 129 | aliases: 130 | - node2.emqx.io 131 | 132 | networks: 133 | emqx-bridge: 134 | driver: bridge 135 | ``` 136 | 137 | + Start the docker-compose cluster 138 | 139 | ```bash 140 | docker-compose -p my_emqx up -d 141 | ``` 142 | 143 | + View cluster 144 | 145 | ```bash 146 | $ docker exec -it my_emqx_emqx1_1 sh -c "emqx_ctl cluster status" 147 | Cluster status: #{running_nodes => ['emqx@node1.emqx.io','emqx@node2.emqx.io'], 148 | stopped_nodes => []} 149 | ``` 150 | 151 | ### Persistence 152 | 153 | If you want to persist the EMQX docker container, you need to keep the following directories: 154 | 155 | + `/opt/emqx/data` 156 | + `/opt/emqx/etc` 157 | + `/opt/emqx/log` 158 | 159 | Since data in these folders are partially stored under the `/opt/emqx/data/mnesia/${node_name}`, the user also needs to reuse the same node name to see the previous state. In detail, one needs to specify the two environment variables: `EMQX_NAME` and `EMQX_HOST`, `EMQX_HOST` set as `127.0.0.1` or network alias would be useful. 160 | 161 | In if you use docker-compose, the configuration would look something like this: 162 | 163 | ```YAML 164 | volumes: 165 | vol-emqx-data: 166 | name: foo-emqx-data 167 | vol-emqx-etc: 168 | name: foo-emqx-etc 169 | vol-emqx-log: 170 | name: foo-emqx-log 171 | 172 | services: 173 | emqx: 174 | image: emqx/emqx:latest 175 | restart: always 176 | environment: 177 | EMQX_NAME: foo_emqx 178 | EMQX_HOST: 127.0.0.1 179 | volumes: 180 | - vol-emqx-data:/opt/emqx/data 181 | - vol-emqx-etc:/opt/emqx/etc 182 | - vol-emqx-log:/opt/emqx/log 183 | ``` 184 | 185 | Note that `/opt/emqx/etc` contains some essential configuration files. If you want to mount a host directory in the container to persist configuration overrides, you will need to bootstrap it with [default configuration files](https://github.com/emqx/emqx/tree/master/apps/emqx/etc). 186 | 187 | ### Kernel Tuning 188 | 189 | Under Linux host machine, the easiest way is [Tuning guide](https://www.emqx.io/docs/en/latest/deploy/tune.html). 190 | 191 | If you want tune Linux kernel by docker, you must ensure your docker is latest version (>=1.12). 192 | 193 | ```bash 194 | docker run -d --name emqx -p 18083:18083 -p 1883:1883 \ 195 | --sysctl fs.file-max=2097152 \ 196 | --sysctl fs.nr_open=2097152 \ 197 | --sysctl net.core.somaxconn=32768 \ 198 | --sysctl net.ipv4.tcp_max_syn_backlog=16384 \ 199 | --sysctl net.core.netdev_max_backlog=16384 \ 200 | --sysctl net.ipv4.ip_local_port_range=1000 65535 \ 201 | --sysctl net.core.rmem_default=262144 \ 202 | --sysctl net.core.wmem_default=262144 \ 203 | --sysctl net.core.rmem_max=16777216 \ 204 | --sysctl net.core.wmem_max=16777216 \ 205 | --sysctl net.core.optmem_max=16777216 \ 206 | --sysctl net.ipv4.tcp_rmem=1024 4096 16777216 \ 207 | --sysctl net.ipv4.tcp_wmem=1024 4096 16777216 \ 208 | --sysctl net.ipv4.tcp_max_tw_buckets=1048576 \ 209 | --sysctl net.ipv4.tcp_fin_timeout=15 \ 210 | emqx/emqx:latest 211 | ``` 212 | 213 | > REMEMBER: DO NOT RUN EMQX DOCKER PRIVILEGED OR MOUNT SYSTEM PROC IN CONTAINER TO TUNE LINUX KERNEL, IT IS UNSAFE. 214 | 215 | ### Thanks 216 | 217 | + [@je-al](https://github.com/emqx/emqx-docker/issues/2) 218 | + [@RaymondMouthaan](https://github.com/emqx/emqx-docker/pull/91) 219 | + [@zhongjiewu](https://github.com/emqx/emqx/issues/3427) 220 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eou pipefail 4 | 5 | VERSION="$1" 6 | VERSION_DIR=$(echo "$VERSION" | cut -d '.' -f 1,2 -) 7 | 8 | AMD64_SHA256=$(curl -sSL https://github.com/emqx/emqx/releases/download/v${VERSION}/emqx-${VERSION}-debian12-amd64.tar.gz.sha256) 9 | ARM64_SHA256=$(curl -sSL https://github.com/emqx/emqx/releases/download/v${VERSION}/emqx-${VERSION}-debian12-arm64.tar.gz.sha256) 10 | 11 | sed -i.bak \ 12 | -e "s/EMQX_VERSION=.*/EMQX_VERSION=${VERSION}/" \ 13 | -e "s/AMD64_SHA256=.*/AMD64_SHA256=${AMD64_SHA256}/" \ 14 | -e "s/ARM64_SHA256=.*/ARM64_SHA256=${ARM64_SHA256}/" \ 15 | $VERSION_DIR/Dockerfile 16 | rm -f $VERSION_DIR/Dockerfile.bak 17 | --------------------------------------------------------------------------------