From 3ef9288eb57c16715ada1655b17f5211f5cfa80f Mon Sep 17 00:00:00 2001 From: GraphTheory Date: Thu, 4 Jun 2026 13:11:30 -0400 Subject: [PATCH] feat: add Docker image with cron-based scheduled monitoring (Fixes #28) Co-authored-by: lb1192176991-lab --- Dockerfile | 26 +++++++++++++++---- docker-compose.yml | 18 +++++++++++++ docker-entrypoint.sh | 57 +++++++++++++++++++++++++++++++++++++++++ scripts/telegram_bot.py | 3 +-- setup.py | 1 + 5 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 docker-compose.yml create mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 09288aa..95fcbbe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,31 @@ FROM python:3.12-slim +LABEL org.opencontainers.image.source="https://github.com/rugpullnet/solana-rug" +LABEL org.opencontainers.image.description="Solana Rug Guard — background monitoring container" + WORKDIR /app -# Install solana-rug and its Telegram bot dependencies +# Install solana-rug from source COPY scripts/ scripts/ COPY solana_rug/ solana_rug/ -COPY pyproject.toml setup.py ./ +COPY pyproject.toml setup.py README.md ./ +RUN pip install --no-cache-dir . + +# Copy entrypoint +COPY docker-entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh -RUN pip install --no-cache-dir . python-telegram-bot +# Persistent data volume +VOLUME /data -ENV TELEGRAM_BOT_TOKEN="" +# Default config via env +ENV WATCH_TOKENS="" +ENV WATCH_INTERVAL=300 +ENV WEBHOOK_URL="" +ENV SQLITE_HISTORY=/data/history.sqlite3 ENV SOLANA_RPC_URL="" -CMD ["python", "-m", "scripts.telegram_bot"] +HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ + CMD python3 -c "import os; exit(0 if os.path.isfile(os.environ.get('SQLITE_HISTORY','/data/history.sqlite3')) else 1)" + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0a758f8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3.9" + +services: + solana-rug: + build: . + container_name: solana-rug-monitor + restart: unless-stopped + volumes: + - solana-rug-data:/data + environment: + - WATCH_TOKENS=DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263,EPjFWdd5AufQSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v + - WATCH_INTERVAL=300 + - WEBHOOK_URL= + - THRESHOLD=40 + - SOLANA_RPC_URL= + +volumes: + solana-rug-data: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..237e355 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# docker-entrypoint.sh — cron-like monitoring loop for solana-rug Docker image. +# +# Reads WATCH_TOKENS (comma-separated mint addresses) and checks each +# on the configured interval, storing results in SQLite and optionally +# posting webhook alerts. + +set -e + +if [ "$WATCH_TOKENS" = "***" ] || [ -z "$WATCH_TOKENS" ]; then + echo "ERROR: WATCH_TOKENS env var is required (comma-separated mint addresses)" + exit 1 +fi + +echo "=== Solana Rug Guard Docker Monitor ===" +echo "Watch list: $WATCH_TOKENS" +echo "Interval: ${WATCH_INTERVAL}s" +echo "History: $SQLITE_HISTORY" +echo "Webhook: ${WEBHOOK_URL:-disabled}" +echo "" + +# Trap SIGTERM for graceful shutdown +trap 'echo "Shutting down..."; exit 0' SIGTERM SIGINT + +while true; do + echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] Checking tokens..." + + OLD_IFS="$IFS" + IFS=',' + for mint in $WATCH_TOKENS; do + mint=$(echo "$mint" | tr -d ' ') + echo " Checking $mint..." + + if [ -n "$WEBHOOK_URL" ]; then + python3 -m scripts.rugguard token "$mint" --json 2>/dev/null | \ + curl -s -X POST "$WEBHOOK_URL" \ + -H "Content-Type: application/json" \ + -d @- >/dev/null 2>&1 && \ + echo " Webhook sent" || \ + echo " Webhook failed" + fi + + # Also store in history via watch command (if history is persisted) + env SQLITE_HISTORY="$SQLITE_HISTORY" \ + python3 -m scripts.rugguard watch "$mint" \ + --iterations 1 --interval 1 \ + --history "$SQLITE_HISTORY" \ + ${WEBHOOK_URL:+--webhook "$WEBHOOK_URL"} \ + ${THRESHOLD:+--threshold "$THRESHOLD"} \ + 2>&1 | sed 's/^/ /' + done + IFS="$OLD_IFS" + + echo " Sleeping for ${WATCH_INTERVAL}s..." + sleep "$WATCH_INTERVAL" & + wait $! +done diff --git a/scripts/telegram_bot.py b/scripts/telegram_bot.py index 5e890a0..62f7558 100644 --- a/scripts/telegram_bot.py +++ b/scripts/telegram_bot.py @@ -13,7 +13,6 @@ from __future__ import annotations -import json import logging import os import sqlite3 @@ -149,7 +148,7 @@ def _format_report(mint: str) -> str: symbol = report.token.symbol or report.token.name or f"{mint[:4]}...{mint[-4:]}" lines = [ f"*🛡️ {symbol} Safety Report*", - f"", + "", f"**Score:** {report.safety_score}/100 — **{report.risk_level}**", f"**Mint:** `{mint}`", "", diff --git a/setup.py b/setup.py index 2231074..fa1303e 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ """Backward-compatible setup.py for solana-rug.""" from setuptools import setup + setup()