123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- .review_app_scripts:
- assign_port:
- # Assign an unprivileged port for the web server based on MR ID.
- - |
- APP_PORT=$(( $CI_MERGE_REQUEST_ID % 64000 + 1024 ))
- WS_PORT=$(( $APP_PORT + 1000 ))
- ASSETS_PORT=$(( $APP_PORT + 2000 ))
- echo "Assigned port number $APP_PORT."
- build_docker_compose_files:
- - !reference [.review_app_scripts, assign_port]
- - |
- echo "Creating docker compose files…"
- curl https://raw.githubusercontent.com/zammad/zammad-docker-compose/master/docker-compose.yml > docker-compose.yml
- curl https://raw.githubusercontent.com/zammad/zammad-docker-compose/master/.env > .env
- cat - <<YML_FILE > docker-compose.review-app.yml
- ---
- version: '3'
- services:
- zammad-init:
- environment:
- - MEMCACHE_SERVERS=\${MEMCACHE_SERVERS}
- - POSTGRESQL_USER=\${POSTGRES_USER}
- - POSTGRESQL_PASS=\${POSTGRES_PASS}
- - REDIS_URL=\${REDIS_URL}
- - ZAMMAD_HTTP_TYPE=https
- - ZAMMAD_FQDN=${APP_FQDN}
- zammad-railsserver:
- ports:
- - "127.0.0.1:${APP_PORT}:3000"
- zammad-websocket:
- ports:
- - "127.0.0.1:${WS_PORT}:6042"
- zammad-nginx:
- ports:
- - "127.0.0.1:${ASSETS_PORT}:8080"
- zammad-backup:
- profiles:
- - do-not-start
- YML_FILE
- cat - <<ENV_FILE >> .env
- IMAGE_REPO=${CI_REGISTRY}/${CI_PROJECT_PATH}
- VERSION=${APP_NAME}
- ENV_FILE
- # cat docker-compose* .env
- # Check if containers were previously created, so that this is an update deployment
- - |
- APP_DEPLOYED_BEFORE=$(${DOCKER_COMPOSE_COMMAND} ps --all --quiet)
- if [ "$APP_DEPLOYED_BEFORE" ]
- then
- echo "This review app was previously deployed."
- else
- echo "This review app was not deployed yet."
- fi
- build_and_push_docker_image:
- # Build/update docker image and publish it to the GitLab container registry.
- - |
- echo "Build docker image…"
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- echo -e "\\e[0Ksection_start:`date +%s`:docker_build[collapsed=true]\\r\\e[0Kdocker build"
- if [ ! "${SKIP_DOCKER_BUILD}" ]
- then
- docker build --pull --no-cache -t $IMAGE_URL .
- docker push $IMAGE_URL
- fi
- echo -e "\\e[0Ksection_end:`date +%s`:docker_build\\r\\e[0K"
- create_auto_wizard_json:
- - |
- cat - <<JSON_FILE > tmp/auto_wizard.json
- {
- "Token": "${CI_JOB_TOKEN}",
- "Users": [
- {
- "login": "admin@example.com",
- "firstname": "Test Admin",
- "lastname": "Agent",
- "email": "admin@example.com",
- "password": "${CI_MERGE_REQUEST_ID}"
- },
- {
- "login": "agent1@example.com",
- "firstname": "Agent 1",
- "lastname": "Test",
- "email": "agent1@example.com",
- "password": "${CI_MERGE_REQUEST_ID}",
- "roles": ["Agent"]
- }
- ],
- "Groups": [
- {
- "name": "some group1",
- "users": ["admin@example.com", "agent1@example.com"]
- },
- {
- "name": "Users",
- "users": ["admin@example.com", "agent1@example.com"],
- "signature": "default",
- "email_address_id": 1
- }
- ],
- "Channels": [
- {
- "id": 1,
- "area": "Email::Account",
- "group": "Users",
- "options": {
- "inbound": {
- "adapter": "imap",
- "options": {
- "host": "mx1.example.com",
- "user": "not_existing",
- "password": "not_existing",
- "ssl": true
- }
- },
- "outbound": {
- "adapter": "sendmail"
- }
- }
- }
- ],
- "EmailAddresses": [
- {
- "id": 1,
- "channel_id": 1,
- "name": "Zammad Helpdesk",
- "email": "zammad@localhost"
- }
- ],
- "Settings": [
- {
- "name": "product_name",
- "value": "Zammad Review App ${APP_NAME}"
- },
- {
- "name": "http_type",
- "value": "https"
- },
- {
- "name": "fqdn",
- "value": "${APP_FQDN}"
- },
- {
- "name": "developer_mode",
- "value": true
- }
- ],
- "TextModuleLocale": {
- "Locale": "de-de"
- }
- }
- JSON_FILE
- create_vhost_config:
- - |
- cat - <<VHOST_CONFIG > /etc/nginx/conf.d/vhost-includes/${APP_NAME}.conf
- server {
- listen 443 ssl http2;
- listen [::]:443 ssl http2;
- server_name ${APP_SLUG}.${SERVER_NAME};
- client_max_body_size 50M;
- location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png) {
- expires max;
- proxy_pass http://127.0.0.1:${ASSETS_PORT};
- }
- location / {
- proxy_set_header Host \$http_host;
- proxy_set_header CLIENT_IP \$remote_addr;
- proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto \$scheme;
- # Change this line in an SSO setup
- proxy_set_header X-Forwarded-User "";
- proxy_read_timeout 300;
- proxy_pass http://127.0.0.1:${APP_PORT};
- gzip on;
- gzip_types text/plain text/xml text/css image/svg+xml application/javascript application/x-javascript application/json application/xml;
- gzip_proxied any;
- }
- # legacy web socket server
- location /ws {
- proxy_http_version 1.1;
- proxy_set_header Upgrade \$http_upgrade;
- proxy_set_header Connection "Upgrade";
- proxy_set_header CLIENT_IP \$remote_addr;
- proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto \$scheme;
- proxy_read_timeout 86400;
- proxy_pass http://127.0.0.1:${WS_PORT};
- }
- # action cable
- location /cable {
- proxy_http_version 1.1;
- proxy_set_header Upgrade \$http_upgrade;
- proxy_set_header Connection "Upgrade";
- proxy_set_header CLIENT_IP \$remote_addr;
- proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto \$scheme;
- proxy_read_timeout 86400;
- proxy_pass http://127.0.0.1:${APP_PORT};
- }
- }
- VHOST_CONFIG
- delete_vhost_config:
- - rm -f /etc/nginx/conf.d/vhost-includes/${APP_NAME}.conf
- reload_nginx:
- - sudo systemctl reload nginx.service
- .review-app:
- tags:
- - review-apps
- stage: pre
- cache: []
- variables:
- SERVER_NAME: review-apps.dc.zammad.com
- APP_SLUG: $CI_COMMIT_REF_SLUG
- APP_NAME: review-app-${APP_SLUG}
- APP_FQDN: ${APP_SLUG}.${SERVER_NAME}
- IMAGE_URL: ${CI_REGISTRY}/${CI_PROJECT_PATH}:${APP_NAME}
- DOCKER_COMPOSE_COMMAND: docker compose -f docker-compose.yml -f docker-compose.review-app.yml -p ${APP_NAME}
- environment:
- name: ${APP_NAME}
- url: https://${APP_FQDN}#getting_started/auto_wizard/${CI_JOB_TOKEN}
- rules:
- - if: $CI_MERGE_REQUEST_ID
- when: manual
- allow_failure: true
- - when: never
- before_script:
- - !reference [.review_app_scripts, build_docker_compose_files]
- after_script:
- - echo "Clean-up project build directory…" # shell runners don't clean-up, see https://gitlab.com/gitlab-org/gitlab/-/issues/243716
- - rm -rf $CI_PROJECT_DIR
- - echo "Perform docker clean-up…"
- - docker image prune --all --force
- - docker volume prune --all --force
- - docker network prune --force
- review-app:deploy:
- extends:
- - .review-app
- script:
- - !reference [.review_app_scripts, build_and_push_docker_image]
- # Spawn a new or update an existing docker compose application on the GitLab runner.
- # If starting did not complete, bring down the container again to free up resources.
- - |
- echo "Deploy review app…"
- ${DOCKER_COMPOSE_COMMAND} up --force-recreate --detach || FAILED=true
- if [ $FAILED ]
- then
- ${DOCKER_COMPOSE_COMMAND} down
- echo "Failed to bring up container, exiting."
- exit 1
- fi
- # Always provide auto_wizard.json, because we don't know when it will be activated.
- - !reference [.review_app_scripts, create_auto_wizard_json]
- - docker cp tmp/auto_wizard.json ${APP_NAME}-zammad-railsserver-1:/opt/zammad
- - !reference [.review_app_scripts, create_vhost_config]
- - !reference [.review_app_scripts, reload_nginx]
- environment:
- on_stop: review-app:stop
- auto_stop_in: 1 month
- review-app:stop:
- extends:
- - .review-app
- variables:
- GIT_STRATEGY: none
- script:
- - echo "Stop review app…"
- - !reference [.review_app_scripts, delete_vhost_config]
- - !reference [.review_app_scripts, reload_nginx]
- - ${DOCKER_COMPOSE_COMMAND} down
- environment:
- action: stop
|