【问题标题】:How can I keep my database, but change the code in docker-compose?如何保留我的数据库,但更改 docker-compose 中的代码?
【发布时间】:2019-06-03 20:34:41
【问题描述】:

我有一个 Python+MySQL 网络服务在生产中的 Digital Ocean 液滴上运行。当我在本地机器上更新项目中的代码时,我希望更改也发生在 droplet(生产中)中。所以我做了以下部署:

$ ssh root@12.34.56.78
# 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

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

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 之类的模糊词?如果您正确定义了卷,那么它在备份时不应丢失任何数据
  • 我不知道它对它做了什么。我只能说这些表不再存在(数据库确实存在,但它完全是空的)
  • 我最好的猜测是它完全重新初始化了它。因此,它会用新的卷覆盖该卷。但这纯粹是猜测。
  • “你已经正确定义了卷,那么当它恢复时它不应该丢失任何数据” - 我如何正确定义卷?我已经发布了我所做的一切。

标签: mysql docker-compose devops


【解决方案1】:

你必须像这样为你的数据库创建一个命名卷

version: '3'

services:    
  mysql:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

现在您可以安全地运行docker-compose stopdocker-compose down,而不会丢失mysql_data 卷上的数据。只有当您运行 docker-compose down -v 时,它才会删除该卷。

您可以通过运行docker volume ls查看所有命名卷

快速说明:docker-compose 是为开发而非生产而设计的。您可能需要考虑不同的策略。

【讨论】:

  • “您可能需要考虑不同的策略。”你能在这里添加一些例子吗?
  • 根据此页面docs.docker.com/compose/production 似乎可以使用docker-compose 运行它。 docker swarm 和 kubernetes 等其他解决方案更复杂,在您的情况下可能有点矫枉过正
【解决方案2】:
  1. 在主机上创建文件夹
mkdir /data/mysql
  1. 在 docker 中启动您的 MySQL
  2. 将数据库从正在运行的 MySQL 容器复制到主机
docker ps | grep mysql
docker cp <container_id>:/var/lib/mysql /data/mysql
  1. 在您的 docker-compose.yml 中进行更改
    volumes:
      - ./db:/docker-entrypoint-initdb.d/:ro
      - /data/mysql:/var/lib/mysql
  1. 重新启动所有。

【讨论】:

  • 这并不能解决我的问题。当我进行这些更改然后进入“向下、构建、向上”的工作流程时,我仍然会丢失我的数据。
  • 确认:MySQL DB 仍然是 docker-compose 的一部分,对吧?所以“在docker中启动mysql”是指docker-compose up db?命令中的“全部重启”是什么意思?
【解决方案3】:

如果您只想更新app 容器而不接触db 容器,为什么不这样做

docker-compose down app
docker-compose up app

在这种情况下,您只是重建您的 app 容器,而不接触 db 容器。

还建议保持容器无状态。按照Qteb 的建议将您的mysql 数据存储在本地机器上。

谢谢。

【讨论】:

  • 这真的会重建应用容器吗?还是只是将其关闭/再次启动同一个容器?
  • 它会关闭容器、镜像、卷和网络等所有内容,然后重新启动。这是一种推荐的方式。请点击此链接获取信息stackoverflow.com/questions/41322541/…
  • 所以我想在实践中我会称之为docker-compose down app &amp;&amp; docker-compose up -d app
  • 这会保留数据,但不会更新容器。我刚试过。
  • 它不更新容器?我们还在谈论应用容器吗?
【解决方案4】:

首先,您需要有一个 命名卷,如 Chris 所述,用于数据持久性。

然后,构建代码镜像并从新镜像单独启动容器:

docker-compose up -d --no-deps --build app

--no-deps 标志不会启动任何链接服务。链接服务默认启动。这会破坏你的数据(就像你做docker-compose up -d --build app时一样)。

参考文献:

【讨论】:

    【解决方案5】:

    要存储 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
    

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 2019-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多