J'ai un webservice Python + MySQL fonctionnant sur un droplet Digital Ocean en production. Lorsque j'ai mis à jour le code du projet sur ma machine locale, je souhaite que les modifications aient également lieu dans le droplet (en production). Je fais donc ce qui suit pour déployer:
# This killed my data: $ docker-compose up -d --build app # This did NOT update the code in app: # 1 $ docker-compose stop app && docker-compose up -d app # 2 $ docker-compose up -d --no-deps --build app
Après cela, ma base de données est vide. Il ne contient aucune de mes tables. Comment puis-je mettre à jour le code en cours d'exécution sans perdre les données?
FROM python:3.7-slim # Copy projects code RUN apt-get update && apt-get install -y git COPY . /opt/app WORKDIR /opt/app RUN pip install -e . --no-cache-dir # Start app ENV ENV=prod EXPOSE 5000 ENTRYPOINT ["sh", "start.sh"] CMD ["/opt/app/start.sh"]
version: "2" services: db: image: mysql:5.7 ports: - "32000:3306" environment: MYSQL_DATABASE: *** MYSQL_ROOT_PASSWORD: *** volumes: - ./db:/docker-entrypoint-initdb.d/:ro app: build: ./web links: - db ports: - "5000:5000" environment: MYSQL_PORT: 32000
. âââ db âââ docker-compose.yml âââ web âââ Dockerfile âââ project â  âââ app.py â  âââ __init__.py â  âââ blueprint1 â  âââ blueprint2 â  âââ models.py â  âââ static â  âââ templates â  âââ _version.py âââ Makefile âââ migrations âââ README.md âââ setup.cfg âââ setup.py âââ start.sh âââ tests âââ tox.ini
$ ssh root@12.34.56.78 # cd project # git pull # docker-compose down # docker-compose build # docker-compose up -d
5 Réponses :
volumes: - ./db:/docker-entrypoint-initdb.d/:ro - /data/mysql:/var/lib/mysql
docker ps | grep mysql docker cp <container_id>:/var/lib/mysql /data/mysql
mkdir /data/mysql
Cela ne résout pas mon problème. Lorsque je fais ces modifications et que je passe au flux de travail «down, build, up», je perds toujours mes données.
Pour confirmer: la base de données MySQL fait toujours partie de docker-compose, non? Donc "démarrer mysql dans docker" signifie docker-compose up db
? Que signifie «tout redémarrer» en tant que commande?
Si vous souhaitez simplement mettre à jour le conteneur app
sans toucher le conteneur db
pourquoi ne pas faire
docker-compose down app docker-compose up app
Dans ce cas, vous êtes simplement reconstruire votre conteneur app
sans toucher le conteneur db
.
Et il est également recommandé de garder vos conteneurs sans état. Stockez vos données mysql sur la machine locale comme le suggère Qteb
.
Merci .
Cela reconstruira-t-il réellement le conteneur d'application? Ou va-t-il simplement l'arrêter / redémarrer le même conteneur?
Il arrête tout comme le conteneur, l'image, le volume et le réseau et redémarre à nouveau. C'est une manière recommandée. Veuillez suivre ce lien pour plus d'informations stackoverflow.com/ questions / 41322541 /…
Donc je suppose qu'en pratique, j'appellerai cela docker-compose down app && docker-compose up -d app
Cela conserve les données, mais ne met pas à jour le conteneur. J'ai juste essayé.
il ne met pas à jour le conteneur? Parlons-nous toujours du conteneur d'applications?
Eh bien, cela n'a pas aidé. Comme je l'ai écrit, il n'a PAS mis à jour le code. De plus, docker-compose stop app && docker-compose up -d app
n'a pas mis à jour le code.
Oui, je parle du conteneur d'application.
docker-compose down app && docker-compose up -d app
devrait redémarrer le conteneur. l'application d'arrêt docker-compose
ne changera pas le code
Vous oubliez la construction de docker-compose?
docker-compose up
construit l'image si elle n'existe pas déjà.
J'ai découvert que le problème était ailleurs. Pourriez-vous s'il vous plaît ajouter quelques informations sur les volumes (par exemple, quelle est la différence entre "volumes:" dans un service et "volumes:" au même niveau que "services:"? Quand les volumes sont-ils créés / détruits?). Si vous ajoutez ceci, je vous donnerai la prime et accepterai votre réponse.
C'est simple. Les volumes externes sont comme des globaux. Ils sont réutilisables avec d'autres services également par leur nom. Si vous ne voulez pas de volume réutilisable, ne le nommez pas. Donnez simplement le chemin. Et en termes de docker-compose
, Lorsqu'un conteneur est lancé, des volumes sont créés s'ils ne sont pas déjà sortis. Ils ne sont pas détruits sur la commande stop
. Ils sont détruits sur commande down
.
Vous devez créer un volume nommé pour votre base de données comme ceci
version: '3' services: mysql: image: mysql:5.7 volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:
Vous pouvez maintenant exécuter en toute sécurité docker-compose stop
ou docker-compose vers le bas
sans perdre vos données sur le volume mysql_data
. Ce n'est que lorsque vous exécutez docker-compose down -v
que le volume sera également supprimé.
Vous pouvez voir tous vos volumes nommés en exécutant docker volume ls code >
Note rapide: docker-compose est conçu pour le développement et non pour la production. Vous voudrez peut-être envisager une stratégie différente.
"Vous voudrez peut-être envisager une stratégie différente." Pourriez-vous s'il vous plaît ajouter quelques exemples ici?
Selon cette page docs.docker.com/compose/production , il semble correct de l'exécuter avec docker-compose
. D'autres solutions comme docker swarm et kubernetes sont plus complexes et probablement un peu exagérées dans votre cas
Tout d'abord, vous devez avoir un volume nommé pour la persistance des données comme mentionné par Chris.
Ensuite, créez l'image de code et démarrez le conteneur à partir de la nouvelle image individuellement:
docker-compose up -d --no-deps --build app
L'indicateur --no-deps
ne démarre aucun service lié. Les services liés sont démarrés par défaut. Cela détruirait vos données (comme lorsque vous avez fait docker-compose up -d --build app
).
Références:
Pour stocker la base de données mysql ou d'autres données de base de données, assurez-vous que votre docker-compose.yml ressemblera à 1.si vous souhaitez utiliser Dockerfile
docker volume ls DRIVER VOLUME NAME local 35c819179d883cf8a4355ae2ce391844fcaa534cb71dc9a3fd5c6a4ed862b0d4 local 133db2cc48919575fc35457d104cb126b1e7eb3792b8e69249c1cfd20826aac4 local 483d7b8fe09d9e96b483295c6e7e4a9d58443b2321e0862818159ba8cf0e1d39 local 725aa19ad0e864688788576c5f46e1f62dfc8cdf154f243d68fa186da04bc5ec local de265ce8fc271fc0ae49850650f9d3bf0492b6f58162698c26fce35694e6231c local phphelloworld_mysql-data
2.si vous souhaitez utiliser votre image au lieu de Dockerfile, votre docker-compose.yml ressemblera à
docker-compose down -v
Peut être directement lié à stackoverflow.com/q/56486763/562769
Qu'est-ce que cela fait réellement à votre base de données, vous utilisez des mots vagues comme tuer et nuke? Si vous avez correctement défini le volume, il ne devrait perdre aucune donnée lors de sa sauvegarde
Je n'ai aucune idée de ce que cela lui fait. Je peux juste dire que les tables n'existent plus (la base de données existe, mais elle est complètement vide)
Ma meilleure hypothèse est qu'il le réinitialise complètement. Donc, il écrase le volume par un nouveau. Mais c'est une pure supposition.
Ma meilleure hypothèse est qu'il le réinitialise complètement. Donc, il écrase le volume par un nouveau. Mais c'est une pure supposition.
"Vous avez correctement défini le volume, il ne devrait pas perdre de données lors de sa sauvegarde" - comment définir correctement le volume? J'ai posté tout ce que j'ai fait.
Eh bien, votre déclaration de volume contient deux deux points, ce qui, pour autant que je sache, n'est pas une syntaxe correcte, mais je peux me tromper
Pouvez-vous publier votre fichier start.sh, c'est peut-être en train d'écraser. Si vous avez toujours votre base de données mais pas les tables, je ne pense pas que ce soit un problème de volume. Un de vos codes est probablement en train de l'effacer.
Hahahah, je l'ai trouvé. Je n'utilisais pas du tout la base de données MySQL 🤦. J'ai utilisé une base de données sqlite locale au conteneur. Bien sûr, ce n'était plus là. Je vais passer en revue les commentaires / la question pour m'assurer qu'elle ne prête pas à confusion par la suite.