Что такое Concourse CI?

Concourse — это открытая система непрерывной интеграции с уникальной pipeline-ориентированной архитектурой. В отличие от традиционных CI систем, Concourse строится вокруг концепции ресурсов и задач, создавая наглядные и масштабируемые пайплайны.

Ключевые концепции Concourse

  • Resources — внешние источники данных (Git, S3, Docker Registry)
  • Jobs — набор задач, которые выполняются последовательно
  • Tasks — атомарные единицы работы в контейнерах
  • Pipelines — граф из jobs и resources
  • Teams — изоляция и управление доступом

Установка Concourse

Установка с помощью Docker Compose:

 1# docker-compose.yml
 2version: '3.8'
 3
 4services:
 5  concourse-db:
 6    image: postgres:13
 7    environment:
 8      POSTGRES_DB: concourse
 9      POSTGRES_USER: concourse_user
10      POSTGRES_PASSWORD: concourse_pass
11    volumes:
12      - concourse-db:/var/lib/postgresql/data
13
14  concourse:
15    image: concourse/concourse:7.8.0
16    command: web
17    depends_on:
18      - concourse-db
19    ports:
20      - "8080:8080"
21    environment:
22      CONCOURSE_POSTGRES_HOST: concourse-db
23      CONCOURSE_POSTGRES_USER: concourse_user
24      CONCOURSE_POSTGRES_PASSWORD: concourse_pass
25      CONCOURSE_POSTGRES_DATABASE: concourse
26      CONCOURSE_EXTERNAL_URL: http://localhost:8080
27      CONCOURSE_ADD_LOCAL_USER: admin:admin
28      CONCOURSE_MAIN_TEAM_LOCAL_USER: admin
29
30  concourse-worker:
31    image: concourse/concourse:7.8.0
32    command: worker
33    privileged: true
34    depends_on:
35      - concourse
36    environment:
37      CONCOURSE_TSA_HOST: concourse:2222
38      CONCOURSE_GARDEN_NETWORK: 172.16.0.0/16
39
40volumes:
41  concourse-db:

Установка Fly CLI

1# Скачивание fly CLI
2curl -L https://github.com/concourse/concourse/releases/download/v7.8.0/fly-7.8.0-linux-amd64.tgz | tar -xz
3sudo mv fly /usr/local/bin/
4
5# Подключение к Concourse
6fly -t main login -c http://localhost:8080 -u admin -p admin
7
8# Проверка подключения
9fly -t main workers

Создание простого пайплайна

Файл pipeline.yml:

 1resources:
 2- name: source-code
 3  type: git
 4  source:
 5    uri: https://github.com/myorg/myapp.git
 6    branch: main
 7
 8- name: docker-image
 9  type: docker-image
10  source:
11    repository: myorg/myapp
12    username: ((docker-username))
13    password: ((docker-password))
14
15jobs:
16- name: test
17  plan:
18  - get: source-code
19    trigger: true
20  - task: run-tests
21    config:
22      platform: linux
23      image_resource:
24        type: docker-image
25        source:
26          repository: node
27          tag: "16"
28      inputs:
29      - name: source-code
30      run:
31        path: sh
32        args:
33        - -c
34        - |
35          cd source-code
36          npm ci
37          npm test
38
39- name: build-and-push
40  plan:
41  - get: source-code
42    passed: [test]
43    trigger: true
44  - task: build-image
45    privileged: true
46    config:
47      platform: linux
48      image_resource:
49        type: docker-image
50        source:
51          repository: concourse/oci-build-task
52      inputs:
53      - name: source-code
54      outputs:
55      - name: image
56      run:
57        path: build
58      params:
59        CONTEXT: source-code
60  - put: docker-image
61    params:
62      image: image/image.tar

Развертывание пайплайна:

1# Загрузка пайплайна
2fly -t main set-pipeline -p myapp -c pipeline.yml
3
4# Активация пайплайна
5fly -t main unpause-pipeline -p myapp
6
7# Запуск job вручную
8fly -t main trigger-job -j myapp/test

Работа с секретами

Файл credentials.yml:

1docker-username: myusername
2docker-password: mypassword
3slack-webhook: https://hooks.slack.com/services/...
1# Загрузка с секретами
2fly -t main set-pipeline -p myapp -c pipeline.yml -l credentials.yml

Сложный пайплайн с параллельными задачами

 1resources:
 2- name: source-code
 3  type: git
 4  source:
 5    uri: https://github.com/myorg/myapp.git
 6
 7- name: version
 8  type: semver
 9  source:
