2
votes

Comment puis-je conserver ma base de données, mais modifier le code dans docker-compose?

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?

Mon code

Structure du projet

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"]

docker -compose.yml

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

Dockerfile

.
├── 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

Ce que j'ai essayé

$ ssh root@12.34.56.78
# cd project
# git pull
# docker-compose down
# docker-compose build
# docker-compose up -d


9 commentaires

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.


5 Réponses :


2
votes
  1. Créer un dossier sur la machine hôte
  2.     volumes:
          - ./db:/docker-entrypoint-initdb.d/:ro
          - /data/mysql:/var/lib/mysql
    
    1. Démarrez votre MySQL dans le docker
    2. Copier la base de données du conteneur MySQL en cours d'exécution vers la machine hôte
    docker ps | grep mysql
    docker cp <container_id>:/var/lib/mysql /data/mysql
    
    1. Apportez des modifications à votre docker-compose.yml
    mkdir /data/mysql
    
    1. Tout redémarrer.

2 commentaires

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?



0
votes

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 .


12 commentaires

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 .



6
votes

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.


2 commentaires

"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



0
votes

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:


0 commentaires

0
votes

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


0 commentaires