Construire et exécuter Dockerfile avec une seule commande

137

Est-il possible de créer une image à partir de Dockerfile et de l'exécuter avec une seule commande?
Il existe une commande docker buildpour créer un Dockerfile et docker run -itexécuter l'image.

Existe-t-il une combinaison de ces deux commandes pour faciliter la création et l'exécution avec une seule commande?

Scintillement
la source
Si vous développez votre cas d'utilisation, nous pouvons peut-être vous présenter de meilleures options.
Jonathon Reinhart
7
@JonathonReinhart Mon cas d'utilisation est d'itérer rapidement lorsque je modifie un Dockerfile sur lequel je travaille.
Shubham Chaudhary

Réponses:

155

Non, il n'y a pas de commande unique. Mais si vous marquez votre image au fur et à mesure que vous la construisez, elle sera plus facile à exécuter:

docker build -t foo . && docker run -it foo
Jonathon Reinhart
la source
2
Bonne réponse parce que vous pouvez ensuite supprimer facilement l'image si vous souhaitez: docker rmi foo.
Sarkis Varozian
237

Si vous voulez éviter le balisage, docker build -qne produit rien d'autre que le hachage final de l'image , que vous pouvez utiliser comme argument pour docker run:

docker run -it $(docker build -q .)

Et ajouter --rmà docker runsi vous voulez que le conteneur automatiquement supprimé quand il sort.

docker run --rm -it $(docker build -q .)
starthal
la source
9
Mieux que la réponse acceptée, car elle n'encombre pas le référentiel d'images local
InsOp
18
@InsOp En fait, cela produit aussi des images locales. Ils ne sont tout simplement pas étiquetés.
Jonathon Reinhart
2
Malheureusement, cela ne vous montre pas la sortie de construction régulière de docker build: /
Lion
1
@Lion que le point d' -qoption. Pour le rendre silencieux, pour afficher uniquement la balise générée automatiquement. Et c'est tout. N'hésitez pas à transformer ce stdin comme vous le souhaitez.
Salathiel Genèse le
Pour obtenir la sortie de la construction, vous devez adapter la réponse de Viacheslav Shalamov :docker build . | tee /dev/tty | tail -n1 | cut -d' ' -f3 | xargs -I{} docker run --rm {}
oliverpool
5

Si vous utilisez Makefile, je trouve cet extrait utile:

build:
    @docker build . | tee .buildlog

bash: build
    @docker run --rm -it $(shell grep "Successfully built" .buildlog | cut -d ' ' -f 3) /bin/bash

Vous n'avez pas besoin de balisage, comme dans @ jonathon-reinhart answer, mais vous obtenez également la sortie de construction.

Tavlima
la source
5

J'utilise docker-compose pour cette commodité, car la plupart des applications que je construis parlent tôt ou tard à des services externes, donc si je vais l'utiliser quand même, pourquoi ne pas l'utiliser dès le début. Ayez simplement docker-compose.yml comme:

version: "3"
services:
  app:
    build: .

puis exécutez simplement l'application avec:

docker-compose up --build app

Il reconstruira l'image ou réutilisera le conteneur en fonction des modifications apportées à la définition de l'image.

Dejan Simic
la source
0

PC Windows

Créez un run.batfichier. Ensuite, dans le fichier, ajoutez ceci:

docker build -t foo . 
docker run -it foo

Pour exécuter le fichier à l'aide de PowerShell ou cmd, procédez comme suit:

./run.bat
Rob
la source
0

docker-build-and-run

J'ai créé une petite commande d'aide pour la construction et l'exécution, en une seule commande. Sur Linux ou Mac, vous pouvez l'ajouter à votre ~/.bash_profilepour le rendre disponible dans le terminal.

Usage:

docker-build-and-run BUILD_ARGS [-- RUN_ARGS] [-- RUN_COMMAND]

Exemples:

docker-build-and-run . -- npm run test
docker-build-and-run --file ./Dockerfile . -- -v ~/volume:/var/volume -- node server.js

Le scénario:

Ajoutez-le à un .shfichier ou ajoutez-le à votre ~/.bash_profile:

TERM_GREEN="\033[1;32m"
TERM_BLUE="\033[1;34m"
TERM_NC="\033[0m"
docker-build-and-run() {
    if [[ -z "$@" ]]; then
        echo "
            Usage:
                docker-build-and-run BUILD_ARGS [-- RUN_ARGS] [-- RUN_COMMAND]
            Examples:
                docker-build-and-run . -- npm run test
                docker-build-and-run --file ./Dockerfile . -- -v ~/volume:/var/volume -- node server.js
        "
        return
    fi

    # Extract the segments between the dashes:
    BEFORE_THE_DASHES=
    while (( "$#" )); do
        if [[ "$1" = "--" ]]; then
            shift
            break
        fi
        BEFORE_THE_DASHES="$BEFORE_THE_DASHES $1"
        shift
    done
    SEGMENT_1=$BEFORE_THE_DASHES

    BEFORE_THE_DASHES=
    while (( "$#" )); do
        if [[ "$1" = "--" ]]; then
            shift
            break
        fi
        BEFORE_THE_DASHES="$BEFORE_THE_DASHES $1"
        shift
    done
    SEGMENT_2=$BEFORE_THE_DASHES

    SEGMENT_3=$@


    BUILD_ARGS=$SEGMENT_1
    RUN_ARGS=$SEGMENT_2
    RUN_COMMAND=$SEGMENT_3
    if [ -z "$RUN_COMMAND" ]; then
      RUN_COMMAND=$RUN_ARGS
      RUN_ARGS=
    fi


    TEMP_TAG=docker-build-and-run-temp

    docker rm -f $TEMP_TAG 2>/dev/null
    printf "${TERM_GREEN}Building Docker container (${TERM_BLUE}docker build $BUILD_ARGS${TERM_GREEN})${TERM_NC}\n" \
    && docker build --tag $TEMP_TAG $BUILD_ARGS \
    && printf "${TERM_GREEN}Running Docker container (${TERM_BLUE}docker run $RUN_ARGS $RUN_COMMAND${TERM_GREEN})${TERM_NC}\n" \
    && docker run --rm -it $RUN_ARGS --label $TEMP_TAG $TEMP_TAG $RUN_COMMAND
}
Scott Rippey
la source
0

Vous pouvez également faire docker buildet diriger le nom de l'image vers laquelle il sort docker run:

docker build . | tail -n1 | cut -d' ' -f3 | xargs -I{} docker run {}
  • docker build vous donnera un texte sur plusieurs lignes ... Successfully built 18e77bc0d83a
  • vous obtenez la dernière ligne avec tail -n1
  • diviser par ' 'et obtenir 3rd mot aveccut -d' ' -f3
  • passer comme argument à runavecxargs -I{} docker run {}
Viacheslav Shalamov
la source
ajoutez | tee /dev/ttyaprès docker build .pour obtenir la sortie complète!
oliverpool
0

Pour tous ceux qui recherchent une solution réutilisable, vous pouvez installer ce plugin docker que j'ai créé: https://github.com/stasmihailov/docker-script

Ensuite, vous pouvez créer et exécuter un Dockerfile comme suit:

docker script ./Dockerfile
Denis Babochenko
la source