10    driver: git
11    uri: https://github.com/myorg/myapp-version.git
12    branch: version
13    file: version
14
15jobs:
16- name: test-unit
17  plan:
18  - get: source-code
19    trigger: true
20  - task: unit-tests
21    file: source-code/ci/tasks/unit-tests.yml
22
23- name: test-integration
24  plan:
25  - get: source-code
26    trigger: true
27  - task: integration-tests
28    file: source-code/ci/tasks/integration-tests.yml
29
30- name: build
31  plan:
32  - get: source-code
33    passed: [test-unit, test-integration]
34    trigger: true
35  - get: version
36    params: {bump: patch}
37  - task: build-app
38    file: source-code/ci/tasks/build.yml
39  - put: version
40    params: {file: version/version}
41
42- name: deploy-staging
43  plan:
44  - get: source-code
45    passed: [build]
46    trigger: true
47  - task: deploy
48    file: source-code/ci/tasks/deploy.yml
49    params:
50      ENVIRONMENT: staging
51
52- name: deploy-production
53  plan:
54  - get: source-code
55    passed: [deploy-staging]
56  - task: deploy
57    file: source-code/ci/tasks/deploy.yml
58    params:
59      ENVIRONMENT: production

Создание переиспользуемых задач

Файл ci/tasks/unit-tests.yml:

 1platform: linux
 2
 3image_resource:
 4  type: docker-image
 5  source:
 6    repository: node
 7    tag: "16"
 8
 9inputs:
10- name: source-code
11
12outputs:
13- name: test-results
14
15run:
16  path: sh
17  args:
18  - -c
19  - |
20    cd source-code
21    npm ci
22    npm test -- --reporter=junit --outputFile=../test-results/results.xml
23    npm run coverage -- --reporter=lcov --outputDir=../test-results/coverage
24
25params:
26  NODE_ENV: test

Уведомления и интеграции

 1resources:
 2- name: slack-alert
 3  type: slack-notification
 4  source:
 5    url: ((slack-webhook))
 6
 7jobs:
 8- name: notify-failure
 9  plan:
10  - get: source-code
11    trigger: true
12    passed: [test]
13  on_failure:
14    put: slack-alert
15    params:
16      channel: '#ci-cd'
17      text: |
18        ❌ Pipeline failed: $BUILD_PIPELINE_NAME/$BUILD_JOB_NAME
19        Build: $ATC_EXTERNAL_URL/builds/$BUILD_ID

Мониторинг ресурсов

 1# Просмотр всех пайплайнов
 2fly -t main pipelines
 3
 4# Детали пайплайна
 5fly -t main get-pipeline -p myapp
 6
 7# Просмотр активности
 8fly -t main builds
 9
10# Логи конкретной сборки
11fly -t main watch -j myapp/test
12
13# Информация о воркерах
14fly -t main workers

Управление командами

1# Создание новой команды
2fly -t main set-team -n development \
3  --local-user dev-user \
4  --local-user another-dev
5
6# Назначение пайплайна команде
7fly -t dev-target set-pipeline -p myapp -c pipeline.yml \
8  --team development

Vault интеграция для секретов

1# Конфигурация Concourse с Vault
2environment:
3  CONCOURSE_VAULT_URL: https://vault.example.com
4  CONCOURSE_VAULT_AUTH_BACKEND: cert
5  CONCOURSE_VAULT_CLIENT_CERT: /vault-certs/client.crt
6  CONCOURSE_VAULT_CLIENT_KEY: /vault-certs/client.key

Использование секретов из Vault:

1resources:
2- name: docker-image
3  type: docker-image
4  source:
5    repository: myorg/myapp
6    username: ((vault:secret/docker:username))
7    password: ((vault:secret/docker:password))

Сравнение с другими CI системами

ОсобенностьConcourseJenkinsGitLab CI
АрхитектураPipeline-orientedJob-orientedStage-oriented
ВизуализацияОтличнаяБазоваяХорошая
МасштабированиеАвтоматическоеРучноеАвтоматическое
ИзоляцияПолнаяЧастичнаяПолная

Случаи использования Concourse

  • Сложные пайплайны — множество зависимостей между задачами
  • Микросервисы — координация развертывания нескольких сервисов
  • Инфраструктура как код — автоматизация провижининга
  • Compliance — аудируемые и воспроизводимые процессы

Преимущества Concourse

  • Наглядная визуализация пайплайнов
  • Полная изоляция выполнения
  • Декларативная конфигурация
  • Масштабируемость и отказоустойчивость
  • Отличная интеграция с облачными сервисами

Рекомендации по использованию

  • Используй переиспользуемые задачи для стандартных операций
  • Настрой мониторинг ресурсов и уведомления
  • Применяй команды для изоляции проектов
  • Интегрируй с системами управления секретами

FAQ

Подходит ли Concourse для простых проектов?

Concourse лучше подходит для средних и сложных проектов, где важна визуализация зависимостей. Для простых проектов может быть избыточным.

Можно ли мигрировать с Jenkins на Concourse?

Да, но потребуется переосмысление пайплайнов в терминах ресурсов и задач. Автоматической миграции не существует.