Сборка докера игнорирует существующие данные и конфигурацию базы данных, хранящиеся в моем томе

У меня есть следующее 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

Как я могу решить проблему и сохранить схему базы данных и данные каждый раз, когда мне нужно перестроить систему.

1 ответ

Решение

Почему данные базы данных теряются?

Я пробовал разные вещи и сравнивал образ MySQL с образом PostgreSQL. Теперь я нашел проблему. При использовании именованного тома или подключенного тома нет никакой разницы, но для сохранения данных базы данных необходимо связать правильную папку на контейнере:

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> чтобы получить точку монтирования на хост-машине.

Другие вопросы по тегам