Ever wanted that your config files in you docker-stack updated also when you released a new version of your stack through a CI/CD pipeline? Or you where in a development phase where you are constantly changing stuff in the config but you also wanted to make sure that you knew which config was used in what release in the pipeline? Well… Maybe you should try the next trick:
variables:
HOSTNAME: dockerhost.tuxito.be #Host to deploy docker-compose
Clone or Pull Repo to Remote Host
clone:
image: alpine
before_script:
- apk add openssh-client git jq curl
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY_ANSIBLE" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- /usr/bin/git config --global user.email "$GITLAB_USER_EMAIL"
- /usr/bin/git config --global user.name "$GITLAB_USER_LOGIN"
- GIT_CLONE_URL="$(curl --silent -XGET "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID?private_token=$ANSIBLE_TOKEN" | jq -r '.ssh_url_to_repo')"
script:
- ssh -o StrictHostKeyChecking=no ansible@$HOSTNAME "printf '%s\n %s\n' 'Host *' 'StrictHostKeyChecking no' > ~/.ssh/config && chmod 600 ~/.ssh/config"
- ssh -o StrictHostKeyChecking=no ansible@$HOSTNAME "if [ -d "$CI_PROJECT_NAME" ]; then (rm -rf $CI_PROJECT_NAME; git clone $GIT_CLONE_URL); else git clone $GIT_CLONE_URL; fi"
Deploy stack
deploy:
image: alpine
before_script:
- apk add openssh-client git jq curl
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY_ANSIBLE" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
script:
- ssh -o StrictHostKeyChecking=no ansible@$HOSTNAME "sed -i -E "/CONF_VERSION=/s/=.*/=$CI_JOB_ID/" $CI_PROJECT_NAME/deploy.sh"
- ssh -o StrictHostKeyChecking=no ansible@$HOSTNAME "cd $CI_PROJECT_NAME; chmod +x deploy.sh; sudo ./deploy.sh"
I’m using a gitlab-ci pipeline file here.. But the eventual purpose can be achieved using all Ci/Cd tools. It is just a matter of changing the Variable name.
More importantly this line:
ssh -o StrictHostKeyChecking=no ansible@$HOSTNAME "sed -i -E "/CONF_VERSION=/s/=.*/=$CI_JOB_ID/" $CI_PROJECT_NAME/deploy.sh"
Here you wil find the ENVIRONMENT value used in the upcoming docker-compose file CONF_VERSION. Which on his term has the value of the $CI_JOB_ID which is a baked in value of Gitlab:
CI_JOB_ID
The unique ID of the current job that GitLab CI/CD uses internally.
If you where using Bamboo for example you could use bamboo.buildNumber.
Then for the trick in your docker-compose file:
version: "3.7"
services:
elasticsearch:
image: elasticsearch:${ELASTIC_VERSION}
hostname: elasticsearch
environment:
- "discovery.type=single-node"
- "xpack.monitoring.collection.enabled=true"
ports:
- 9200:9200
- 9300:9300
networks:
- elastic
volumes:
- type: volume
source: elasticsearch-data
target: /usr/share/elasticsearch/data
- type: volume
source: snapshots
target: /snapshots
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.hostname == morsuv1416.agfa.be]
secrets:
- source: elasticsearch-config
target: /usr/share/elasticsearch/config/elasticsearch.yml
mode: 0644
uid: "1000"
gid: "1000"
filebeat:
image: docker.elastic.co/beats/filebeat:${ELASTIC_VERSION}
hostname: "{{.Node.Hostname}}-filebeat"
ports:
- "5066:5066"
user: root
networks:
- elastic
secrets:
- source: filebeat-config
target: /usr/share/filebeat/filebeat.yml
volumes:
- filebeat:/usr/share/filebeat/data
- /var/run/docker.sock:/var/run/docker.sock
- ...
secrets:
elasticsearch-config:
file: configs/elasticsearch.yml
name: elasticsearch-config-v${CONF_VERSION}
filebeat-config:
file: configs/filebeat.yml
name: filebeat-config-v${CONF_VERSION}
As you can see… The name in docker stack will change but there reference to the secret (aka Config file) will be the same in docker-compose.yml.
So all there is left in the deploy.sh script that we use in the the gitlab-ci file and you are good to go:
!/bin/bash
export ELASTIC_VERSION=7.10.1
export ELASTICSEARCH_USERNAME=elastic
export ELASTICSEARCH_PASSWORD=changeme
export ELASTICSEARCH_HOST=elasticsearch
export KIBANA_HOST=kibana
1 is PlaceHolder. Gets changed During deploy
export CONF_VERSION=1
docker network ls|grep elastic > /dev/null || docker network create --driver overlay --attachable elastic
docker stack deploy --prune --compose-file docker-compose.yml elkstack
Happy dockering!
Leave a Reply