Як створити користувача / базу даних у скрипті для Docker Postgres


213

Я намагався створити контейнер для екземпляра постгреси розвитку, створивши користувацький користувач та базу даних. Я використовую офіційне зображення докера postgres . У документації він вказує вам вставити bash-скрипт всередині /docker-entrypoint-initdb.d/папки, щоб налаштувати базу даних з будь-якими спеціальними параметрами.

Мій скрипт bash: make_db.sh

su postgres -c "createuser -w -d -r -s docker"
su postgres -c "createdb -O docker docker"

Докерфайл

FROM library/postgres

RUN ["mkdir", "/docker-entrypoint-initdb.d"]
ADD make_db.sh /docker-entrypoint-initdb.d/

Помилка, яку я отримую від docker logs -f db(db - це моє ім'я контейнера):

createuser: не вдалося підключитися до постгресів бази даних: не вдалося підключитися до сервера: Немає такого файлу чи каталогу

Здається, що команди, що знаходяться всередині /docker-entrypoint-initdb.d/папки, виконуються до запуску постгресів. Моє запитання: як я можу програмно налаштувати користувача / базу даних за допомогою офіційного контейнера postgres? Чи можливо це зробити за допомогою сценарію?

Відповіді:


378

EDIT - з 23 липня 2015 року

Офіційний Postgres докер зображення буде запускати .sqlскрипти знаходяться в /docker-entrypoint-initdb.d/папці.

Отже, все, що вам потрібно, це створити наступний скрипт sql:

init.sql

CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;

і додайте його у свій Dockerfile:

Докерфайл

FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/

Але з 8 липня 2015 року, якщо все , що вам потрібно , щоб створити користувача і базу даних , це найлегше використовувати косметику в POSTGRES_USER, POSTGRES_PASSWORDі POSTGRES_DBзмінні оточення:

docker run -e POSTGRES_USER=docker -e POSTGRES_PASSWORD=docker -e POSTGRES_DB=docker library/postgres

або з Dockerfile:

FROM library/postgres
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker

для зображень старше 23 липня 2015 року

З документації зображення Postgres Docker сказано, що

[...] він видасть будь-який * .sh скрипт, знайдений у цьому каталозі [ /docker-entrypoint-initdb.d], для подальшої ініціалізації перед запуском служби

Тут важливо "перед запуском послуги" . Це означає, що ваш скрипт make_db.sh буде виконаний до запуску послуги Postgres , отже, повідомлення про помилку "не вдалося підключитися до постгресів бази даних" .

Після цього з'являється ще одна корисна інформація:

Якщо вам потрібно виконати команди SQL як частину вашої ініціалізації, рекомендується використовувати єдиний користувальницький режим Postgres.

Погодився, це може бути трохи таємничим на перший погляд. Це говорить про те, що ваш сценарій ініціалізації повинен запустити послугу postgres в єдиному режимі, перш ніж робити свої дії. Таким чином, ви можете змінити сценарій make_db.ksh наступним чином, і він повинен наблизитись до того, що ви хочете:

ПРИМІТКА , це нещодавно змінилося в наступних комісіях . Це буде працювати з останньою зміною:

export PGUSER=postgres
psql <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

Раніше потрібно було використовувати --singleрежим:

gosu postgres postgres --single <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

2
можна з:gosu postgres postgres --single < /tmp/somefile.sql
Thomasleveil

1
Як я можу бігтиpsql -U myDb -d myDb -f myDb.sql
DarVar

3
Зауважте, --single більше не підтримується в жодному з Dockfiles постгресів.
brianz

1
Я дотримувався кроків, і коли я впадаю в контейнер mysql і перетворюю його на CD, docker-entrypoint-initdb.dя бачу свій init.sqlкод з кодом sql. АЛЕ коли я відкриваю mysql (використовуючи root-доступ) та вводя базу даних show, я бачу лише docker-compose.ymlфайл за замовчуванням у файлі! Чому це не працює для мене?
Махмуд Зальт

1
Його не виконується db.sqlнавіть після того, як він копіюється в `Докер-EntryPoint-initdb.d`
Камала

16

Тепер ви можете помістити .sql файли всередині каталогу init:

Від док

Якщо ви хочете зробити додаткову ініціалізацію в зображенні, похідному від цього, додайте один або кілька сценаріїв * .sql або * .sh у /docker-entrypoint-initdb.d (якщо необхідно, створивши каталог). Після того, як точка входу викликає initdb для створення користувачем та базою даних postgres за замовчуванням, він запустить будь-які * .sql файли та джерело будь-яких * .sh скриптів, знайдених у цьому каталозі, для подальшої ініціалізації перед запуском послуги.

Отже, копіювання файлу .sql буде працювати.


екологічні змінні для користувача / пароля та створення db все ще працюють. (9.5.3)
Єремія Адамс

1
У мене є проект, який працює на місцях. Однак коли я переміщую його до AWS EC2, він говорить, що БД не знайдено. Я копіюю файл .sql у відповідний каталог, але він все одно повертає цю помилку. Будь-яка ідея, де я міг шукати? Я новачок у Докер.
MadPhysicist

1
Це справедливо лише в тому випадку, якщо є один екземпляр db, прив'язаний до одного тома, тобто він не запускатиме жодних сценаріїв, якщо щось є вже в папці тому. Це дає мені головний біль, тому що я хочу мати окремі ініціалізатори db для кожної зі своїх служб стеку.
Фіолетовий Червоний

З Документів Warning: scripts in /docker-entrypoint-initdb.d are only run if you start the container with a data directory that is empty; any pre-existing database will be left untouched on container startup. One common problem is that if one of your /docker-entrypoint-initdb.d scripts fails (which will cause the entrypoint script to exit) and your orchestrator restarts the container with the already initialized data directory, it will not continue on with your scripts.
sh87

9

Використовуючи docker-compose:

Припустимо, що у вас є такий макет каталогу:

$MYAPP_ROOT/docker-compose.yml
           /Docker/init.sql
           /Docker/db.Dockerfile

Файл: docker-compose.yml

version: "3.3"
services:
  db:
    build:
      context: ./Docker
      dockerfile: db.Dockerfile
    volumes:
      - ./var/pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

Файл: Docker/init.sql

CREATE USER myUser;

CREATE DATABASE myApp_dev;
GRANT ALL PRIVILEGES ON DATABASE myApp_dev TO myUser;

CREATE DATABASE myApp_test;
GRANT ALL PRIVILEGES ON DATABASE myApp_test TO myUser;

Файл: Docker/db.Dockerfile

FROM postgres:11.5-alpine
COPY init.sql /docker-entrypoint-initdb.d/

Складання та започаткування послуг:

docker-compose -f docker-compose.yml up --no-start
docker-compose -f docker-compose.yml start

8

Я додаю спеціальні команди до середовища, викликаного в CMD після запуску служб ... Я не робив це з postgres, а з Oracle:

#set up var with noop command
RUN export POST_START_CMDS=":"
RUN mkdir /scripts
ADD script.sql /scripts
CMD service oracle-xe start; $POST_START_CMDS; tail -f /var/log/dmesg

і почати з

docker run -d ... -e POST_START_CMDS="su - oracle -c 'sqlplus @/scripts/script' " <image>

.


7

Ви можете використовувати ці команди:

docker exec -it yournamecontainer psql -U postgres -c "CREATE DATABASE mydatabase ENCODING 'LATIN1' TEMPLATE template0 LC_COLLATE 'C' LC_CTYPE 'C';"

docker exec -it yournamecontainer psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE postgres TO postgres;"

3
ENCODING 'LATIN1'дуже дивно ... Ви повинні мати особливі потреби, щоб не використовувати utf8
Zyigh

4

Перед створенням користувачів вам потрібно запустити базу даних. Для цього вам потрібно кілька процесів. Ви можете або запустити postgres в нижній частині (&) у сценарії оболонки, або використовувати такий інструмент, як supervisord, щоб запустити postgres, а потім запустити будь-які сценарії ініціалізації.

Посібник з нагляду та докера https://docs.docker.com/articles/using_supervisord/


2

З docker compose існує проста альтернатива (не потрібно створювати Dockerfile). Просто створіть init-database.sh:

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE USER docker;
    CREATE DATABASE my_project_development;
    GRANT ALL PRIVILEGES ON DATABASE my_project_development TO docker;
    CREATE DATABASE my_project_test;
    GRANT ALL PRIVILEGES ON DATABASE my_project_test TO docker;
EOSQL

І посилайтеся на це в розділі обсягів:

version: '3.4'

services:
  postgres:
    image: postgres
    restart: unless-stopped
    volumes:
      - postgres:/var/lib/postgresql/data
      - ./init-database.sh:/docker-entrypoint-initdb.d/init-database.sh
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - 5432:5432

volumes:
  postgres:
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.