Compose: Utilisation de la commande shell dans docker-compose.yml

Créé le 27 oct. 2016  ·  41Commentaires  ·  Source: docker/compose

Bonjour, existe-t-il un moyen d'utiliser les commandes shell dans le fichier docker-compose.yml ?
Voici mon cas d'utilisation:

 version: '2'
 services:
   ci:
     image: jenkins
     volumes:
       - ./data:/var/jenkins_home
       - /var/run/docker.sock:/var/run/docker.sock
       - $(command -v docker):/usr/bin/docker
     groupadd:
       - $(stat -c %g /var/run/docker.sock)
     ports:
       - "8080:8080"
       - "50000:50000"

Actuellement, cela me donne cette erreur:

ERROR: Invalid interpolation format for "volumes" option in service "ci": "${command -v docker}:/usr/bin/docker"
kinquestion

Commentaire le plus utile

Ce serait très utile d'avoir ...

Tous les 41 commentaires

Salut @zkanda ,

Désolé, ce n'est pas quelque chose que nous soutenons. Habituellement, cela se fait en définissant des variables d'environnement et en utilisant la substitution de variable dans le fichier Compose à la place.

@ shin- merci, je peux contourner les variables d'environnement. De plus, .env semble également très utile.
Documents pertinents: https://docs.docker.com/compose/environment-variables/#/the -env-file

@zkanda avez-vous déjà réussi à faire fonctionner cela, j'ai essayé dans mon fichier .env

DOCKER_BIN=`which docker`

puis dans le docker-compose.yml

jenkinsmaster:
  build: jenkins-master
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ${DOCKER_BIN}:/usr/bin/docker
  ports:
    - "50000:50000"

Mais je continue à avoir

Cannot create container for service jenkinsmaster: create `which docker`: "`which docker`" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.

Il semble donc que les commandes sont interprétées comme des chaînes dans le fichier .env ?

Les commandes ne sont pas développées par Compose, dans .env ou ailleurs.

Ce serait très utile d'avoir ...

+1

Voici un cas d'utilisation. Lors de la configuration de Kafka, il a besoin de l'adresse IP de la machine hôte. J'ai le script suivant pour l'obtenir pour moi:

DOCKER_HOST_IP=$(ifconfig | grep 'inet .*br' | sed -E 's/.*inet (.*) netmask.*/\1/')

Je référence cette IP dans l'environnement env. Je ne peux plus simplement lancer docker-compose up car je dois l'exécuter au préalable. Et je dois en informer les autres développeurs de l'équipe.

+1

Serait utile pour obtenir l'utilisateur actuel, comme dans:

services:
  foo:
    image: bar:latest
    user: ${CURRENT_USER-$(id -u):$(id -g)}

Il doit y avoir d'autres cas d'utilisation aussi ...

Au fait, je ne comprends pas que ${BAZ-default} fonctionne dans Compose si nous ne pouvons pas exécuter le reste des fonctionnalités de Bash ... (pour autant que je sache, le - est l'une des fonctionnalités de manipulation de variables de Bash, comme substitution avec ${VAR/search/replace} , par exemple)

Oui @ davi5e ... Ce que j'essayais:

version: "3.7"

services:
  orchestrator:
    build: .
    ports:
      - "2000:2000"
    # Use type host until we can test link
    network_mode: "host"
    environment:
      - NODE_ENV=development
      - LOCAL_USER_ID=${id -u}

@ davi5e est un autre cas d'utilisation lorsque vous souhaitez créer un volume docker et le lier à votre répertoire de référentiel git. Ce bain absolu se méfiera de chaque développeur de l'équipe.

+1
Plz rouvrir le problème

+1
mon cas d'utilisation est de publier une plage de ports qui est déterminée en fonction d'un port "de base"

Cela serait très utile pour définir des variables UID / GID car c'est à peu près une exigence pour utiliser Docker dans un environnement de développement (sans avoir besoin d'utiliser des scripts pour définir cela dans un fichier .env).

+1

Pourrait l'utiliser pour étiqueter / étiqueter les images générées par docker compose avec la balise git et le hachage de validation:

En .env :

GIT_VERSION=$(git describe --always --dirty --abbrev)
OUTER_PORT=6970

En docer-complse.yml :

version: '3'
services:
  nginx:
    restart: always
    build:
        context: ./nginx
        labels:
          org.label-schema.schema-version: "1.0"
          org.label-schema.version: "${GIT_VERSION}"
          org.lavel.schema.url: "https://mydocu-server.company.com/vcs/${GIT_VERSION}"
    ports:
      - ${OUTER_PORT}:8080

