Вопрос или проблема
Я контейнеризовал полнофункциональное API приложение, которое представляет собой простую контактную форму и страницу благодарности, использующие react-hook-form, axios и ORM с Sequelize и его методом Contact.create().
Когда данные отправляются, я попадаю на страницу благодарности, но не вижу, чтобы они сохранялись в базе данных psql, и не наблюдаю новых записей. Однако данные успешно сохраняются при запуске без Docker.
Я не вижу никаких проблем в логах Docker, и форма успешно отправляется в консоли. Я проверил подключения к базе данных.
Вот мой запрос и функция onsubmit. Я вижу, что объект возвращается в консоли как локально, так и в Docker, но в Docker я не получаю ‘submitted’ в console.log. Я ожидаю увидеть новую запись в psql и ‘submitted’ при запуске в Docker.
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
const { first_name, last_name, email, phone_number, message } = req.body;
try {
await Contact.create({ first_name, last_name, email, phone_number, message })
res.status(200).json({ message: 'форма отправлена' })
} catch (error) {
console.log('ошибка сохранения данных:', error);
res.status(500).json({ error: 'произошла ошибка' })
}
})
const onSubmit = async (data) => {
console.log('Данные формы:', data);
try {
const response = await axios.post(apiSubmit, data)
if (response.status === 200) {
navigate('/Thankyou')
console.log('отправлено');
}
} catch (error) {
}
};
Вот мой Docker-compose.
version: '3'
services:
server:
build:
context: ./server
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- DATABASE_URL=${DATABASE_URL}
depends_on:
- db
links:
- db
client:
build:
context: ./client
dockerfile: Dockerfile
ports:
- "3000:3000"
depends_on:
- server
environment:
- REACT_APP_API_URL=${REACT_APP_API_URL}
db:
image: postgres:latest
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Подключения к БД
import { Sequelize } from 'sequelize';
import dotenv from 'dotenv';
dotenv.config();
const sequelize = new Sequelize(process.env.DATABASE_URL, {
dialect: 'postgres',
logging: false,
});
export default sequelize;
import sequelize from '../sequelize.js';
const syncDatabase = async () => {
try {
await sequelize.sync();
} catch (error) {
}
};
syncDatabase();
export default syncDatabase;
Ответ или решение
Для решения проблемы с сохранением данных в базе данных Postgres при использовании Docker, следует обратить внимание на несколько ключевых моментов. Исходя из вашего описания, данные не сохраняются в базе данных, хотя приложение работает без Docker. Давайте рассмотрим возможные причины и решения.
1. Проверка подключения к базе данных
Убедитесь, что переменная окружения DATABASE_URL
, используемая для подключения к базе данных, верно задана в файле .env
и передается в контейнер. Строка подключения для Postgres в DATABASE_URL
должна выглядеть следующим образом:
DATABASE_URL=postgres://<USER>:<PASSWORD>@db:5432/<DATABASE>
Здесь <USER>
, <PASSWORD>
и <DATABASE>
должны соответствовать тем, которые вы задаете в docker-compose.yml
.
2. Проверка настроек машины для Docker
Иногда проблемы могут возникать из-за сетевых настроек или разделяемых ресурсов между контейнерами. Убедитесь, что на хостовой машине (где работает Docker) не настроены ограничения на доступ к ресурсам.
3. Логи и отладка
Хотя вы упомянули, что логи Docker не показывают ошибок, стоит добавить больше информации в логи — вам нужно удостовериться, что ошибки выводятся не только при сохранении, но и в других местах вашего приложения. Например, в блоке catch
как для функции обработки запроса, так и для функции отправки данных в onSubmit
.
try {
await Contact.create({ first_name, last_name, email, phone_number, message });
res.status(200).json({ message: 'form submitted' });
} catch (error) {
console.log('error saving data:', error);
res.status(500).json({ error: 'an error occurred' });
}
Также добавьте логи для проверки, что доходит ли запрос до нужного обработчика.
4. Синхронизация базы данных
Убедитесь, что функция syncDatabase()
корректно выполняется, и таблицы базы данных созданы до отправки данных. Добавьте логи, чтобы проверить, выполняется ли синхронизация:
const syncDatabase = async () => {
try {
await sequelize.sync();
console.log('Database synchronized');
} catch (error) {
console.log('Error synchronizing database:', error);
}
};
syncDatabase();
5. Проверка CORS
Если ваше приложение работает на клиенте и сервере, убедитесь, что у вас корректно настроены CORS (Cross-Origin Resource Sharing), так как запросы могут блокироваться, если сервер не разрешает их с определенных источников.
6. С помощью Postman или cURL
Для дополнительной проверки, отправьте запрос на сервер с помощью Postman или cURL, чтобы убедиться, что проблема не в клиентской части. Это поможет нам понять, происходит ли что-то не так на стороне клиента.
Пример cURL:
curl -X POST http://localhost:8080/your-endpoint -H "Content-Type: application/json" -d '{"first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "123456789", "message": "Hello"}'
7. Проверка прав доступа к базе данных
Убедитесь, что у пользователя, указанного в POSTGRES_USER
, есть все необходимые права на запись в базе данных. Вы можете сделать это, выполнив команду SQL после подключения к базе данных:
GRANT ALL PRIVILEGES ON DATABASE your_database TO your_user;
Вывод
Пошагово проверив каждую из вышеперечисленных проблем, вы с большей вероятностью сможете определить источник проблемы. Не забудьте также обновить ваши зависимости и убедиться, что все необходимые модули и пакеты установлены в контейнерах. Удачи в отладке вашего приложения!