review-app.yml 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. .review_app_scripts:
  2. assign_port:
  3. # Assign an unprivileged port for the web server based on MR ID.
  4. - |
  5. APP_PORT=$(( $CI_MERGE_REQUEST_ID % 64000 + 1024 ))
  6. echo "Assigned port number $APP_PORT."
  7. build_docker_compose_files:
  8. - !reference [.review_app_scripts, assign_port]
  9. - |
  10. echo "Creating docker compose files…"
  11. curl https://raw.githubusercontent.com/zammad/zammad-docker-compose/master/docker-compose.yml > docker-compose.yml
  12. curl https://raw.githubusercontent.com/zammad/zammad-docker-compose/master/.env > .env
  13. cat - <<YML_FILE > docker-compose.review-app.yml
  14. ---
  15. version: '3'
  16. services:
  17. zammad-nginx:
  18. ports:
  19. - "127.0.0.1:${APP_PORT}:8080"
  20. zammad-backup:
  21. profiles:
  22. - do-not-start
  23. YML_FILE
  24. cat - <<ENV_FILE >> .env
  25. IMAGE_REPO=${CI_REGISTRY}/${CI_PROJECT_PATH}
  26. VERSION=${APP_NAME}
  27. ENV_FILE
  28. # cat docker-compose* .env
  29. # Check if containers were previously created, so that this is an update deployment
  30. - |
  31. APP_DEPLOYED_BEFORE=$(${DOCKER_COMPOSE_COMMAND} ps --all --quiet)
  32. if [ "$APP_DEPLOYED_BEFORE" ]
  33. then
  34. echo "This review app was previously deployed."
  35. else
  36. echo "This review app was not deployed yet."
  37. fi
  38. build_and_push_docker_image:
  39. # Build/update docker image and publish it to the GitLab container registry.
  40. - |
  41. echo "Build docker image…"
  42. docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  43. echo -e "\\e[0Ksection_start:`date +%s`:docker_build[collapsed=true]\\r\\e[0Kdocker build"
  44. if [ ! "${SKIP_DOCKER_BUILD}" ]
  45. then
  46. docker build --pull --no-cache -t $IMAGE_URL .
  47. docker push $IMAGE_URL
  48. fi
  49. echo -e "\\e[0Ksection_end:`date +%s`:docker_build\\r\\e[0K"
  50. create_auto_wizard_json:
  51. - |
  52. cat - <<JSON_FILE > tmp/auto_wizard.json
  53. {
  54. "Token": "${CI_JOB_TOKEN}",
  55. "Users": [
  56. {
  57. "login": "admin@example.com",
  58. "firstname": "Test Admin",
  59. "lastname": "Agent",
  60. "email": "admin@example.com",
  61. "password": "${CI_MERGE_REQUEST_ID}"
  62. },
  63. {
  64. "login": "agent1@example.com",
  65. "firstname": "Agent 1",
  66. "lastname": "Test",
  67. "email": "agent1@example.com",
  68. "password": "${CI_MERGE_REQUEST_ID}",
  69. "roles": ["Agent"]
  70. }
  71. ],
  72. "Groups": [
  73. {
  74. "name": "some group1",
  75. "users": ["admin@example.com", "agent1@example.com"]
  76. },
  77. {
  78. "name": "Users",
  79. "users": ["admin@example.com", "agent1@example.com"],
  80. "signature": "default",
  81. "email_address_id": 1
  82. }
  83. ],
  84. "Channels": [
  85. {
  86. "id": 1,
  87. "area": "Email::Account",
  88. "group": "Users",
  89. "options": {
  90. "inbound": {
  91. "adapter": "imap",
  92. "options": {
  93. "host": "mx1.example.com",
  94. "user": "not_existing",
  95. "password": "not_existing",
  96. "ssl": true
  97. }
  98. },
  99. "outbound": {
  100. "adapter": "sendmail"
  101. }
  102. }
  103. }
  104. ],
  105. "EmailAddresses": [
  106. {
  107. "id": 1,
  108. "channel_id": 1,
  109. "realname": "Zammad Helpdesk",
  110. "email": "zammad@localhost"
  111. }
  112. ],
  113. "Settings": [
  114. {
  115. "name": "product_name",
  116. "value": "Zammad Review App ${APP_NAME}"
  117. },
  118. {
  119. "name": "fqdn",
  120. "value": "${APP_FQDN}"
  121. },
  122. {
  123. "name": "developer_mode",
  124. "value": true
  125. }
  126. ],
  127. "TextModuleLocale": {
  128. "Locale": "de-de"
  129. }
  130. }
  131. JSON_FILE
  132. create_vhost_config:
  133. - |
  134. cat - <<VHOST_CONFIG > /etc/nginx/conf.d/vhost-includes/${APP_NAME}.conf
  135. server {
  136. listen 443 ssl http2;
  137. listen [::]:443 ssl http2;
  138. server_name ${APP_SLUG}.${SERVER_NAME};
  139. location / {
  140. proxy_redirect off;
  141. proxy_set_header Host \$host;
  142. proxy_set_header X-Real-IP \$remote_addr;
  143. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  144. proxy_pass http://127.0.0.1:${APP_PORT};
  145. }
  146. }
  147. VHOST_CONFIG
  148. delete_vhost_config:
  149. - rm -f /etc/nginx/conf.d/vhost-includes/${APP_NAME}.conf
  150. reload_nginx:
  151. - sudo systemctl reload nginx.service
  152. .review-app:
  153. tags:
  154. - review-apps
  155. stage: pre
  156. cache: []
  157. variables:
  158. SERVER_NAME: review-apps.dc.zammad.com
  159. APP_SLUG: $CI_COMMIT_REF_SLUG
  160. APP_NAME: review-app-${APP_SLUG}
  161. APP_FQDN: ${APP_SLUG}.${SERVER_NAME}
  162. IMAGE_URL: ${CI_REGISTRY}/${CI_PROJECT_PATH}:${APP_NAME}
  163. DOCKER_COMPOSE_COMMAND: docker compose -f docker-compose.yml -f docker-compose.review-app.yml -p ${APP_NAME}
  164. environment:
  165. name: ${APP_NAME}
  166. url: https://${APP_FQDN}#getting_started/auto_wizard/${CI_JOB_TOKEN}
  167. rules:
  168. - if: $CI_MERGE_REQUEST_ID
  169. when: manual
  170. allow_failure: true
  171. - when: never
  172. before_script:
  173. - !reference [.review_app_scripts, build_docker_compose_files]
  174. after_script:
  175. - echo "Clean-up project build directory…" # shell runners don't clean-up, see https://gitlab.com/gitlab-org/gitlab/-/issues/243716
  176. - rm -rf $CI_PROJECT_DIR
  177. - echo "Perform docker clean-up…"
  178. - docker image prune -f
  179. - docker volume prune -f
  180. review-app:deploy:
  181. extends:
  182. - .review-app
  183. script:
  184. - !reference [.review_app_scripts, build_and_push_docker_image]
  185. # Spawn a new or update an existing docker compose application on the GitLab runner.
  186. # If starting did not complete, bring down the container again to free up resources.
  187. - |
  188. echo "Deploy review app…"
  189. ${DOCKER_COMPOSE_COMMAND} up -d || FAILED=true
  190. if [ $FAILED ]
  191. then
  192. ${DOCKER_COMPOSE_COMMAND} down
  193. echo "Failed to bring up container, exiting."
  194. exit 1
  195. fi
  196. # Always provide auto_wizard.json, because we don't know when it will be activated.
  197. - !reference [.review_app_scripts, create_auto_wizard_json]
  198. - docker cp tmp/auto_wizard.json ${APP_NAME}-zammad-railsserver-1:/opt/zammad
  199. - !reference [.review_app_scripts, create_vhost_config]
  200. - !reference [.review_app_scripts, reload_nginx]
  201. environment:
  202. on_stop: review-app:stop
  203. auto_stop_in: 1 month
  204. review-app:stop:
  205. extends:
  206. - .review-app
  207. variables:
  208. GIT_STRATEGY: none
  209. script:
  210. - echo "Stop review app…"
  211. - !reference [.review_app_scripts, delete_vhost_config]
  212. - !reference [.review_app_scripts, reload_nginx]
  213. - ${DOCKER_COMPOSE_COMMAND} down
  214. environment:
  215. action: stop