В этом уроке мы будем использовать зал для развертывания нашего приложения в Docker Swarm.
Поток
- Наш код приложения находится на GitHub
- Трубопровод запускается, когда коммит выдвигается в главную ветку
- Трубопровод автоматически развернут в стационарной среде
- Трубопровод требует ручного триггера для развертывания для Prod
- Примечание: постановка и протокол на одном и том же роя для демонстрации
Код для этого урока доступен на моем Репозиторий GitHub
Структура приложения
Структура приложения для нашего кода выглядит следующим образом:
Прохождение трубопровода
Наш ci/pipeline.yml
resources: - name: main-repo type: git source: uri: git@github.com:ruanbekker/concourse-swarm-app-demo.git branch: master private_key: ((github_private_key)) - name: main-repo-staging type: git source: uri: git@github.com:ruanbekker/concourse-swarm-app-demo.git branch: master private_key: ((github_private_key)) paths: - config/staging/* - name: main-repo-prod type: git source: uri: git@github.com:ruanbekker/concourse-swarm-app-demo.git branch: master private_key: ((github_private_key)) paths: - config/prod/* - name: slack-alert type: slack-notification source: url: ((slack_notification_url)) - name: version-staging type: semver source: driver: git uri: git@github.com:ruanbekker/concourse-swarm-app-demo.git private_key: ((github_private_key)) file: version-staging branch: version-staging - name: version-prod type: semver source: driver: git uri: git@github.com:ruanbekker/concourse-swarm-app-demo.git private_key: ((github_private_key)) file: version-prod branch: version-prod resource_types: - name: slack-notification type: docker-image source: repository: cfcommunity/slack-notification-resource tag: v1.3.0 jobs: - name: bump-staging-version plan: - get: main-repo-staging trigger: true - get: version-staging - put: version-staging params: bump: major - name: bump-prod-version plan: - get: main-repo-prod trigger: true - get: version-prod - put: version-prod params: bump: major - name: deploy-staging plan: - get: main-repo-staging - get: main-repo - get: version-staging passed: - bump-staging-version trigger: true - task: deploy-staging params: DOCKER_SWARM_HOSTNAME: ((docker_swarm_staging_host)) DOCKER_SWARM_KEY: ((docker_swarm_key)) DOCKER_HUB_USER: ((docker_hub_user)) DOCKER_HUB_PASSWORD: ((docker_hub_password)) SERVICE_NAME: app-staging SWARM: staging ENVIRONMENT: staging AWS_ACCESS_KEY_ID: ((aws_access_key_id)) AWS_SECRET_ACCESS_KEY: ((aws_secret_access_key)) AWS_DEFAULT_REGION: ((aws_region)) config: platform: linux image_resource: type: docker-image source: repository: rbekker87/build-tools tag: latest username: ((docker_hub_user)) password: ((docker_hub_password)) inputs: - name: main-repo-staging - name: main-repo - name: version-staging run: path: /bin/sh args: - -c - | ./main-repo/ci/scripts/deploy.sh on_failure: put: slack-alert params: channel: '#system_events' username: 'concourse' icon_emoji: ':concourse:' silent: true text: | *$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME* ($BUILD_NAME) FAILED :rage: - TestApp Deploy to staging-swarm failed http://ci.example.local/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME on_success: put: slack-alert params: channel: '#system_events' username: 'concourse' icon_emoji: ':concourse:' silent: true text: | *$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME* ($BUILD_NAME) SUCCESS :aww_yeah: - TestApp Deploy to staging-swarm succeeded http://ci.example.local/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME - name: deploy-prod plan: - get: main-repo-prod - get: main-repo - get: version-prod passed: - bump-prod-version - task: deploy-prod params: DOCKER_SWARM_HOSTNAME: ((docker_swarm_prod_host)) DOCKER_SWARM_KEY: ((docker_swarm_key)) DOCKER_HUB_USER: ((docker_hub_user)) DOCKER_HUB_PASSWORD: ((docker_hub_password)) SERVICE_NAME: app-prod SWARM: prod ENVIRONMENT: production AWS_ACCESS_KEY_ID: ((aws_access_key_id)) AWS_SECRET_ACCESS_KEY: ((aws_secret_access_key)) AWS_DEFAULT_REGION: ((aws_region)) config: platform: linux image_resource: type: docker-image source: repository: rbekker87/build-tools tag: latest username: ((docker_hub_user)) password: ((docker_hub_password)) inputs: - name: main-repo-prod - name: main-repo - name: version-prod run: path: /bin/sh args: - -c - | ./main-repo/ci/scripts/deploy.sh on_failure: put: slack-alert params: channel: '#system_events' username: 'concourse' icon_emoji: ':concourse:' silent: true text: | *$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME* ($BUILD_NAME) FAILED :rage: - TestApp Deploy to prod-swarm failed http://ci.example.local/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME on_success: put: slack-alert params: channel: '#system_events' username: 'concourse' icon_emoji: ':concourse:' silent: true text: | *$BUILD_PIPELINE_NAME/$BUILD_JOB_NAME* ($BUILD_NAME) SUCCESS :aww_yeah: - TestApp Deploy to prod-swarm succeeded http://ci.example.local/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME
Наш ci/detrentys.yml
который будет хранить всю нашу секретную информацию, которая останется местной:
username: yourdockerusername password: yourdockerpassword docker_swarm_prod_host: 10.20.30.40 ...
Первый шаг нашего развертывания вызовет сценарий оболочки, который установит туннель SSH для хоста Docker, установив гнездо Docker в локальный порт TCP, а затем экспорт порт хоста Docker в туннельный порт, ci/scripts/deploy.sh
:
#!/usr/bin/env sh export DOCKER_HOST="localhost:2376" echo "${DOCKER_SWARM_KEY}" | sed -e 's/\(KEY-----\)\s/\1\n/g; s/\s\(-----END\)/\n\1/g' | sed -e '2s/\s\+/\n/g' > key.pem chmod 600 key.pem screen -S \ sshtunnel -m -d sh -c \ "ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -i ./key.pem -NL localhost:2376:/var/run/docker.sock root@$DOCKER_SWARM_HOSTNAME" sleep 5 docker login -u "${DOCKER_HUB_USER}" -p "${DOCKER_HUB_PASSWORD}" docker stack deploy --prune -c ./main-repo/ci/docker/docker-compose.${ENVIRONMENT}.yml $SERVICE_NAME --with-registry-auth if [ $? != "0" ] then echo "deploy failure for: $SERVICE_NAME" screen -S sshtunnel -X quit exit 1 else set -x echo "deploy success for: $SERVICE_NAME" screen -S sshtunnel -X quit fi
Скрипт развертывания ссылается на файлы Docker-Compose, сначала наш ci/docker/docker-compose.staging.yml
:
version: "3.4" services: web: image: ruanbekker/web-center-name environment: - APP_ENVIRONMENT=Staging ports: - 81:5000 networks: - web_net deploy: mode: replicated replicas: 2 networks: web_net: {}
Кроме того, наша докера для производства, ci/docker/docker-compose.production.yml
:
version: "3.4" services: web: image: ruanbekker/web-center-name environment: - APP_ENVIRONMENT=Production ports: - 80:5000 networks: - web_net deploy: mode: replicated replicas: 10 networks: web_net: {}
Установите трубопровод в зале
Создайте 2 филиала в вашем репозитории GitHub для использования версий: Постановка версии
и Версия-прод
, затем войдите в заговор и сохраните цель:
$ fly -t ci login -n main -c http://
Установите конвейер, укажите конфигурацию, определение локальных переменных и назовите трубопровод:
$ fly -t ci sp -n main -c ci/pipeline.yml -p-l ci/ .yml
Вы обнаружите, что трубопровод будет выглядеть ниже и что он будет в приостановленном состоянии:
Неужели трубопровод:
$ fly -t ci up -p swarm-demo
Трубопровод должен начать автоматически из-за триггера, который установлен на True:
Развернуто автоматически к постановке, Prod — это ручный триггер:
Тестирование наше приложение
Для демонстрационных целей мы развернули постановку на порту 81 и производство на порту 80.
Проверка тестирования на http://: 81/
Производство тестирования на http://: 80/
Оригинал: «https://dev.to/ruanbekker/using-concourse-ci-to-deploy-to-docker-swarm-5g4b»