docker 构建忽略存储在我的卷中的现有数据和数据库配置

docker build ignore existing data and database config stored in my volume

我有以下 docker-compose.yml 文件:

# some other services here
......
......    

#############################
# Setup PostgreSQL container
#############################

  service-postgres:
    image: postgres:10-alpine
    container_name: service-postgres-server
    volumes:
      - ./data/postgres:/var/lib/postgresql
      - ./docker/initdb:/docker-entrypoint-initdb.d
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_PASSWORD=root
      - POSTGRES_DB=db_name

每次我尝试重建容器时 运行 强制重建我丢失了我的数据库架构和数据:

docker-compose up -d --force-recreate --build

但是当我在 data/postgres 下查看时,我发现文件和设置在那里:

-$ ls data/postgres
PG_VERSION           pg_commit_ts         pg_ident.conf        pg_notify            pg_snapshots         pg_subtrans          pg_wal               postgresql.conf
base                 pg_dynshmem          pg_logical           pg_replslot          pg_stat              pg_tblspc            pg_xact              postmaster.opts
global               pg_hba.conf          pg_multixact         pg_serial            pg_stat_tmp          pg_twophase          postgresql.auto.conf postmaster.pid

每次需要重建系统时,我该如何解决这个问题并保留我的数据库架构和数据。

为什么数据库数据丢失了?

我尝试了不同的方法并比较了容器上的 MySQL image with the PostgreSQL image. Now I found the problem. There is no difference using a named volume or a mounted volume but you have to bind the correct folder 来持久化数据库数据:

services:
  service-postgres:
    image: postgres:10-alpine
    container_name: service-postgres-server
    volumes:
      - ./data/postgres/data:/var/lib/postgresql/data
      - ./docker/initdb:/docker-entrypoint-initdb.d
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: root
      POSTGRES_DB: db_name

您必须将 /var/lib/postgresql/data 文件夹而不是 /var/lib/postgresql 文件夹绑定到主机。您还可以将两个文件夹都挂载到主机(data 文件夹和 postgres 文件夹),但您需要 data 文件夹才能保留。在 MySQL 图像上,您只需要 /var/lib/mysql 文件夹即可将数据保存在主机上。

仅供比较:MySQL图片:

services:
  service-mysql:
    image: mysql:5.7
    container_name: service-mysql-server
    volumes:
      - ./data/mysql-db:/var/lib/mysql
      - ./docker/initdb:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"
    environment:
      MYSQL_PASSWORD: root
      MYSQL_DATABASE: db_name

通过上述配置,MySQL 数据将保存在主机上。

使用命名卷:

services:
  service-postgres:
    image: postgres:10-alpine
    container_name: service-postgres-server
    volumes:
      - postgresql-data:/var/lib/postgresql/data
      - ./docker/initdb:/docker-entrypoint-initdb.d
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: root
      POSTGRES_DB: db_name

volumes:
  postgresql-data:

对于命名卷,您可以使用 docker-compose down -v 将其删除。您不能使用 docker-compose down 命令删除已安装的卷。

您可以在 docker volume ls 的卷列表中找到该卷。您还可以使用 docker volume inspect <volume-name> 检查卷以获取主机上的安装点。