Невозможно выполнить запросы из файла, используя psql командную строку с docker exec - PullRequest
2 голосов
/ 08 января 2020

У меня есть файл bash, который должен перевести контейнер postgres docker в оперативный режим, а затем запустить файл .sql для создания баз данных. Но он выдает ошибку.

psql: error: provision-db.sql: No such file or directory

Я проверил путь, и файл существует на том же уровне этого сценария bash. Ниже приводится содержимое моего bash файла.

#!/usr/bin/env bash

docker-compose up -d db

# Ensure the Postgres server is online and usable
until docker exec -i boohoo.postgres pg_isready --host="${POSTGRES_HOST}" --username="${POSTGRES_USER}"
do
    echo "."
    sleep 1
done

docker exec -i boohoo.postgres psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -a -q -f provision-db.sql

И это файл provision-db.sql.

DROP DATABASE "boo-hoo";
CREATE DATABASE "boo-hoo";
GRANT ALL PRIVILEGES ON DATABASE "boo-hoo" TO postgres;

Это часть docker-compose.yml

version: '3.3'

services:
  db:
    container_name: boohoo.postgres
    hostname: postgres.boohoo
    image: postgres
    ports:
      - "15432:5432"
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"

Ответы [ 2 ]

1 голос
/ 08 января 2020

Короткая версия

Это работает

cat provision-db.sql | docker exec -i boohoo.postgres bash -c 'psql -U ${POSTGRES_USER} -w -a -q -f -'

Длинная версия

несколько вещей здесь

1) почему следующая команда не находит provision-db.sql?

docker exec -i boohoo.postgres psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -a -q -f provision-db.sql

, потому что положение-db. sql находится на вашем хосте, а не в вашем контейнере. Поэтому, когда вы выполняете команду psql внутри контейнера, он не может найти файл

2) Почему не сработало мое первое решение?

cat provision-db.sql | docker exec -i boohoo.postgres psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -a -q -f - должно выполнить трюк в предположении provision-db. sql

Это связано с тем, что переменные ${POSTGRES_USER} и ${POSTGRES_PASSWORD} оцениваются на вашем хост-компьютере, и я думаю, что они там не установлены. Кроме того, я забыл указать флаг -w, чтобы избежать запроса пароля

3) Почему это работает?

cat provision-db.sql | docker exec -i boohoo.postgres bash -c 'psql -U ${POSTGRES_USER} -w -a -q -f -'

Хорошо, давайте go пройдем его шаг за шагом ,

Сначала мы печатаем содержимое provision-db.sql, которое находится на хост-компьютере, в стандартный вывод и передаем его следующей команде через |.

docker-exec выполняет команду в указанном контейнере (boohoo.postgres). Указывая флаг -i, мы разрешаем stdin с вашего хоста на go вводить stdin в контейнер <- это важно. </p>

В контейнере мы выполняем bash -c, который является просто оболочкой, чтобы избежать оценивая переменные bash на хосте. Нам нужны переменные из контейнера, и, поместив их в одинарные кавычки, мы можем сделать это.

docker-exec boohoo.postgres bash -c "echo $POSTGRES_USER"

вычисляет переменную хоста env с именем POSTGRES_USER.

docker-exec boohoo.postgres bash -c "echo $POSTGRES_USER"

оценивает переменную контейнера env с именем POSTGRES_USER.

Далее нужно просто получить нашу команду postgres по порядку.

psql -U ${POSTGRES_USER} -w -a -q -f -

-U указывает, что пользователь
-w не запрашивает пароль
-q делайте это тихо
-f - обрабатывайте все, что получаете от стандартного ввода

0 голосов
/ 08 января 2020

-f является опцией для psql, а не для docker exec, и psql работает внутри контейнера, поэтому он может получить доступ к файлу, только если он находится внутри контейнера.

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