SulgX Panel: the README documents v1.1.0 and tells you to pin that tag, the newest release is 1.5.7, and SECRET_KEY ships an example value
🚀 SulgX Panel: A single-file, powerful, and free panel for managing VLESS subscriptions via WebSocket + TLS. Responsive UI, JWT auth, per-user bandwidth limits, clean IP scanner, bilingual Telegram bot, and real-time traffic charts. Runs smoothly on Render, Railway, Dockfly, and other cloud platforms.
At a glance
- What is it?
- SulgX Panel is a single-file FastAPI and SQLite application for operating VLESS over WebSocket with TLS, offering JWT login, per-user traffic quotas, an analytics dashboard, a Telegram bot, and a built-in port scanner. It deploys from a Dockerfile to several free-tier platforms. The architecture is one file, which is both its clearest identity and the reason several of its rough edges cannot be fixed by adding a module.
- Who is it for?
- This is a capable single-file panel with an unusually good deployment story for free-tier hosts, and if your use is running your own VLESS inbounds for people you control it has the pieces: quotas, expiry, concurrent connection limits, audit logs, and rate-limited login. Three things to check before you deploy it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 70 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The page documents 1.1.0 and the newest tag is 1.5.7
The heading reads Version 1.1.0, there is a section titled What's New in v1.1.0, and the release link at the bottom of that section points at `releases/tag/v1.1.0`. The three most recent releases are `1.5.7` on 2026-07-28, `1.5.5` on 2026-07-25, and `1.5.4` on 2026-07-25. That is four minor versions of drift, and the drift is not cosmetic because the documented feature set is not the current one. The v1.1.0 notes describe a keep-alive engine that was completely redesigned into two modes, automatic schema migration adding `flag` and `fragment` columns, and a set of bug fixes around theme persistence and the Telegram language toggle. A reader who pins v1.1.0 because the README tells them to gets none of that. The pin is presented as the stability recommendation, in the fork step, as an alternative to tracking `main`, which means the safest documented option is four versions old.
Tag names lost the v prefix and the version numbers skip
The release names are `1.5.7`, `1.5.5`, and `1.5.4`. There is no `v` in front of any of them, and `1.5.6` does not appear between `1.5.5` and `1.5.7`. The README's own links and instructions, on the other hand, use the prefix throughout: the release link target `releases/tag/v1.1.0` and the instruction to pin deployments to release tag `v1.1.0`. If the tags were created without the prefix, then that link does not resolve to a tag and the pin instruction points at a ref that does not exist, which is a deployment step that fails at the point a user least expects it to. A skipped version number is not itself a defect, but combined with a renamed prefix it means the numbering scheme has changed at least once and the documentation did not follow. There is also no CHANGELOG file in the root, so the release pages are the only record.
One file carries a proxy, a scanner, a bot and an analytics engine
The repository root is `.gitignore`, `Dockerfile`, `LICENSE`, `Procfile`, `README-fa.md`, `README.md`, `SulgX-config.toml`, `img/`, `main.py`, `render.yaml`, and `requirements.txt`. The claim of a single Python file is structurally accurate: `main.py` is the only source file, and the Dockerfile copies the whole tree and starts `python main.py`. What lives in that one file, per the feature list, is a FastAPI application with SQLite persistence, JWT cookie sessions with bcrypt password checking, rate limiting, a WebSocket server for VLESS traffic, live speed sampling described as highly accurate with adaptive spike filtering, a 24-hour timezone-aware traffic history, CPU, memory and disk sampling through psutil with loadavg fallbacks, a CIDR-aware scanner, a bilingual Telegram bot with alert events, and a keep-alive engine with two modes and header self-adjustment. Twelve pinned dependencies. None of that can be replaced or tested in isolation without first splitting the file, which is the real cost of the single-file shape.
The only unpinned dependency is a PostgreSQL driver in a SQLite project
`requirements.txt` pins eleven of its twelve entries with exact versions, including `fastapi==0.115.0`, `uvicorn[standard]==0.30.0`, `websockets==14.1`, `httpx==0.27.0`, `psutil==6.0.0`, `bcrypt==4.2.0`, `slowapi==0.1.9`, `python-json-logger==2.0.7`, and `aiosqlite==0.20.0`. One entry uses a floor instead: `asyncpg>=0.28.0`. So the single floating dependency is an asynchronous PostgreSQL driver, in a project the README describes as SQLite-powered and an environment table that configures a SQLite file path. Both database drivers are installed, which means the requirements file cannot tell you which one the application opens. The same file also carries an environment marker on `uvloop`, excluding Windows, and the analytics section offers loadavg fallbacks for system health, a concept that does not exist on the platform the marker is carving out. If you want a reproducible image, that one floor is the gap that will move under you.
EXPOSE 8000, a PORT variable most platforms ignore, and no single source
The Dockerfile is ten lines: a `python:3.11-slim` base, a working directory, a pip upgrade, the requirements copy, a full tree copy, `EXPOSE 8000`, and `CMD ["python", "main.py"]`. The environment table then documents a `PORT` variable whose description reads that it is optional, that it is the port your app listens on, and that most platforms ignore this and use their own. The row is cut off mid-sentence. So the listening port is decided inside `main.py` from an environment variable that the Dockerfile never sets, while the image metadata declares 8000 unconditionally and the `CMD` passes no port argument at all. On a platform that injects its own `PORT`, a program that honours it and an `EXPOSE` line that says 8000 are describing different things, and image metadata is what some orchestrators and humans read first. There is no line in the Dockerfile or the docs that reconciles the two.
The signing key for every session ships as a dictionary phrase
The environment table gives one example value per variable. `ADMIN_PASSWORD` is illustrated with a password that satisfies the stated policy of at least eight characters with upper case, lower case and digits. `SECRET_KEY` is illustrated with the literal string `random_long_string`, and described as the secret key used to sign JWT cookies. That key is the root of trust for the entire authentication system: every session cookie the panel issues is signed with it, and a leaked or guessable value lets anyone mint a cookie for any account. The panel has one operator credential rather than per-user panel accounts, so that single key protects the entire console, including every VLESS inbound, every quota, and the built-in default inbound that the feature list says is protected against deletion. The policy for the password has no maximum length and no symbol requirement, and no documented rotation procedure exists.
The scanner probes four thousand addresses across twenty-four providers
The clean IP feature works by scanning port 443 across twenty-four predefined cloud providers, which are named as Cloudflare, AWS, Azure and others, and attaching discovered addresses to subscriptions. The safety controls described are two: a cap of 4,096 addresses per scan, described as protection against a browser freezing on large CIDR ranges such as a `/14`, and a hardcoded exclusion of one public resolver, 8.8.8.8. That is the entire scope story, and it is worth being blunt about what it lacks. There is no per-host or per-range authorisation check, because the target set is a list of other people's provider ranges rather than hosts you own. There is no dry run or preview described. There is no abort switch in the feature list. And a single hardcoded exclusion does not generalise, since any other public resolver in a scanned range is still a third party. If you run this from a PaaS instance, the probes originate from your own infrastructure. Scope this deliberately or leave it off.
Four deployment descriptors for five recommended platforms
Three deployment paths are committed rather than one. `Dockerfile` is the generic path and the one the README recommends. `render.yaml` is specific to Render. `Procfile` is the generic process declaration that Heroku-style platforms read. `SulgX-config.toml` is a fourth file that no part of the README explains, sitting at the root next to the environment table that is supposed to be the configuration surface. Five platforms are recommended, with Railway named as the top choice for its free credit and persistent volumes, Render for its free tier with persistent disks, Dockfly as minimal, Back4app described as parse-based with a generous free tier, and Scalingo as a French PaaS with a thirty-day trial. Four more are named as working but requiring a card or a phone number. The repository description, meanwhile, names only three platforms. Every recommendation depends on a persistent volume at `/data` for the SQLite file, and the one thing all of them share is that an ephemeral disk loses every inbound and every user's quota.
Editorial conclusion
This is a capable single-file panel with an unusually good deployment story for free-tier hosts, and if your use is running your own VLESS inbounds for people you control it has the pieces: quotas, expiry, concurrent connection limits, audit logs, and rate-limited login. Three things to check before you deploy it. Pin nothing, and read the changelog between 1.1.0 and 1.5.7, because the page you are reading predates four minor versions including a keep-alive redesign and schema migration. Replace both example secrets, since the JWT signing key is the root of trust for every session the panel issues. And decide for yourself whether you want a port scanner that probes third-party provider ranges from your own infrastructure, because that is a decision about someone else's address space, not only about your configuration.
Frequently asked questions
What is the current version of SulgX Panel?
The three newest releases are `1.5.7` on 2026-07-28, `1.5.5` on 2026-07-25, and `1.5.4` on 2026-07-25. The README itself is written around version 1.1.0, four minor versions earlier, and instructs users to pin deployments to the `v1.1.0` tag.
Which environment variables does SulgX Panel need?
`ADMIN_PASSWORD` for the panel login, `SECRET_KEY` to sign JWT cookies, `DOMAIN` for link generation, and `DB_PATH` for the SQLite file. A `PORT` variable is documented as optional, with most platforms supplying their own. The examples given for the first two are a sample password and the literal string `random_long_string`.
How does the SulgX Panel IP scanner limit itself?
It caps each scan at 4,096 addresses to avoid freezing a browser on large CIDR ranges, and it excludes the public resolver 8.8.8.8. No per-host authorisation check, dry run, or abort switch is described, and the target set is 24 predefined cloud provider ranges.
What does SulgX Panel depend on?
Twelve entries in `requirements.txt`, eleven pinned exactly and one not: `asyncpg>=0.28.0` is a floor, and it is a PostgreSQL driver in a project the README describes as SQLite-powered. The Dockerfile runs on `python:3.11-slim`, exposes port 8000, and starts `python main.py`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sulgx-sulgx-panel)