Pour ceux qui font cela en développement, si votre shell définit la variable UID , vous pouvez la transmettre lors de la construction de l'image de développement local. Puisque l'image du développement local n'est pas partagée, vous n'avez pas à vous soucier des conflits d'uid avec vos collègues.

+1

@ con-f-use En faisant cela, vous enverrez simplement la commande réelle et non le résultat de mes tests, le seul hack que j'ai réussi jusqu'à présent est d'écrire un script docker wrapping compose qui configure la variable d'environnement.

+1

TL; DR si vous souhaitez exporter ces variables à partir du fichier .env :

# set the path of .env file here
ENV_FILE="${ENV_FILE:-local.env}"
while IFS= read -r line; do
  export "$line"
done < <( grep --color=never -E -v -e '^#' -e '^[[:space:]]*$' "${ENV_FILE}" )

Comment utiliser:

  • Tapez-le sur votre ligne de commande et appuyez sur Entrée pour modifier votre environnement shell actuel

OU

  • Enregistrez-le en tant que script bash et créez-le

Mises en garde:

  • L'enregistrer en tant que script et l'exécuter n'exportera pas comme par magie ces variables dans votre environnement shell actuel. Vous devrez le trouver ou faire de fantaisie eval .
  • (Peut-être une bonne chose?) Cela écrasera les variables existantes avec le même nom dans $ENV_FILE

Explication: ici

Jetez un œil à direnv pour automatiser tout cela https://direnv.net/

Le ven 28 juin 2019, 12:57 PM Sudarshan Wadkar [email protected]
a écrit:

TL; DR si vous souhaitez exporter ces variables à partir d'un fichier .env:

définissez le chemin du fichier .env ici

ENV_FILE = "$ {ENV_ FILE: -local.env }" while IFS = read -r line; faire
export "$ line" done <<(grep --color = never -E -v -e '^ #' -e '^ [[: space:]] * $' "$ {ENV_FILE}")

Comment utiliser:

  • Tapez-le sur votre ligne de commande
  • Enregistrez-le en tant que script bash et créez-le

Mises en garde:

  • L'enregistrer en tant que script et l'exécuter ne les exportera pas comme par magie
    variables dans votre environnement shell actuel. Vous devrez le trouver ou le faire
    une évaluation de fantaisie.
  • (Peut-être une bonne chose?) Cela écrasera les variables existantes avec le même
    nom dans $ ENV_FILE

Explication: ici
https://explainshell.com/explain?cmd= While+IFS%3D+read+-r+line%3B+do+export+%22%24line%22%3B+done+%3C+%3C%28grep+--color%3Dno+ -v + -e +% 27% 5E% 23% 27 + -e +% 27% 5E% 5B% 5B% 3Aspace% 3A% 5D% 5D *% 24% 27 +% 24% 7BENV_FILE% 7D% 29

-
Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDBQXQZTC5FXTOFL6UTP4XOBJA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43TUL52HS4DFVREXG43TUL52HS4DFVREXG43TUL52HS4DFVREXG43
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AACHRDGJ6FAQBEDLBSRVS6TP4XOBJANCNFSM4CUISSSA
.

Ouais, direnv est bien mais je ne suis pas sûr si cela sera utile avec le fichier .env Docker qui a des lignes simples avec la syntaxe VAR=VAL (comme sur ce lien.) L'idée étant .env fichier docker-compose peut l'exécuter sur le staging / deploy.

Il n'y a pas vraiment de variables d'environnement
https://en.wikipedia.org/wiki/Environment_variable s'ils font partie de
la base de code et ne fait pas partie de l'environnement ...

Le ven 28 juin 2019 à 14 h 04 Sudarshan Wadkar [email protected]
a écrit:

