Короткая версия
Это работает
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 -
обрабатывайте все, что получаете от стандартного ввода