I have a working swarm setup and rolling-updates deployment. As i have to execute some tasks after deployment (like database migrations) i added a "manager" service to the stack. this service is limited to the node-manager - so i always have a way to find it.
To get the current containerID i use this command:
export MANAGER_ID=$(docker --tls ps --filter label=com.docker.swarm.service.name=projectname-php-manager -q)
This works ... but not during deploy.
The stack deploy
exits to soon (befor the container is up) or even befor the manager container gets updated.
I also added a sleep 10
befor geting the containerID but the results vary.
Is there a way to wait or to know when a specific service is deployed?
The full deploy looks like this (done in a gitlab-ci job - but this is not the root of the problem):
deploy:staging:
variables:
DOCKER_HOST: "tcp://swarm-manager.hostname.tld:2376"
DOCKER_CERT_PATH: "/home/gitlab-runner/docker/swarm-manager.hostname.tld"
VERSION_TAG: "$CI_COMMIT_TAG"
MYSQL_PROD_PASSWORD: "$MYSQL_PROD_PASSWORD"
SECRET_TOKEN: "$SECRET_TOKEN"
script:
- docker --tls stack deploy -c docker-compose.prod.yml project-name --with-registry-auth --prune
- sleep 10
- export MANAGER_ID=$(docker --tls ps --filter label=com.docker.swarm.service.name=project-name_php-manager -q)
- docker --tls exec -t $MANAGER_ID bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration
stage: deploy
environment:
name: staging
url: http://projectname.com
only: [tags]
cache: ~
dependencies:
- build:app
tags:
- deploy
Part from docker-compose.prod.yml:
php-manager:
image: dockerhub.mydomain.tld/namespace/projectname/php:${VERSION_TAG}
environment:
DATABASE_URL: "mysql://projectname:${MYSQL_PROD_PASSWORD}@mysql:3306/projectname?charset=utf8mb4&serverVersion=5.7"
APP_ENV: prod
APP_SECRET: "${SECRET_TOKEN}"
VERSION: "${VERSION_TAG}"
REDIS_HOST: redis
networks:
- default
deploy:
placement:
constraints: [node.role == manager]
replicas: 1
restart_policy:
condition: on-failure