Ouais, direnv est sympa mais je ne sais pas si ça sera utile avec Docker
fichier .env qui a des lignes simples avec la syntaxe VAR = VAL simple (selon ce
https://docs.docker.com/compose/env-file/#syntax-rules link.) L'idée
le fichier .env est validé dans le référentiel et le script de construction peut
l'exécuter sur mon local ou docker-compose peut l'exécuter sur le staging / deploy.

-
Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDCEKOMK2VI3A43QBC3P4XV5BA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYZY53A#issuecomment-506695404 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AACHRDF3Q3YOZPHUIUZYEPTP4XV5BANCNFSM4CUISSSA
.

Ah d'accord.

J'aime penser que le fichier .env se transforme en variable d'environnement lorsque vous exécutez docker-compose up .

Mon cas d'utilisation était d'utiliser le même fichier .env que la source de vérité pour exécuter une instance de développement locale (peut-être sans l'aide de docker-compose ). Alors oui, peut-être que ces lignes dans le fichier .env ne sont pas vraiment des variables d'environnement, mais elles se transforment sûrement en une lorsque vous déployez.

Je ne vois toujours pas comment direnv va aider dans ce cas.

Un autre cas d'utilisation est de mettre une commande qui génère un mot de passe en l'associant à env var dans le conteneur.
De cette façon, le mot de passe ne serait pas écrit dans les fichiers .env ou docker-compose.yml.

Je pense que cela va être un énorme avantage pour de nombreux cas d'utilisation liés à la sécurité.

+1

+1

+1, serait extrêmement utile pour définir uid et gid sans trop compliquer la solution

''
/ _ / \
(oo)

^ <`` ``

+1 J'ai un cas d'utilisation comme mentionné ci-dessus pour ajouter une branche git et une validation dans le fichier de composition qui ira éventuellement dans le fichier docker, puis sera ajouté en tant que version dans le manifeste du jar construit dans une étape d'un processus de construction de docker à plusieurs étapes .

  gateway:
    image: name
    build:
      context: ./project
      dockerfile: build/Dockerfile
      args:
        - GIT_COMMIT=${$(git rev-list -1 HEAD):-unspecified}
        - GIT_DATE=${$(git log -1 --date=short --pretty=format:%ct):-unspecified}

Donc, actuellement, pour 7 projets dans mon fichier de composition, je dois définir des environnements 7x2. Triste.

@ shin- Pourriez-vous rouvrir ceci en tant que demande de fonctionnalité? Il semble que cela n'ait pas été résolu par de belles solutions de contournement et qu'il existe un besoin solide.

+1 J'aurais probablement pu y parvenir d'une manière différente, mais j'avais besoin d'engager le moteur docker depuis un conteneur pour redémarrer un conteneur voisin. Dans le cas où mon certificat Letsencrypt a expiré, mais je dois redémarrer le conteneur NGinx après le renouvellement. Le problème est: comment dire à docker-compose à l'intérieur du conteneur quel est le nom du projet pour ce groupe de conteneurs? PROJECT=(basedir ~+) . Il est codé manuellement pour l'instant :(

+1 à cette demande de fonctionnalité
Un autre cas d'utilisation est de récupérer des secrets d'un cli / http (par exemple, coffre-fort, 1Password) et de se connecter à l'environnement.
c'est à dire

...
    environment:
      - SERVICE_USERNAME=$(vault kv get -field=username kv/service/credentials)
      - SERVICE_PASSWORD=$(vault kv get -field=password kv/service/credentials)
...

J'ai le même besoin que @rafaelbattesti , sauf que j'utilise lastpass.

...
     environment:
         - TRPASSWD=$(lpass show --password Transmission)
....

+1

+1

@ shin- Pourriez-vous rouvrir ceci en tant que demande de fonctionnalité? Il semble que cela n'ait pas été résolu par de belles solutions de contournement et qu'il existe un besoin solide.

@ four43 , peut-être @ shin- ou d'autres ne lisent pas les commentaires sur les problèmes fermés? Devons-nous en ouvrir un autre pour attirer l'attention?

L'extension de variable dans le fichier docker-compose serait une fonctionnalité très utile à avoir ...

+1

@esale - Ouais je suppose que ça dépend un peu. Je pouvais voir que c'était hors de portée pour cette affaire. N'exagérez pas trop sur certains DSL. À ce stade, modélisez le fichier docker-compose avec un autre outil? Croisons-nous trop les préoccupations?

Si vous utilisez un fichier .env, vous pouvez remplacer la sortie du shell par une commande comme celle-ci

eval "echo \"$(cat .env.example)\"" > .env

Exemple de fichier .env.example

DOCKER_BIN=$(which docker)
DOCKER_COMPOSE_BIN=$(which docker-compose)

Créez le fichier .env

DOCKER_BIN=/snap/bin/docker
DOCKER_COMPOSE_BIN=/snap/bin/docker-compose
Cette page vous a été utile?
0 / 5 - 0 notes