Docker Compose - 如何存储数据库数据?

27

我是docker的新手,正在使用docker-compose开发项目。从文档中我了解到应该使用数据容器来保持数据的持久性,但是使用docker-compose时我无法做到这一点。 每当我执行docker-compose down时,它会删除数据库中的数据,但通过执行docker-compose stop则不会删除数据。可能这是因为我没有创建命名数据卷,而docker-compose down几乎不会删除所有容器。因此,我尝试给容器命名,但遇到了错误。 请查看我的yml文件:

version: '2'
services: 
   data_container:
     build: ./data
     #volumes:
     #  - dataVolume:/data
  db:
    build: ./db
    ports:
      - "5445:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres
    #   - PGDATA=/var/lib/postgresql/data/pgdata
    volumes_from:
     # - container:db_bus
       - data_container
  geoserver:
    build: ./geoserver
    depends_on:
      - db
    ports:
      - "8004:8080"
    volumes:
      - ./geoserver/data:/opt/geoserverdata_dir

  web:
    build: ./web
    volumes:
      - ./web:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
    command: python manage.py runserver 0.0.0.0:8000

  nginx:
    build: ./nginx
    ports:
      - "83:80"
    depends_on:
      - web

数据容器的Docker文件如下:

FROM stackbrew/busybox:latest
MAINTAINER Tom Offermann <tom@offermann.us>

# Create data directory
RUN mkdir /data

# Create /data volume
VOLUME /data

我尝试过这样做,但是通过执行 docker-compose down 命令,数据被删除了。我尝试给 data_container 命名如您所见的注释行,但它抛出了以下错误:

ERROR: Named volume "dataVolume:/data:rw" is used in service "data_container" but no declaration was found in the volumes section.

现在我正在做的是创建一个独立的数据容器,并将其放置在 dbvolumes_from 值中。它运行良好,即使执行 docker-compose down 后也不会删除任何数据。

我的问题:

  • 使用 docker-compose 创建能够存储数据库数据并正确使用它们的最佳方法是什么?

  • 我对所采用的方法并不满意,即通过创建一个独立的数据容器。您有什么想法吗?


1
你不想使用命名卷来存储数据吗?像这样 volumes: - /data/mydata:/var/lib/postgresql/data/pgdata,这是优先于数据容器卷的首选方法。 - ldg
我尝试过这样做,但是它抛出了错误:ERROR: Named volume "dataVolume:/data:rw" is used in service "data_container" but no declaration was found in the volumes section. 我也对使用这种方法进行数据可移植性很感兴趣。 - Salman Ghauri
3个回答

31

docker-compose down

执行以下操作:

停止容器并删除由up创建的容器、网络、卷和镜像

因此,您正在经历的行为是预期的。

使用docker-compose stop来关闭使用docker-compose文件创建的容器,但不要删除它们的卷。

其次,在Docker Compose版本2中不需要data-container模式。因此,请删除它并只使用

  db:
    ...
    volumes:
       - /var/lib/postgresql/data

我如何使用这种方法备份数据或使其便携? - Salman Ghauri
3
数据已经在 Docker 主机的卷中了。你需要使用一个能够转储数据的工具来访问该卷,例如 docker-compose exec POSTGRES_CONTAINER pg_dump | bzip2 > path/on/host/mydb-dump-`date "+%Y%m%d%H%M%S"`.sql.bz2 - lukeaus
这非常有帮助。在尝试备份数据时出现了一个错误,即: pg_dump:[archiver(db)]连接到数据库“root”失败:FATAL:角色“root”不存在 你能帮我解决这个问题吗? - Salman Ghauri
@SalmanGhauri,可能偏离了主题 - 如果您继续遇到问题,请尝试发布一个新的问题。 - lukeaus
这个问题通过使用命名卷得以解决。如果您使用命名卷,执行 docker-compose down 不会销毁数据。 - Salman Ghauri

15

docker-compose down 停止容器,但也会移除它们(包括所有内容:网络等)。

请使用 docker-compose stop 代替。

我认为使用命名卷是使用 docker-compose 存储数据库数据的最佳方案:

version: '2'
services:

  db: #https://hub.docker.com/_/mysql/
    image: mysql
    volumes:
      - "wp-db:/var/lib/mysql:rw"
    env_file:
      - "./conf/db/mysql.env"

volumes:
  wp-db: {}

这里将创建一个名为“wp-db”的命名卷(如果不存在),并将其挂载到/var/lib/mysql(以读写模式,即默认模式)中。这是数据库存储其数据的位置(针对mysql镜像)。

如果已经存在该命名卷,则会使用它而不进行创建。

启动时,mysql镜像会查看/var/lib/mysql目录(您的卷)中是否有数据库以供使用。

您可以在此处查看docker-compose文件参考以获取更多信息:https://docs.docker.com/compose/compose-file/#/volumes-volume-driver


3

如果您想使用Dockerfile存储数据库数据,请确保您的docker-compose.yml文件如下所示:

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:

如果您想使用自己的镜像而不是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

and

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接