У меня есть веб-сервис Python + MySQL, работающий на дроплете Digital Ocean в производстве. Когда я обновляю код в проекте на своем локальном компьютере, я хочу, чтобы изменения происходили и в дроплете (в производстве). Поэтому я делаю следующее для развертывания:
$ ssh [email protected]
# cd project
# git pull
# docker-compose down
# docker-compose build
# docker-compose up -d
После этого моя база данных пуста. В нем нет ни одной из моих таблиц. Как я могу обновить код, который работает, но не потерять данные?
.
├── 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
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
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"]
# 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
Что это на самом деле делает с вашей базой данных, вы используете расплывчатые слова, такие как kill и nuke? Если вы правильно определили том, он не должен потерять данные при резервном копировании.
Я понятия не имею, что он делает с ним. Я просто могу сказать, что таблиц больше не существует (база данных существует, но она совершенно пуста)
Я думаю, что он полностью повторно инициализирует его. Таким образом, он перезаписывает том новым. Но это чистое предположение.
«Вы правильно определили том, тогда он не должен потерять данные при резервном копировании» - как мне правильно определить том? Я опубликовал все, что сделал.
Ну, в вашем объявлении тома есть два двоеточия, что, насколько я знаю, не является правильным синтаксисом, но я могу ошибаться.
Можете ли вы опубликовать свой файл start.sh, возможно, он делает перезапись. Если у вас все еще есть база данных, но нет таблиц, то я не думаю, что это проблема объема. Какой-то ваш код, вероятно, стирает его.
Хахахах, нашел. Я вообще не использовал базу данных MySQL ?. Я использовал локальную базу данных контейнера sqlite. Конечно, этого тогда уже не было. Я пробегусь по комментариям/вопросу, чтобы потом не запутаться.






mkdir /data/mysql
docker ps | grep mysql
docker cp <container_id>:/var/lib/mysql /data/mysql
volumes:
- ./db:/docker-entrypoint-initdb.d/:ro
- /data/mysql:/var/lib/mysql
Это не решает мою проблему. Когда я делаю эти изменения, а затем перехожу к рабочему процессу «вниз, сборка, вверх», я все равно теряю свои данные.
Для подтверждения: БД MySQL по-прежнему является частью docker-compose, верно? Итак, «запустить mysql в докере» означает docker-compose up db? Что означает «перезапустить все» как команду?
Если вы просто хотите обновить контейнер app, не касаясь контейнера db, почему бы и нет?
docker-compose down app
docker-compose up app
В этом случае вы просто перестраиваете свой app контейнер, не касаясь db контейнера.
А также рекомендуется сохранять ваши контейнеры без гражданства. Храните данные mysql на локальном компьютере, как предлагает Qteb.
Спасибо.
Будет ли это фактически перестраивать контейнер приложения? Или он просто выключит его/запустит снова тот же контейнер?
Он отключает все, например, контейнер, образ, том и сеть, и снова перезагружается. Это рекомендуемый способ. Перейдите по этой ссылке для получения информации stackoverflow.com/questions/41322541/…
Так что, думаю, на практике я буду называть это как docker-compose down app && docker-compose up -d app
Это сохраняет данные, но не обновляет контейнер. Я только что попробовал.
он не обновляет контейнер? Мы все еще говорим о контейнере приложений?
Ну не помогло. Как я уже писал, он НЕ обновлял код. Также docker-compose stop app && docker-compose up -d app не обновил код.
Да, я говорю о контейнере приложения.
docker-compose down app && docker-compose up -d app следует перезапустить контейнер. docker-compose stop app не изменит код
Вы, ребята, забыли сборку docker-compose?
docker-compose up создает изображение, если оно еще не существует.
Выяснил, что проблема была в другом. Не могли бы вы добавить некоторую информацию о томах (например, в чем разница между «томами:» в службе и «томами:» на том же уровне, что и «службы:»? Когда тома создаются/уничтожаются?). Если вы добавите это, я дам вам награду и приму ваш ответ.
Это просто. Внешние тома похожи на глобальные. Их можно повторно использовать с другими службами, а также по имени. Если вам не нужен многоразовый том, не называйте его. Просто дайте путь. И с точки зрения docker-compose, когда контейнер инициируется, создаются тома, если они еще не выходят. Они не уничтожаются по команде stop. Они уничтожаются по команде down.
Вы должны создать именованный том для своей базы данных, например
version: '3'
services:
mysql:
image: mysql:5.7
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
Теперь вы можете безопасно запускать docker-compose stop или docker-compose down без потери данных на томе mysql_data. Только когда вы запустите docker-compose down -v, он также удалит громкость.
Вы можете увидеть все ваши именованные тома, запустив docker volume ls
Краткое примечание: docker-compose предназначен для разработки, а не для производства. Возможно, вы захотите рассмотреть другую стратегию.
«Возможно, вы захотите рассмотреть другую стратегию». Не могли бы вы добавить сюда несколько примеров?
Судя по этой странице docs.docker.com/compose/production, можно запускать ее с docker-compose. Другие решения, такие как docker swarm и kubernetes, более сложны и, вероятно, немного излишни в вашем случае.
Во-первых, вам нужно иметь именованный том для сохранения данных, как упоминал Крис.
Затем создайте образ кода и запустите контейнер из нового образа по отдельности:
docker-compose up -d --no-deps --build app
Флаг --no-deps не запускает никакие связанные службы. Связанные службы запускаются по умолчанию. Это уничтожит ваши данные (например, когда вы это сделали docker-compose up -d --build app).
Использованная литература:
Чтобы сохранить базу данных mysql или другие данные базы данных, убедитесь, что ваш docker-compose.yml будет выглядеть так: 1.если вы хотите использовать Dockerfile
version: '3.1'
services:
php:
build:
context: .
dockerfile: Dockerfile
ports:
- 80:80
volumes:
- ./src:/var/www/html/
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- mysql-data:/var/lib/mysql
adminer:
image: adminer
restart: always
ports:
- 8080:8080
volumes:
mysql-data:
2. если вы хотите использовать свой образ вместо Dockerfile, ваш docker-compose.yml будет выглядеть так:
version: '3.1'
services:
php:
image: php:7.4-apache
ports:
- 80:80
volumes:
- ./src:/var/www/html/
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- mysql-data:/var/lib/mysql
adminer:
image: adminer
restart: always
ports:
- 8080:8080
volumes:
если вы хотите хранить или сохранять данные mysql, тогда не забудьте добавить две строки в ваш docker-compose.yml
volumes:
- mysql-data:/var/lib/mysql
а также
volumes:
mysql-data:
после этого используйте эту команду
docker-compose up -d
теперь ваши данные будут постоянными и не будут удалены даже после использования этой команды
docker-compose down
дополнительно: - но если вы хотите удалить все данные, вы будете использовать
docker-compose down -v
плюс вы можете проверить список данных вашей базы данных с помощью этой команды
docker volume ls
DRIVER VOLUME NAME
local 35c819179d883cf8a4355ae2ce391844fcaa534cb71dc9a3fd5c6a4ed862b0d4
local 133db2cc48919575fc35457d104cb126b1e7eb3792b8e69249c1cfd20826aac4
local 483d7b8fe09d9e96b483295c6e7e4a9d58443b2321e0862818159ba8cf0e1d39
local 725aa19ad0e864688788576c5f46e1f62dfc8cdf154f243d68fa186da04bc5ec
local de265ce8fc271fc0ae49850650f9d3bf0492b6f58162698c26fce35694e6231c
local phphelloworld_mysql-data
Может быть напрямую связано с stackoverflow.com/q/56486763/562769