Заполнение образа Postgres Docker во время сборки (не работает) - PullRequest
0 голосов
/ 05 марта 2019

Я хочу подготовить пользовательское изображение (на основе официального Postges image ) с двумя задачами:

  1. Загрузить данные (например, получить файл CSV с помощью wget),
  2. Загрузка данных в базу данных (создание таблиц, вставки).

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

Я знаю, как выполнить шаг 1 (загрузка данных) во время построения образа, но я не знаю, как загрузить данные в базу данных во время построения образа вместо запускаконтейнер (шаг 2).

Пример:

(загрузка - во время построения образа, загрузка - во время работы контейнера)

Dockerfile:

FROM postgres:10.7

RUN  apt-get update \
  && apt-get install -y wget \
  && rm -rf /var/lib/apt/lists/* 

COPY download.sh /download.sh
RUN /download.sh

download.sh:

#!/bin/bash

cd /docker-entrypoint-initdb.d/
wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/northwindextended/northwind.postgre.sql

Для загрузки данных я запускаю скрипт самостоятельно.Для загрузки данных я использую утилиту сценариев инициализации из официального образа Postgres.

Образ сборки:

docker build -t mydbimage .

Запуск изображения:

docker run --name mydbcontainer -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d mydbimage 

После запуска вы можете увидеть, сколько времени занимает загрузка данных:

docker logs mydbcontainer

Этот пример набора данных небольшой, но с большим, долго работающим контейнером неудобно.

1 Ответ

0 голосов
/ 05 марта 2019

Вы можете проанализировать вышестоящий Dockerfile и docker-entrypoint.sh и просто выбрать нужные фрагменты для инициализации вашей базы данных:

FROM postgres:10.7

ENV PGDATA /var/lib/postgresql/datap-in-image
RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)

RUN set -x \
  && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
  && wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/northwindextended/northwind.postgre.sql \ 
    -O /docker-entrypoint-initdb.d/northwind.postgre.sql \
  && cp ./docker-entrypoint.sh ./docker-entrypoint-init-only.sh \
  && sed -ri '/exec "\$@"/d' ./docker-entrypoint-init-only.sh \
  && ./docker-entrypoint-init-only.sh postgres \
  && rm ./docker-entrypoint-initdb.d/northwind.postgre.sql ./docker-entrypoint-init-only.sh \
  && apt-get purge -y --auto-remove ca-certificates wget

Build,запустить и проверить:

docker build -t mydbimage .

# bring up the database
docker run --rm mydbimage --name pgtest

# run this in another terminal to check for the imported data 
docker exec -ti pgtest psql -v ON_ERROR_STOP=1 --username "postgres" --no-password --dbname postgres --command "\d"

Предостережения:

  • При этой настройке пароль отсутствует для базы данных.Вы можете добавить его во время сборки, но тогда оно будет сохранено в образе.Вы должны принять меры предосторожности, чтобы никто не получил доступ к вашему изображению.В зависимости от вашей настройки это может быть трудно достичь, может быть, даже невозможно.
  • Вторая проблема заключается в том, что записи в вашу базу данных эфемерны .Во время сборки нет тома для сохранения импортированных данных.Вот почему PGDATA заменяется на каталог, который не объявлен как том.

По сути, это причины, по которым импорт обрабатывается при запуске контейнера, а не во время сборки в обратном хранилище.Если у вас есть не секретные данные, которые используются только для чтения, все равно имеет смысл импортировать их во время сборки, чтобы сэкономить время и упростить их обработку во время запуска контейнера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...