build_and_push_docker_images.yaml 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. name: Build and push docker images
  2. concurrency:
  3. group: docker-build-${{ github.event_name }}-${{ inputs.profile }}-${{ github.ref }}
  4. cancel-in-progress: true
  5. on:
  6. workflow_call:
  7. inputs:
  8. profile:
  9. required: true
  10. type: string
  11. latest:
  12. required: false
  13. type: string
  14. default: false
  15. publish:
  16. required: false
  17. type: boolean
  18. default: false
  19. secrets:
  20. DOCKER_HUB_USER:
  21. required: false
  22. DOCKER_HUB_TOKEN:
  23. required: false
  24. AWS_ACCESS_KEY_ID:
  25. required: false
  26. AWS_SECRET_ACCESS_KEY:
  27. required: false
  28. workflow_dispatch:
  29. inputs:
  30. ref:
  31. required: false
  32. profile:
  33. required: false
  34. type: string
  35. default: 'emqx'
  36. latest:
  37. required: false
  38. type: boolean
  39. default: false
  40. publish:
  41. required: false
  42. type: boolean
  43. default: false
  44. permissions:
  45. contents: read
  46. jobs:
  47. build:
  48. runs-on: ${{ github.repository_owner == 'emqx' && fromJSON(format('["self-hosted","ephemeral","linux","{0}"]', matrix.arch)) || 'ubuntu-22.04' }}
  49. outputs:
  50. PKG_VSN: ${{ steps.build.outputs.PKG_VSN }}
  51. strategy:
  52. fail-fast: false
  53. matrix:
  54. profile:
  55. - ${{ inputs.profile }}
  56. - ${{ inputs.profile }}-elixir
  57. arch:
  58. - x64
  59. - arm64
  60. steps:
  61. - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
  62. with:
  63. ref: ${{ github.event.inputs.ref }}
  64. - name: build release tarball
  65. id: build
  66. env:
  67. BUILDER_SYSTEM: force_docker
  68. run: |
  69. source ./env.sh
  70. ./scripts/buildx.sh --profile ${{ matrix.profile }} --pkgtype tgz --builder "$EMQX_DOCKER_BUILD_FROM"
  71. PKG_VSN=$(docker run --rm -v $(pwd):$(pwd) -w $(pwd) -u $(id -u) "$EMQX_DOCKER_BUILD_FROM" ./pkg-vsn.sh "${{ matrix.profile }}")
  72. echo "PKG_VSN=$PKG_VSN" >> "$GITHUB_OUTPUT"
  73. - uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5
  74. with:
  75. name: "${{ matrix.profile }}-${{ matrix.arch == 'x64' && 'amd64' || 'arm64' }}.tar.gz"
  76. path: "_packages/emqx*/emqx-*.tar.gz"
  77. retention-days: 7
  78. overwrite: true
  79. if-no-files-found: error
  80. docker:
  81. runs-on: ${{ endsWith(github.repository, '/emqx') && 'ubuntu-22.04' || fromJSON('["self-hosted","ephemeral","linux","x64"]') }}
  82. needs:
  83. - build
  84. defaults:
  85. run:
  86. shell: bash
  87. strategy:
  88. fail-fast: false
  89. matrix:
  90. profile:
  91. - ["${{ inputs.profile }}", "${{ inputs.profile == 'emqx' && 'docker.io,public.ecr.aws' || 'docker.io' }}"]
  92. - ["${{ inputs.profile }}-elixir", "${{ inputs.profile == 'emqx' && 'docker.io,public.ecr.aws' || 'docker.io' }}"]
  93. env:
  94. PROFILE: ${{ matrix.profile[0] }}
  95. DOCKER_REGISTRY: ${{ matrix.profile[1] }}
  96. DOCKER_ORG: ${{ github.repository_owner }}
  97. DOCKER_LATEST: ${{ inputs.latest }}
  98. PKG_VSN: ${{ needs.build.outputs.PKG_VSN }}
  99. EMQX_SOURCE_TYPE: tgz
  100. steps:
  101. - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
  102. with:
  103. ref: ${{ github.event.inputs.ref }}
  104. - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
  105. with:
  106. pattern: "${{ matrix.profile[0] }}-*.tar.gz"
  107. path: _packages
  108. merge-multiple: true
  109. - name: Move artifacts to root directory
  110. env:
  111. PROFILE: ${{ inputs.profile }}
  112. run: |
  113. ls -lR _packages/$PROFILE
  114. mv _packages/$PROFILE/*.tar.gz ./
  115. - name: Enable containerd image store on Docker Engine
  116. run: |
  117. echo "$(sudo cat /etc/docker/daemon.json | jq '. += {"features": {"containerd-snapshotter": true}}')" > daemon.json
  118. sudo mv daemon.json /etc/docker/daemon.json
  119. sudo systemctl restart docker
  120. - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
  121. - uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
  122. - name: Login to hub.docker.com
  123. uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
  124. if: inputs.publish && contains(matrix.profile[1], 'docker.io')
  125. with:
  126. username: ${{ secrets.DOCKER_HUB_USER }}
  127. password: ${{ secrets.DOCKER_HUB_TOKEN }}
  128. - name: Login to AWS ECR
  129. uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
  130. if: inputs.publish && contains(matrix.profile[1], 'public.ecr.aws')
  131. with:
  132. registry: public.ecr.aws
  133. username: ${{ secrets.AWS_ACCESS_KEY_ID }}
  134. password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  135. ecr: true
  136. - name: Build docker image
  137. env:
  138. DOCKER_PUSH: false
  139. DOCKER_BUILD_NOCACHE: true
  140. run: |
  141. ./build ${PROFILE} docker
  142. echo "Built tags:"
  143. echo "==========="
  144. cat .emqx_docker_image_tags
  145. echo "==========="
  146. echo "_EMQX_DOCKER_IMAGE_TAG=$(head -n 1 .emqx_docker_image_tags)" >> $GITHUB_ENV
  147. - name: Verify that size of docker image is less than 300 MB
  148. run: |
  149. docker image inspect $_EMQX_DOCKER_IMAGE_TAG --format='{{.Size}}' | xargs -I {} test {} -lt 300000000
  150. - name: smoke test
  151. timeout-minutes: 1
  152. run: |
  153. for tag in $(cat .emqx_docker_image_tags); do
  154. CID=$(docker run -d -p 18083:18083 $tag)
  155. HTTP_PORT=$(docker inspect --format='{{(index (index .NetworkSettings.Ports "18083/tcp") 0).HostPort}}' $CID)
  156. ./scripts/test/emqx-smoke-test.sh localhost $HTTP_PORT
  157. docker rm -f $CID
  158. done
  159. - name: dashboard tests
  160. working-directory: ./scripts/ui-tests
  161. timeout-minutes: 5
  162. run: |
  163. set -eu
  164. docker compose up --abort-on-container-exit --exit-code-from selenium
  165. docker compose rm -fsv
  166. - name: test node_dump
  167. run: |
  168. CID=$(docker run -d -P $_EMQX_DOCKER_IMAGE_TAG)
  169. docker exec -t -u root -w /root $CID bash -c 'apt-get -y update && apt-get -y install net-tools'
  170. docker exec -t -u root $CID node_dump
  171. docker rm -f $CID
  172. - name: export docker image
  173. run: |
  174. docker save "${_EMQX_DOCKER_IMAGE_TAG}" | gzip > $PROFILE-docker-$PKG_VSN.tar.gz
  175. - uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5
  176. with:
  177. name: "${{ env.PROFILE }}-docker"
  178. path: "${{ env.PROFILE }}-docker-${{ env.PKG_VSN }}.tar.gz"
  179. retention-days: 7
  180. - name: Publish docker image
  181. if: inputs.publish || github.repository_owner != 'emqx'
  182. env:
  183. DOCKER_PUSH: true
  184. DOCKER_BUILD_NOCACHE: false
  185. DOCKER_PLATFORMS: linux/amd64,linux/arm64
  186. DOCKER_LOAD: false
  187. run: |
  188. ./build ${PROFILE} docker
  189. - name: Build and publish docker image with Snowflake ODBC driver
  190. if: (inputs.publish || github.repository_owner != 'emqx') && matrix.profile[0] == 'emqx-enterprise'
  191. env:
  192. DOCKER_PUSH: true
  193. DOCKER_BUILD_NOCACHE: false
  194. DOCKER_PLATFORMS: linux/amd64,linux/arm64
  195. DOCKER_LOAD: false
  196. EMQX_DOCKERFILE: deploy/docker/Dockerfile.sfodbc
  197. run: |
  198. export BUILD_FROM="${_EMQX_DOCKER_IMAGE_TAG}"
  199. export EMQX_IMAGE_TAG="${_EMQX_DOCKER_IMAGE_TAG##docker.io/}-sf"
  200. ./build ${PROFILE} docker