#docker-compose #jenkins-pipeline
#docker-compose #дженкинс-конвейер
Вопрос:
Я пытаюсь использовать docker-compose с Jenkins CI.
Главная проблема для меня сейчас — как остановить все контейнеры docker после завершения сборки? В то же время нам нужно учитывать, что одни и те же контейнеры могут использоваться другими.
Вот пример:
docker-compose:
version: "3"
services:
my_app:
build: .
depends_on:
- mysql
- selenium
mysql:
...
selenium:
...
Jenkinsfile:
sh 'docker-compose -f docker-compose.yml build'
sh 'docker-compose -f docker-compose.yml run --rm my_app sh -c "some-commands'
stage('Run Checks') {
parallel(
'Tests': { sh 'docker-compose -f docker-compose.yml run --rm my_app sh -c "some command"' },
'Scan': { sh 'docker-compose -f docker-compose.yml run --rm my_app sh -c "some command"' },
'Some other things': { sh 'docker-compose -f docker-compose.yml run --rm my_app sh -c "some command"' }
)
}
sh 'docker-compose -f docker-compose.yml down'
Это работает как единая сборка. Но если я запущу две или более сборки одновременно — первая завершенная сборка будет выполнена docker-compose -f docker-compose.yml down
, а все остальные запущенные сборки завершатся неудачей.
Если я удалю docker-compose -f docker-compose.yml down
строку из Jenkinsfile — mysql
и selenium
контейнеры продолжат работать.
Каков наилучший способ остановить все контейнеры, если они не используются? Мне нужно остановить все контейнеры ( mysql
и selenium
для этого примера) после завершения сборки.
Ответ №1:
Я не понимаю, чего вы хотите достичь в своем Jenkinsfile.
1) Когда вы запускаете контейнеры mysql
и selenium
? Команда sh 'docker-compose -f docker-compose.yml run --rm my_app sh -c "some command"'
запустит только службу my_app
, выполнит «некоторую команду» и удалит контейнер.
2) Вам действительно нужно запускать 3 разных контейнера my_app
для «Тестов», «Сканирования» и «Некоторых других вещей»? Если вам просто нужно выполнить "some command"
параллельно, рассмотрите возможность использования команды docker-compose exec
.
Если ваша основная проблема заключается в запуске / остановке контейнеров при одновременном запуске нескольких сборок, вот файл Jenkins, который может помочь :
//Build the services
sh 'docker-compose -f docker-compose.yml build'
//Create and start the containers
sh 'docker-compose -f docker-compose.yml -p my_project_${BUILD_NUMBER} up -d'
stage('Run Checks') {
parallel(
//Execute "some command" on running container my_app
'Tests': { sh 'docker-compose -f docker-compose.yml -p my_project_${BUILD_NUMBER} exec my_app sh -c "some command"' },
'Scan': { sh 'docker-compose -f docker-compose.yml -p my_project_${BUILD_NUMBER} exec my_app sh -c "some command"' },
'Some other things': { sh 'docker-compose -f docker-compose.yml -p my_project_${BUILD_NUMBER} exec my_app sh -c "some command"' }
)
}
//Stop and remove containers
sh 'docker-compose -f docker-compose.yml -p my_project_${BUILD_NUMBER} down'
Опция -p my_project_${BUILD_NUMBER}
в docker-compose
командах позволит вам (и для Дженкинса соответственно) различать контейнеры, запущенные разными сборками.
Например, сборка # 1 создаст : my_project_1_my_app
, my_project_1_mysql
и my_project_1_selenium
.
Затем в сборке # 2 будут созданы : my_project_2_my_app
, my_project_2_mysql
и my_project_2_selenium
.
Затем сборка # 1 удалит : my_project_1_my_app
, my_project_1_mysql
и my_project_1_selenium
, в то время как контейнеры сборки # 2 все еще запущены.
И, наконец, сборка # 2 удалит : my_project_2_my_app
, my_project_2_mysql
и my_project_2_selenium
.