Go to file
2026-11-01 18:51:03 +03:00
api feat: добавил бэк 2026-11-01 17:59:12 +03:00
bot feat: добавил бота 2026-11-01 17:59:29 +03:00
docker feat: добавил файл конфигурации для nginx 2026-11-01 18:00:00 +03:00
web feat: добавил веб клиент 2026-11-01 17:58:46 +03:00
.env.example feat: добавил docker-compose и .env.example 2026-11-01 18:00:42 +03:00
.gitignore feat: добавил docker-compose и .env.example 2026-11-01 18:00:42 +03:00
docker-compose.yml feat: добавил docker-compose и .env.example 2026-11-01 18:00:42 +03:00
README.md Обновить README.md 2026-11-01 18:51:03 +03:00

Магазин

Минимальный интернет-магазин: каталог, карточка, корзина и заказ без оплаты.

Сайт открывается на http://localhost:8088. Порт 8080 на этой машине уже занят, поэтому gateway выведен на 8088. Консоль хранилища: http://localhost:9001 (minio / minioadmin). Образ pgsty/silo — публичная сборка MinIO: исходный minio/minio с Docker Hub больше не скачивается без аккаунта.

Запуск

Нужен Docker.

docker compose up --build

API, веб и бот поднимаются в двух репликах. Снаружи опубликован только gateway на порту 8080: он заново резолвит имя web и распределяет запросы по копиям.

Бот молчит, пока в окружении нет токена. Чтобы включить его:

set BOT_TOKEN=123456:telegram-token
docker compose up --build

В Telegram: /catalog, /cart, /checkout. Имя и телефон бот хранит в Postgres, не в памяти процесса.

Что специально сделано stateless

  • Сессия сайта — строка в web_sessions и HttpOnly-кука. Её принимает любая реплика API.
  • Корзина и заказ лежат в Postgres. Повторное добавление одного товара — INSERT ... ON CONFLICT, две реплики не создают две строки.
  • Оформление блокирует строки корзины FOR UPDATE и в той же транзакции пишет заказ.
  • Картинки читаются из MinIO. На диск контейнера они не сохраняются.
  • Бот в режиме polling: одна реплика держит advisory lock и вызывает getUpdates, вторая ждёт. Telegram не принимает два poller на один токен. Повторный update_id отсекается первичным ключом telegram_updates. Сообщения одного чата сериализуются pg_advisory_xact_lock.
  • BOT_MODE=webhook и WEBHOOK_URL переключают бота на webhook: lock не берётся, работают все реплики, дедупликация та же. Нужен публичный HTTPS, который Telegram достучится до bot:8081.

Пароли в compose — только для локального демо.

Запущенный пример

на веб - invix-test.bratskih.tech
бот тг - @invix_test12345_task_bot