Вопрос или проблема
Используя openresty/openresty:latest
в Dockerfile:
FROM openresty/openresty:latest
COPY default-prod.conf /etc/nginx/conf.d/default.conf
RUN apt-get update && apt-get install -y luarocks
RUN luarocks install luasocket
RUN luarocks install pgmoon
RUN luarocks install lua-cjson
RUN luarocks install lua-resty-openssl
и networks:
в моем docker-compose.yml
smalljobsdb:
image: postgres:14
container_name: smalljobsdb
env_file:
- .env.production
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "5450:5432"
volumes:
- ./db-production/postgresql:/var/lib/postgresql/data
networks:
- smalljobs
nginx:
build:
context: ./nginx
dockerfile: Dockerfile.prod
container_name: nginx
restart: always
# network_mode: host
networks:
- smalljobs
volumes:
# - ./certbot/www/:/var/www/certbot/:ro
- ./server/shared:/usr/share/nginx/html
- ./nginx/cert:/etc/nginx/ssl:ro
- storefrontbuild:/usr/share/nginx/html/storefront
ports:
- 80:80
- 443:443
depends_on:
smalljobsdb:
condition: service_started
smalljobsserver:
condition: service_started
smalljobsstorefront:
condition: service_completed_successfully
когда я пытаюсь подключиться к своей базе данных postgres во время рендеринга своего веб-сайта в файле nginx.conf:
location ~ ^/[0-9]+$ {
default_type text/html;
resolver 127.0.0.11 valid=30s;
content_by_lua_block {
local id = ngx.var.uri:match("^/([0-9]+)$") -- Извлечение ID из URI
if id then
local cjson = require "cjson"
local pgmoon = require("pgmoon")
-- Настройка соединения с PostgreSQL
local pg = pgmoon.new({
host = "smalljobsdb",
port = "", << УДАЛЕНО НО ИСПОЛЬЗУЕТСЯ
user = "", << УДАЛЕНО НО ИСПОЛЬЗУЕТСЯ
password = "", << УДАЛЕНО НО ИСПОЛЬЗУЕТСЯ
database = "" << УДАЛЕНО НО ИСПОЛЬЗУЕТСЯ
})
ngx.log(ngx.ERR, "BEFORE CONNECTION " .. id)
-- Подключение к базе данных PostgreSQL
assert(pg:connect())
ngx.log(ngx.ERR, "AFTER CONNECTION " .. id)
pg:keepalive()
я получаю ошибку:
nginx | 2024/11/08 17:09:27 [error] 7#7: *1 [lua] default.conf:60):17: BEFORE CONNECTION 8, client: 85.193.34.174, server: smalljobs.cz, request: "GET /8 HTTP/1.1", host: "smalljobs.cz"
nginx | 2024/11/08 17:09:28 [error] 7#7: *1 [lua] default.conf:60):20: AFTER CONNECTION 8, client: 85.193.34.174, server: smalljobs.cz, request: "GET /8 HTTP/1.1", host: "smalljobs.cz"
nginx | 2024/11/08 17:09:28 [error] 7#7: *1 attempt to send data on a closed socket: u:00007F1E11F831F8, c:0000000000000000, ft:0 eof:0, client: 85.193.34.174, server: smalljobs.cz, request: "GET /8 HTTP/1.1", host: "smalljobs.cz"
nginx | 2024/11/08 17:09:28 [error] 7#7: *1 attempt to receive data on a closed socket: u:00007F1E11F831F8, c:0000000000000000, ft:0 eof:0, client: 85.193.34.174, server: smalljobs.cz, request: "GET /8 HTTP/1.1", host: "smalljobs.cz"
nginx | 2024/11/08 17:09:28 [error] 7#7: *1 lua entry thread aborted: runtime error: content_by_lua(/etc/nginx/conf.d/default.conf:60):24: receive_message: failed to get type: closed
nginx | stack traceback:
nginx | coroutine 0:
nginx | [C]: in function 'assert'
nginx | content_by_lua(/etc/nginx/conf.d/default.conf:60):24: in main chunk, client: 85.193.34.174, server: smalljobs.cz, request: "GET /8 HTTP/1.1", host: "smalljobs.cz"
ЧТО Я ПРОБОВАЛ:
- Смена контейнера Nginx на
network_mode: host
– не удалось в начале:
upstream smalljobsserver {
server smalljobsserver:3034; << smalljobsserver не найден
} - Подключение через 127.0.0.1 и резолвер 8.8.8.8 или GOOGLE DNS, или не удалось отправить соединение наружу
ЧТО Я ХОЧУ
Получить данные из базы данных в зависимости от /:id из URL. Как можно безопаснее, чтобы не было подделки
Ответ или решение
Ошибка в Docker: "attempt to send data on a closed socket" при подключении к PostgreSQL из OpenResty
Ошибка "attempt to send data on a closed socket" при работе с Docker и OpenResty является распространенным симптомом, указывающим на проблемы с сетевыми соединениями между контейнерами или с конфигурацией самого подключения. Давайте подробно разберемся с возможными причинами и путями их решения.
Контекст ошибки
Ваша конфигурация Docker предполагает использование двух контейнеров: одного для Postgres и другого для OpenResty. В процессе обработки запроса к вашему приложению вы пытаетесь подключиться к базе данных PostgreSQL. Ошибка возникает после попытки установить соединение, что может свидетельствовать о нескольких проблемах.
Возможные причины
-
Неверные параметры подключения: Убедитесь, что все параметры подключения к базе данных (хост, порт, пользователь, пароль, имя базы данных) указаны корректно. Проверьте конфигурацию переменных окружения, чтобы гарантировать их доступность и правильность.
-
Сетевая конфигурация: Обратите внимание на конфигурацию Docker. Оба контейнера должны находиться в одной сети, что, судя по вашему
docker-compose.yml
, сделано правильно (используется сетьsmalljobs
). Убедитесь, что вы используете правильные имена контейнеров и что они доступны друг другу. -
Проблемы с временем жизни соединения: Метод
pg:keepalive()
в Lua может не поддерживать долгосрочные соединения должным образом. Убедитесь, что соединение с базой данных установлено и активно во время работы вашего кода. Также стоит проверить, не закрывается ли соединение между запросами. -
Файловая система: Если у вас есть файлы на хосте, которые монтируются в контейнере (например, данные базы данных), убедитесь, что права доступа к ним корректны.
-
Версия зависимостей: Иногда проблемы возникают из-за несовместимости библиотек. Убедитесь, что версии
pgmoon
и других Lua-библиотек совместимы с используемой версией PostgreSQL.
Рекомендации по устранению проблемы
-
Проверка параметров подключения:
local pg = pgmoon.new({ host = "smalljobsdb", port = "5432", -- Убедитесь, что порт указан user = "ваш_пользователь", password = "ваш_пароль", database = "ваша_база" })
-
Проверка соединения: Добавьте дополнительный лог для проверки успешного подключения:
local connection_status, err = pg:connect() if not connection_status then ngx.log(ngx.ERR, "Connection failed: " .. err) return ngx.exit(500) -- Или другая обработка ошибки end
-
Тестирование соединения: Запустите команду из вашего контейнера с OpenResty, чтобы проверить подключение к базе данных:
docker exec -it nginx_container_name psql -h smalljobsdb -U ваш_пользователь -d ваша_база
-
Настройка Docker Compose: Убедитесь, что все служебные зависимости правильно настроены и запускаются в нужном порядке. Параметры
depends_on
могут быть критически важны, но не гарантируют, что служба будет полностью готова к использованию. Рассмотрите использование кастомных проверок готовности. -
Логи и отладка: Используйте логи Docker и Nginx для получения информации о возможных ошибках и поведении приложения.
-
Избегайте network_mode: host, если это не абсолютно необходимо, так как это может повлечь за собой дополнительные проблемы с разделением сетей и маршрутизации.
Заключение
Ошибка "attempt to send data on a closed socket" может иметь несколько источников. Следуя приведенным выше рекомендациям и методам отладки, вы сможете определить и устранить причину проблемы. Хорошая практика — убедиться в правильности конфигурации, четком понимании сетевой архитектуры Docker и аккуратной обработке ошибок при работе с соединениями к базе данных.