Comment exécuter une commande une fois dans Docker composez
Donc je suis en train de travailler sur un panneau de composer le fichier à déployer mon serveur web. Mon serveur utilise mongo, j'ai donc ajouté un volume de données de conteneur et les mongo de service dans le panneau composition.
Ensuite, j'ai écrit un Dockerfile afin de construire mon projet, et enfin l'exécuter.
Cependant, il y a une autre étape qui doit être fait. Une fois que mon projet a été compilé, j'ai lancer la commande suivante:
./my-project -setup
Cela va ajouter certaines informations nécessaires à la base de données, et les informations ne doit être ajouté une fois.
Je ne peux pas cependant d'ajouter cette étape sur le Dockerfile (dans le processus de construction) parce que mongo doit être déjà commencé.
Alors, comment puis-je y parvenir? Même si je redémarre le serveur, puis exécutez de nouveau docker-compose up
je ne veux pas que cette commande soit exécutée de nouveau.
Je pense que je suis pas certains Docker compréhension, parce que je n'ai pas vraiment tout comprendre sur les données de volume de conteneurs (sont-ils simplement arrêté conteneurs monter un volume?).
Aussi, si je redémarre le serveur, puis exécutez docker-compose up
, les commandes qui seront exécutées? Est-ce juste de commencer le même conteneur qui a été arrêtée aujourd'hui avec le CMD?
En tout cas, voici mon menu fixe-composer.yml:
version: '2'
services:
mongodata:
image: mongo:latest
volumes:
- /data/db
command: --break-mongo
mongo:
image: mongo:latest
volumes_from:
- mongodata
ports:
- "28001:27017"
command: --smallfiles --rest --auth
my_project:
build: .
ports:
- "6060:8080"
depends_on:
- mongo
- mongodata
links:
- mongo
Et voici mon Dockerfile pour construire mon projet image:
FROM golang
ADD . /go/src/my_project
RUN cd /go/src/my_project && go get
RUN go install my_project
RUN my_project -setup
ENTRYPOINT /go/bin/my_project
EXPOSE 8080
source d'informationauteur Ivan
Vous devez vous connecter pour publier un commentaire.
Je suggère d'ajouter un point d'entrée-script à votre conteneur; dans ce point d'entrée-script, vous pouvez vérifier si la base de données a été initialisé, et si elle n'est pas le cas, effectuez les étapes requises.
Comme vous l'avez remarqué dans votre question, l'ordre dans lequel les services /les conteneurs sont démarrés ne doit pas être pris pour acquis, il est donc possible que votre conteneur de l'application est démarrée avant le conteneur de base de données, de sorte que le script doit en tenir compte.
Par exemple, avoir un regard sur l'officiel de WordPress image, qui effectue une seule fois à l'initialisation de la base de données dans son point d'entrée-script. Le script tente de se connecter à la base de données (et les tentatives si la base de données ne peut pas être contacté (encore)), et vérifie si l'initialisation est nécessaire; https://github.com/docker-library/wordpress/blob/df190dc9c5752fd09317d836bd2bdcd09ee379a5/apache/docker-entrypoint.sh#L146-L171
NOTE
Je remarque que vous avez créé un "données uniquement conteneur" pour attacher votre volume. Depuis le panneau de 1,9, docker a la gestion du volume, y compris de nommage des volumes. De ce fait, vous n'avez plus besoin d'utiliser les données "seulement" des conteneurs.
Vous pouvez supprimer les données uniquement le récipient de votre fichier composer, et de changer votre mongo service à ressembler à quelque chose comme cela;
Cela devrait créer un nouveau volume, nommé
mongodata
si elle n'existe pas, ou ré-utiliser le volume de ce nom. Vous pouvez dresser la liste de tous les volumes à l'aide dedocker volume ls
et supprimer un volume avecdocker volume rm <some-volume>
si vous n'en avez plus besoinVous pouvez essayer d'utiliser
ONBUILD
enseignement:La
ONBUILD
instruction ajoute à l'image d'un déclencheur d'instruction à être exécutée à une date ultérieure, lorsque l'image est utilisée comme base pour construire un autre. Le déclencheur sera exécuté dans le contexte de l'aval de construire, comme si elle avait été inséré immédiatement après leFROM
instruction dans l'avalDockerfile
.Toute accumulation d'instruction peut être enregistré comme un déclencheur.
Ceci est utile si vous êtes à la construction d'une image qui sera utilisée comme une base pour construire d'autres images, par exemple une application en environnement de construction ou un démon qui peut être personnalisé avec une configuration spécifique à l'utilisateur.
Par exemple, si votre image est une réutilisables Python application builder, il aura besoin de code source de l'application pour être ajouté dans un répertoire particulier, et il peut avoir besoin d'un script de compilation d'être appelé après. Vous ne pouvez pas simplement appeler
ADD
etRUN
maintenant, parce que vous n'avez pas encore accès au code source de l'application, et elle sera différente pour chaque génération de l'application. Vous pouvez tout simplement vous fournir les développeurs d'applications avec un passe-partoutDockerfile
à copier-coller dans leur application, mais qui est inefficace, et sujettes à erreur difficile à mettre à jour car il se mélange avec l'application du code spécifique.La solution est d'utiliser
ONBUILD
de registre d'instructions à exécuter plus tard, au cours de la prochaine phase de développement.Voici comment cela fonctionne:
ONBUILD
instruction, le constructeur ajoute un élément déclencheur pour les métadonnées de l'image en cours de construction. L'instruction n'a pas d'autre incidence sur la version actuelle.OnBuild
. Ils peuvent être inspectés avec lesdocker inspect
commande.FROM
instruction. Dans le cadre du traitement de laFROM
de l'instruction, de l'aval du générateur de rechercheONBUILD
déclencheurs, et les exécute dans le même ordre qu'ils ont été enregistrés. Si l'un des déclencheurs de l'échec, laFROM
instruction est abandonnée qui à son tour provoque l'échec. Si tous les déclencheurs réussir, leFROM
l'instruction est terminée et que le construire continue comme d'habitude.Votre application a besoin d'un état initial pour le travail. Cela signifie que vous devez:
Vous pouvez écrire le programme pour la vérification de la base de données actuelle de l'état (ici, je vais utiliser des script bash, mais il peut être tout autre programme de langue):
Dans mon cas, si le script renvoie 0 (succès de statut de sortie), puis
setup
commande sera appelée.