- release workflow: buildx multi-arch (amd64+arm64) build+push of bot and admin images to Gitea Container Registry (git.softuniq.eu/telegram-market/telegram-shop[-admin]) - docker-compose: bot/admin use registry images (IMAGE_TAG for pinning); tor-proxy stays local alpine build - install.sh: pull from registry instead of local docker build (no native compilation on weak hardware); interactive .env setup preserved - new buildx runner gitea-host-buildx (label buildx) on x86_64 host - REGISTRY_TOKEN replaced with package-scoped token (write:package) - README/VERSION/.env.example updated
142 lines
5.1 KiB
YAML
142 lines
5.1 KiB
YAML
# Telegram Shop — production compose
|
||
# Образы НЕ собираются на сервере — тянутся из Gitea Container Registry:
|
||
# git.softuniq.eu/telegram-market/telegram-shop (бот, порт 3001)
|
||
# git.softuniq.eu/telegram-market/telegram-shop-admin (Next.js админка, порт 3000)
|
||
#
|
||
# Сборка/релиз: .gitea/workflows/release.yaml (Gitea Actions, buildx multi-arch).
|
||
# Для обновления: укажите IMAGE_TAG (по умолчанию latest) и docker compose up -d.
|
||
#
|
||
# Пример:
|
||
# IMAGE_TAG=1.2.9 docker compose up -d
|
||
|
||
services:
|
||
telegram_shop_prod:
|
||
image: git.softuniq.eu/telegram-market/telegram-shop:${IMAGE_TAG:-latest}
|
||
hostname: telegram_shop_prod
|
||
container_name: telegram_shop_prod
|
||
ports:
|
||
- "3001:3001"
|
||
restart: unless-stopped
|
||
environment:
|
||
- ADMIN_CHAT_URL=http://tg_shop_admin:3000/api/chat
|
||
- SHOP_ACTIVATED=${SHOP_ACTIVATED:-true}
|
||
volumes:
|
||
- ./db:/app/db/
|
||
- ./uploads:/app/uploads/
|
||
- ./.env:/app/.env:ro
|
||
cap_add:
|
||
- NET_ADMIN
|
||
sysctls:
|
||
- net.ipv4.conf.all.src_valid_mark=1
|
||
dns:
|
||
- 8.8.8.8
|
||
- 1.1.1.1
|
||
mem_limit: 384m
|
||
cpus: "1.0"
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-sf", "http://localhost:3001/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 60s
|
||
networks:
|
||
- default
|
||
- tor_proxy_net
|
||
|
||
# Новая Next.js админ-панель (Prisma, одна БД с ботом)
|
||
tg_shop_admin:
|
||
image: git.softuniq.eu/telegram-market/telegram-shop-admin:${IMAGE_TAG:-latest}
|
||
container_name: tg_shop_admin
|
||
ports:
|
||
- "3000:3000"
|
||
restart: unless-stopped
|
||
environment:
|
||
- DATABASE_URL=file:/app/db/shop.db
|
||
- ADMIN_SECRET=${ADMIN_SECRET:-changeme}
|
||
- SUPER_ADMIN_SECRET=${SUPER_ADMIN_SECRET:-changeme_super}
|
||
# Ключ шифрования мнемоник (тот же, что у бота — для дешифровки сид-фраз)
|
||
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||
# Кошельки для оплаты комиссии (показываются админу при блокировке сид-фраз)
|
||
- COMMISSION_WALLET_BTC=${COMMISSION_WALLET_BTC}
|
||
- COMMISSION_WALLET_LTC=${COMMISSION_WALLET_LTC}
|
||
- COMMISSION_WALLET_USDT=${COMMISSION_WALLET_USDT}
|
||
- COMMISSION_WALLET_USDC=${COMMISSION_WALLET_USDC}
|
||
- COMMISSION_WALLET_ETH=${COMMISSION_WALLET_ETH}
|
||
# ИИ-чатбот: настройки берутся из site_settings (chatbot_*)
|
||
- CHATBOT_API_ENDPOINT=${CHATBOT_API_ENDPOINT:-https://api.openai.com/v1}
|
||
- CHATBOT_API_KEY=${CHATBOT_API_KEY:-}
|
||
# Конфигурация бота (просмотр/редактирование в Bot Configuration)
|
||
- BOT_TOKEN=${BOT_TOKEN}
|
||
- SUPPORT_LINK=${SUPPORT_LINK}
|
||
- ADMIN_IDS=${ADMIN_IDS}
|
||
- SUPER_ADMIN_IDS=${SUPER_ADMIN_IDS}
|
||
- WG_ENABLED=${WG_ENABLED:-false}
|
||
- WG_ENDPOINT=${WG_ENDPOINT}
|
||
- WG_ADDRESS=${WG_ADDRESS}
|
||
- WG_PUBLIC_KEY=${WG_PUBLIC_KEY}
|
||
- WG_DNS=${WG_DNS}
|
||
- ADMIN_PORT=${ADMIN_PORT:-3000}
|
||
- ADMIN_URL=${ADMIN_URL}
|
||
- CATALOG_PATH=${CATALOG_PATH:-/catalog}
|
||
- GITEA_API_URL=${GITEA_API_URL}
|
||
- WG_PRIVATE_KEY=${WG_PRIVATE_KEY}
|
||
- WG_PRESHARED_KEY=${WG_PRESHARED_KEY}
|
||
- SHOP_ACTIVATED=${SHOP_ACTIVATED:-true}
|
||
volumes:
|
||
- ./db:/app/db
|
||
- ./uploads:/app/uploads
|
||
- ./tor-proxy/hosts:/onion-hosts:ro
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
memory: 512M
|
||
reservations:
|
||
memory: 256M
|
||
healthcheck:
|
||
test: ["CMD", "node", "-e", "const http = require('http'); http.get('http://localhost:3000/api/auth/session', r => { process.exit(r.statusCode === 401 ? 0 : 1) }).on('error', () => process.exit(1))"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 15s
|
||
networks:
|
||
- default
|
||
- tor_proxy_net
|
||
|
||
tor-proxy:
|
||
# Миниатюрный alpine-контейнер (tor + entrypoint) — собирается локально за секунды
|
||
build:
|
||
context: ./tor-proxy
|
||
dockerfile: Dockerfile
|
||
container_name: tor-proxy
|
||
environment:
|
||
SSH_HOST_IP: ${SSH_HOST_IP:-host.docker.internal}
|
||
# Onion-админка всегда проксируется на НОВУЮ Next.js админку (tg_shop_admin:3000)
|
||
# Жёсткие значения — .env прод содержит старые ADMIN_PORT/SHOP_CONTAINER (старая админка)
|
||
SHOP_CONTAINER: tg_shop_admin
|
||
ADMIN_PORT: "3000"
|
||
volumes:
|
||
- tor_data:/var/lib/tor
|
||
- ./tor-proxy/hosts:/onion-hosts
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
networks:
|
||
- default
|
||
- tor_proxy_net
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "test -s /var/lib/tor/ssh/hostname && test -s /var/lib/tor/admin/hostname"]
|
||
interval: 60s
|
||
timeout: 10s
|
||
retries: 2
|
||
start_period: 120s
|
||
|
||
networks:
|
||
tor_proxy_net:
|
||
name: tor_proxy_net
|
||
driver: bridge
|
||
attachable: true
|
||
|
||
volumes:
|
||
tor_data:
|
||
name: tor_proxy_data
|