|
1 | 1 | # TG Bot Gate |
2 | 2 |
|
3 | | -[](https://railway.com/deploy/Piv1dC?referralCode=kubernetes&utm_medium=integration&utm_source=template&utm_campaign=generic) |
4 | | - |
5 | 3 | TG Bot Gate is a lightweight Telegram Bot API gateway. It lets you register bot tokens in a small admin console and proxies requests only for registered bots. |
6 | 4 |
|
7 | | -The service is designed for simple self-hosting: one Rust backend, a built React admin UI, local disk storage, and Railway-friendly deployment. |
| 5 | +The service is designed for simple self-hosting: one Rust backend, a built React admin UI, SQLite on disk, and Railway-friendly deployment. |
8 | 6 |
|
9 | 7 | ## Features |
10 | 8 |
|
11 | 9 | - Telegram-compatible proxy routes: `/bot<TOKEN>/<METHOD>` |
12 | 10 | - Admin UI for registering and removing bot tokens |
13 | 11 | - SHA-256 token hash storage |
14 | 12 | - In-memory token hash cache for fast request authorization |
15 | | -- Local JSON storage with no database requirement |
| 13 | +- SQLite storage for bots, settings, and optional audit capture |
16 | 14 | - Docker and Railway deployment support |
17 | 15 |
|
18 | 16 | ## How It Works |
@@ -103,23 +101,81 @@ When audit capture is enabled in Settings, `GET /api/audit` supports pagination |
103 | 101 | | `kind` | — | `proxy` (only proxy traffic is recorded) | |
104 | 102 | | `min_status` | — | Minimum HTTP status code | |
105 | 103 |
|
106 | | -## Railway Deployment |
| 104 | +## Deployment |
107 | 105 |
|
108 | | -The repository includes: |
| 106 | +### 1. Railway (one-click) |
109 | 107 |
|
110 | | -- `Dockerfile` |
111 | | -- `railway.json` |
| 108 | +[](https://railway.com/deploy/Piv1dC?referralCode=kubernetes&utm_medium=integration&utm_source=template&utm_campaign=generic) |
112 | 109 |
|
113 | | -Set at least: |
| 110 | +1. Click **Deploy on Railway** and connect this repository (or use the template). |
| 111 | +2. Set variables: |
| 112 | + - `ADMIN_PASSWORD` — strong admin password (required). |
| 113 | + - `GATE_DB_PATH` — `/app/data/gate.db` (recommended). |
| 114 | +3. Attach a [Railway volume](https://docs.railway.com/guides/volumes) at `/app/data` so SQLite survives redeploys. |
| 115 | +4. Generate a public domain; open `https://<your-domain>/admin` and register bot tokens. |
114 | 116 |
|
115 | | -```text |
116 | | -ADMIN_PASSWORD=<strong-password> |
117 | | -GATE_DB_PATH=/app/data/gate.db |
| 117 | +Railway sets `PORT` and terminates HTTPS. Enable audit capture under **Settings** after deploy, or set `AUDIT_CAPTURE=1` once before first boot to seed the database. |
| 118 | + |
| 119 | +### 2. Self-hosted Docker |
| 120 | + |
| 121 | +The image is defined in `Dockerfile` (admin UI + Rust binary). CI publishes tags to GitHub Container Registry on `main` and version tags. |
| 122 | + |
| 123 | +**Option A — build on the server** |
| 124 | + |
| 125 | +```bash |
| 126 | +git clone https://github.com/tailabs/tgbot-gate.git |
| 127 | +cd tgbot-gate |
| 128 | +docker build -t tgbot-gate:local . |
118 | 129 | ``` |
119 | 130 |
|
120 | | -Enable audit capture from **Settings** in the admin UI after deploy (or set `AUDIT_CAPTURE=1` once before first boot to seed the database). |
| 131 | +**Option B — pull prebuilt image (after GHCR publish)** |
| 132 | + |
| 133 | +```bash |
| 134 | +docker pull ghcr.io/tailabs/tgbot-gate:latest |
| 135 | +``` |
121 | 136 |
|
122 | | -Railway provides the public domain and HTTPS. The app listens on the `PORT` value provided by the platform. |
| 137 | +**Run (replace secrets and host port as needed)** |
| 138 | + |
| 139 | +```bash |
| 140 | +docker volume create tgbot-gate-data |
| 141 | + |
| 142 | +docker run -d \ |
| 143 | + --name tgbot-gate \ |
| 144 | + --restart unless-stopped \ |
| 145 | + -p 8080:8080 \ |
| 146 | + -e ADMIN_PASSWORD='change-me-to-a-strong-password' \ |
| 147 | + -e GATE_DB_PATH=/app/data/gate.db \ |
| 148 | + -v tgbot-gate-data:/app/data \ |
| 149 | + tgbot-gate:local |
| 150 | +``` |
| 151 | + |
| 152 | +Use `ghcr.io/tailabs/tgbot-gate:latest` instead of `tgbot-gate:local` when pulling from GHCR. |
| 153 | + |
| 154 | +**Verify** |
| 155 | + |
| 156 | +```bash |
| 157 | +docker logs tgbot-gate |
| 158 | +curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/healthz |
| 159 | +``` |
| 160 | + |
| 161 | +Admin UI: `http://<server-ip>:8080/admin` (put a reverse proxy in front for HTTPS in production). |
| 162 | + |
| 163 | +**Shortcut (Makefile)** |
| 164 | + |
| 165 | +```bash |
| 166 | +ADMIN_PASSWORD='change-me' make docker |
| 167 | +``` |
| 168 | + |
| 169 | +This builds `tgbot-gate:local`, creates volume `tgbot-gate-data`, and runs the container on port `8080`. |
| 170 | + |
| 171 | +### Deployment checklist |
| 172 | + |
| 173 | +| Item | Railway | Docker | |
| 174 | +| --- | --- | --- | |
| 175 | +| Admin password | `ADMIN_PASSWORD` variable | `-e ADMIN_PASSWORD=...` | |
| 176 | +| Persistent data | Volume at `/app/data` | `-v tgbot-gate-data:/app/data` | |
| 177 | +| Public URL | Railway domain + HTTPS | Your reverse proxy / firewall | |
| 178 | +| Bot proxy base | `https://<domain>/bot<TOKEN>/...` | `http(s)://<host>/bot<TOKEN>/...` | |
123 | 179 |
|
124 | 180 | ## Development |
125 | 181 |
|
@@ -148,7 +204,7 @@ pnpm run build |
148 | 204 | ## Security Notes |
149 | 205 |
|
150 | 206 | - Raw bot tokens are not stored on disk. |
151 | | -- The registry file contains token hashes, labels, and creation timestamps. |
| 207 | +- The registry stores token hashes, labels, and creation timestamps in SQLite. |
152 | 208 | - Admin sessions use an HTTP-only cookie. |
153 | 209 | - Keep `ADMIN_PASSWORD` private. |
154 | 210 | - Do not commit `.env`, `data/`, `admin/dist/`, or dependency directories. |
|
0 commit comments