Newer
Older
image: docker:19.03.0
# Disable TLS just for the docker daemon running locally, TLS is still used to deploy built images!
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
- docker:19.03.0-dind
# The file variables will be kept accross jobs : it contains useful informations about modified
# Dockerfile / docker-compose in the last commit
cache:
paths:
- variables
- ci-base
- build
- security-tests
- push
# Hidden key meant to be included in other jobs, for factorization
.pull-modified-image: &pull-modified-image
image: $REGISTRY_PROD/pica-ci-base
tags: [build]
before_script:
- echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin
- source variables
- docker pull $MODIFIED_IMAGE_FULL_TEST
# Build the base image used for all further steps : this is done only when pica-ci's Dockerfile is modified
Quentin Duchemin
committed
pica-ci-base:
stage: ci-base
tags: [build]
Quentin Duchemin
committed
before_script:
- echo $REGISTRY_PROD_PASSWORD | docker login $REGISTRY_PROD -u $REGISTRY_PROD_USERNAME --password-stdin
script:
- docker build -f pica-ci-base/Dockerfile . -t $REGISTRY_PROD/pica-ci-base:latest
- docker push $REGISTRY_PROD/pica-ci-base:latest
Quentin Duchemin
committed
after_script:
- docker logout $REGISTRY_PROD
rules:
- if: '$CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "dev-ci"'
changes:
- "pica-ci-base/Dockerfile"
Quentin Duchemin
committed
allow_failure: true
- when: never
Quentin Duchemin
committed
# Create a file a few environment variables added (which Dockerfile has been modified, the complete name of the image...)
# The file will be an artifact shared with further steps
set-variables:
stage: ci-base
tags: [build]
image: $REGISTRY_PROD/pica-ci-base
script:
- chmod +x ./get-modified-image.sh
- ./get-modified-image.sh
# If there are changes in any of the files and folders of 'pica-*' or
# 'meta-*', then propose a manual build
rules:
- changes:
# Build the image that was modified
stage: build
tags: [build]
image: $REGISTRY_PROD/pica-ci-base
before_script:
# First login on the production registry, in case the image is based on another registry image
- echo $REGISTRY_PROD_PASSWORD | docker login $REGISTRY_PROD -u $REGISTRY_PROD_USERNAME --password-stdin
- source variables
script:
# Build the image
- docker build -f $MODIFIED_IMAGE/Dockerfile $MODIFIED_IMAGE -t $MODIFIED_IMAGE_FULL_TEST
- docker logout $REGISTRY_PROD
# Then login on the test registry and push the image
- echo $REGISTRY_PASSWORD | docker login $REGISTRY -u $REGISTRY_USERNAME --password-stdin
- docker push $MODIFIED_IMAGE_FULL_TEST
after_script:
- docker logout $REGISTRY
# Build if Dockerfile changed and previous stage completed successfully
rules:
- changes:
- "meta-*/Dockerfile"
- changes:
- "pica-*/**"
- "meta-*/**"
when: manual
allow_failure: true
# Run CoreOS' Clair and make the CI failed if a critical vulnerability isn't in the whitelist
stage: security-tests
<<: *pull-modified-image
script:
- docker run -d --name db arminc/clair-db:latest
- docker run -p 6060:6060 -d --link db:postgres --name clair --restart on-failure arminc/clair-local-scan:latest
- wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
- mv clair-scanner_linux_amd64 clair-scanner
- chmod +x clair-scanner
- while( ! wget -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; done
- ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r clair-report.json -l clair.log -w $MODIFIED_IMAGE/clair-whitelist.yml --threshold="High" $MODIFIED_IMAGE_FULL_TEST
artifacts:
paths:
- clair-report.json
- clair.log
rules:
- changes:
- "pica-*/Dockerfile"
- "pica-*/clair-whitelist.yml"
- "meta-*/Dockerfile"
- "meta-*/clair-whitelist.yml"
- changes:
- "pica-*/**"
- "meta-*/**"
when: manual
allow_failure: true
# Run docker-bench-security and upload the results
docker-bench-security:
stage: security-tests
<<: *pull-modified-image
script:
# Change the Docker Compose to use the "testing" image, not yet pushed on production registry
- sed -i -e "s|$MODIFIED_IMAGE_FULL|$MODIFIED_IMAGE_FULL_TEST|g" $MODIFIED_IMAGE/docker-compose.yml
# If *.example secrets files exist, remove the .example extension to be able to start the container
# Indeed these file are used in Docker Compose with env_file directive
- if [[ -d $MODIFIED_IMAGE/secrets ]]; then for i in $MODIFIED_IMAGE/secrets/*.example ; do cp $i $(echo $i| cut -d '.' -f1,2); done; fi;
# Let docker-compose create the required volumes and networks
- "sed -i -e 's/external: true/external: false/g' $MODIFIED_IMAGE/docker-compose.yml"
- cat $MODIFIED_IMAGE/docker-compose.yml
- cd $MODIFIED_IMAGE
Quentin Duchemin
committed
# Login on the production registry, in case there is another image in Docker Compose stored on the production registry
- docker logout $REGISTRY
- echo $REGISTRY_PROD_PASSWORD | docker login $REGISTRY_PROD -u $REGISTRY_PROD_USERNAME --password-stdin
- docker-compose up -d
- git clone https://github.com/docker/docker-bench-security.git
- cd docker-bench-security
- sh docker-bench-security.sh -c container_images,container_runtime,docker_security_operations,community_checks -l ../../report.txt
Quentin Duchemin
committed
- docker logout $REGISTRY_PROD
artifacts:
paths:
- report.txt
- "meta-*/**"
# Push the generated image on the production registry,
# once it passed all security tests and has been successfully built
# and run on the test virtual machine
stage: push
<<: *pull-modified-image
script:
- docker tag $MODIFIED_IMAGE_FULL_TEST $MODIFIED_IMAGE_FULL
- echo $REGISTRY_PROD_PASSWORD | docker login $REGISTRY_PROD -u $REGISTRY_PROD_USERNAME --password-stdin
# MODIFIED_IMAGE_FULL already should include the registry URL
- docker push $MODIFIED_IMAGE_FULL
after_script:
- docker logout $REGISTRY_PROD
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
changes:
when: manual