Reputation: 1505
I am trying to use docker-compose with Jenkins CI.
The main issue for me now is - how to stop all docker containers after build finish? At the same time, we need to take in mind that the same containers can be used by others.
Here is an example:
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'
It works as a single build. But if I run two or more builds at the same time - first completed build will execute docker-compose -f docker-compose.yml down
and all other running builds will fail.
If I remove docker-compose -f docker-compose.yml down
string from Jenkinsfile - mysql
and selenium
containers will continue to work.
What is the best way to stop all containers if they are not using?
I need to stop all containers (mysql
and selenium
for that example) after build is completed.
Upvotes: 0
Views: 1560
Reputation: 821
I do not understand what you want to achieve in your Jenkinsfile.
1) When do you start the containers mysql
and selenium
?
The command sh 'docker-compose -f docker-compose.yml run --rm my_app sh -c "some command"'
will start only the service my_app
, execute "some command" and remove the container.
2) Do you really need to start 3 different containers of my_app
for 'Tests', 'Scan' and 'Some other things' ? If you just need to execute "some command"
in parallel, consider using the command docker-compose exec
.
If your main problem is to start/stop containers when running several builds at the same time, here is a Jenkinsfile that can help :
//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'
The option -p my_project_${BUILD_NUMBER}
in the docker-compose
commands will allow you (and therefor Jenkins) to distinguish the containers launched by the different builds.
For example, the build #1 will create : my_project_1_my_app
, my_project_1_mysql
and my_project_1_selenium
.
Then, the build #2 will create : my_project_2_my_app
, my_project_2_mysql
and my_project_2_selenium
.
Then, the build #1 will remove : my_project_1_my_app
, my_project_1_mysql
and my_project_1_selenium
, while the containers of build #2 are still running.
And finally the build #2 will remove : my_project_2_my_app
, my_project_2_mysql
and my_project_2_selenium
.
Upvotes: 1