Gitlab

Tâche automatisée avec les conteneurs

Si vous avez besoin d’éxécuter des tâches à interval régulier, le déploiement de conteneurs permet de paramétrer automatiquement des tâches automatiques (cronjob) sur la cible de déploiement (préprod ou prod).

La tâche cron doit être définie dans le docker-compose, et le workflow va utiliser les labels du service pour l’installer au moment du déploiment.

Pour cela il nous faut un service qui:

  • échoue rapidement: command: /bin/false
  • ne redémarre pas après cet échec: restart: no
  • deux labels définissant la commande à lancer et la périodicité de la tâche:
    • le label sh.factory.cronjob.command doit être une commande executable depuis votre conteneur avec bash -c. Par exemple bash -c "echo time to run"
    • le label sh.factory.cronjob.schedule suis la syntaxe standard de cron

Il n’y a pas d’autre contrainte. N’importe quel service peut devenir un cronjob.

Définir la tâche cron

Dans l’exemple docker-compose.yml ci-dessous, nous utilisons l’image de notre application pour créer un deuxième service qui sera traité comme cronjob. Ce service sera lancé toutes les heures.

# this file is good to go for production
version: "3"

services:

    # our webapp. we define a &web_service yaml alias to "duplicate" this service later
    app: &web_service
        # use our image
        image: ${CI_REGISTRY_IMAGE}/app:${CI_COMMIT_SHA}
        # expose our server port
        expose: [9000]
        # always restart on failure
        restart: "always"
        # define some env vars available to our container
        environment: &web_service_env
            ENV: ${CI_ENVIRONMENT_NAME}
            CI_ENVIRONMENT_DOMAIN: ${CI_ENVIRONMENT_DOMAIN}
        labels:
            # traefik v1 configuration
            traefik.frontend.rule: Host:${CI_ENVIRONMENT_DOMAIN}
            traefik.enable: 'true'
            # headers STS
            traefik.frontend.headers.STSPreload: 'true'
            traefik.frontend.headers.STSSeconds: '63072000'

    # we define a cronjob service
    cron1:
        <<: *web_service
        command: /bin/false
        restart: "no"
        labels:
            # delay. run each hour
            sh.factory.cronjob.schedule: "0 * * * *"
            # command to launch
            sh.factory.cronjob.command: "python app/cron.py"

L’alias &web_service permet de dupliquer le service dans le docker-compose et de le surcharger. Idem pour l’alias d’environnement &web_service_env.

NB: le workflow empêche d’avoir deux processus d’un même job en simultané. Veillez à avoir une fréquence d’exécution supérieur à la durée d’éxécution du job.

Imposer un timeout au cron

Utiliser la variable de timeout définie dans le .gitlab-ci.yml, reprise lors du déploiement, pour imposer un temps d’exécution maximum appliqué au docker run qui sera appelé lors de la mise en place du cron.

Dans notre exemple de gitlab-ci.yml, à l’étape de déploiement, on peut ajouter une variable RUNJOB_TIMEOUT pour forcer un timeout à l’application (ici 1 heure):

staging:
    stage: staging
    environment:
        name: staging
        url: http://<myapp>.staging.bearstech.com
    only:
        - master
    script:
        # use the factory-deploy script to deploy the compose project
        # this will (re)start docker-compose on the target after pulling the new image
        - factory-deploy
    variables:
        RUNJOB_TIMEOUT: "3600"
Top