psql: ошибка: сервер неожиданно закрыл соединение. Вероятно, это означает, что сервер аварийно завершил работу до или во время обработки запроса

#postgresql #docker #docker-compose #dockerfile

Вопрос:

Я новичок в postgres , я хочу контейнеризировать postgres, ниже приведен мой файл dockerfile

 FROM postgres:13.3-alpine
ENV POSTGRES_USER="postgres"
COPY . /docker-entrypoint-initdb.d
RUN chmod 777 /docker-entrypoint-initdb.d/main.sh
EXPOSE 5432
ENTRYPOINT ["/docker-entrypoint-initdb.d/main.sh"]
 

И у меня есть несколько сценариев инициализации (main.sh), которые должны запускаться при запуске контейнеров, я поместил их в docker-entrypoint-initdb.d. Файлы находятся
.

 ├── ddl
│   ├── create_db_ddl.sql
│   ├── create_index_ddl.sql
│   └── create_table_ddl.sql
├── dml
│   ├── insert_emm_cat4_child_que.sql
│   ├── insert_emm_data_cat1.sql
│   ├── insert_emm_data_cat2.sql
│   ├── insert_emm_data_cat3.sql
│   ├── insert_emm_data_cat4.sql
│   ├── insert_emm_template.sql
│   └── insert_master_data.sql
├── Dockerfile
├── init.sql
├── Jenkinsfile
└── main.sh
 

когда я запускаю контейнер, он выдает это сообщение об ошибке

 ############ Create database and schema if not exist ###########
psql: error: server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request. 
 

это от моего main.sh файл
Одно наблюдение я сделал, если в dockerfile, если я не включу ENTRYPOINT ["/docker-entrypoint-initdb.d/main.sh"] и после docker exec в контейнер postgres, а затем выполню ./main.sh вручную это прекрасно работает
, мой main.sh файл выглядит так

 #!/bin/sh
## SET password
export PGPASSWORD='sapient@123'

#Set the value of variable
database="survey_platform"
user="postgres"
## execute scripts
echo "############ Create database and schema if not exist ###########"
psql -h <IP>-p 5432 -U $user -f "ddl/create_db_ddl.sql"
echo "############ Create table if not exist ###########"
psql -h <IP> -p 5432 -U $user -d $database -f "ddl/create_table_ddl.sql"
echo "############ Create index if not exist ###########"
psql -h <IP> -p 5432 -U $user -d $database -f "ddl/create_index_ddl.sql"
/bin/sh
 

Я в замешательстве, почему я не могу бежать main.sh с ТОЧКОЙ входа из файла dockerfile

Комментарии:

1. Найдите файл журнала сервера PostgreSQL и посмотрите, что в нем говорится о том, почему он исчез. Может быть, файлы системного журнала тоже помогли бы, как если бы это был убийца ООМ.

Ответ №1:

Вам не нужен ENTRYPOINT , или даже этот сценарий-обертка здесь. Если вы COPY введете *.sql файлы /docker-entrypoint-initdb.d , postgres образ запустит их в алфавитном порядке с соответствующими учетными данными при первом запуске контейнера с неинициализированной базой данных.

 FROM postgres:13.3-alpine
COPY ddl/create_db_ddl.sql /docker-entrypoint-initdb.d/01_create_db_ddl.sql
COPY ddl/create_table_ddl.sql /docker-entrypoint-initdb.d/02_create_table_ddl.sql
COPY ddl/create_index_ddl.sql /docker-entrypoint-initdb.d/03_create_index_ddl.sql
# No EXPOSE, ENTRYPOINT, CMD, etc.
 

Обратите внимание, что эти сценарии выполняются только в том случае, если данные базы данных вообще не существуют. Если вы храните данные базы данных в именованном томе или каталоге хоста (а вы должны), эти сценарии не будут перезапущены, если там есть данные.

По сути, контейнер Docker выполняет только одну команду, и когда эта команда завершается, контейнер также завершается. На postgres изображении есть довольно сложный сценарий точки входа, который запускает временную несетевую базу данных для запуска сценариев инициализации; если вы укажете ENTRYPOINT в производном файле Dockerfile, эта команда выполняется вместо стандартного сценария инициализации или фактической базы данных. Ваша программа установки пытается работать psql в контейнере, но так как она работает вместо базы данных, ей не к чему подключаться.

Комментарии:

1. Я скопировал файлы .sql в docker-entrypoint-initdb.d , но SQL не выполняется, я должен выполнить его вручную с помощью exec

2. поскольку я получаю каталог базы данных PostgreSQL, похоже, что он содержит базу данных; Пропуск инициализации даже после того, как у меня нет смонтированного каталога данных