Skip to content

docs: improve Quick Start section - #6348

Open
platilich wants to merge 1 commit into
MHSanaei:mainfrom
platilich:patch-1
Open

docs: improve Quick Start section#6348
platilich wants to merge 1 commit into
MHSanaei:mainfrom
platilich:patch-1

Conversation

@platilich

Copy link
Copy Markdown

Description

Improved the Quick Start section in the README to make it clearer and more user-friendly.

Changes:

  • Moved the recommended installation method (curl ... | sudo bash) to the top
  • Improved structure and readability
  • Added clearer steps after installation
  • Added a note about saving the generated credentials
  • Minor formatting improvements

Why

The previous version had two installation methods without clearly indicating which one is preferred.
Also, new users often forget to save the randomly generated credentials.

This change should reduce confusion for first-time users.

Updated installation instructions to clarify methods for one-line installation, specific version installation, and development build installation.
Comment thread README.md

```bash
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh | sudo bash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 The new "recommended" command silently turns every fresh install into an unattended, HTTP-only install.

install.sh treats a non-TTY stdin as unattended mode, and its own comment names this exact invocation:

3x-ui/install.sh

Lines 43 to 47 in 0cde3b6

# Non-interactive mode: triggered explicitly via XUI_NONINTERACTIVE=1, or
# implicitly when stdin is not a TTY (e.g. `curl ... | bash`, cloud-init).
# In this mode every prompt below is replaced by an env var or a sane default.
if [[ "${XUI_NONINTERACTIVE:-0}" == "1" ]] || [[ ! -t 0 ]]; then
NONINTERACTIVE=1

Piping makes fd 0 the pipe, so [[ ! -t 0 ]] is true → NONINTERACTIVE=1. The replaced bash <(curl -Ls …) form passed /dev/fd/63 as the script file and left stdin on the terminal, so it prompted.

The default that actually changes is SSL:

  • unattended: XUI_SSL_MODE unset → none | "") ssl_choice="4"Skip SSL (install.sh#L828-L832), which sets SSL_SCHEME="http" at L982
  • interactive: anything other than 1/3/4 → ssl_choice="2", Let's Encrypt for the IP (install.sh#L839-L844)

So a user following the new README gets the admin panel on plain HTTP, and the Bind the panel to 127.0.0.1 only? opt-in (L990) is never offered. To be fair, the installer does print a loud warning in that branch (L975-L980) — the user is warned, just never asked.

It also contradicts the section two headings below, which this PR leaves unchanged and which defines piping as the cloud-init path:

3x-ui/README.md

Lines 105 to 110 in 0cde3b6

### Unattended install
The installer also runs **non-interactively** for cloud-init.
Set `XUI_NONINTERACTIVE=1` (or pipe with no TTY) and it installs end-to-end with
zero prompts, generating random credentials and writing them to
`/etc/x-ui/install-result.env`. See [`deploy/`](deploy/) for:

Secondly, this form cannot take a version tag at all: the script reads its tag from $1 (install.sh#L1757), and a piped bash has no positional parameters — it would need | sudo bash -s -- v3.4.0.

Suggest keeping bash <(curl -Ls …) as the recommended form and, if you want a pipe variant documented at all, putting it under Unattended install where its behaviour is already described.

Comment thread README.md
Comment on lines +77 to 91
Alternative method
```bash
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
<(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
```

To install the rolling **dev** build (latest per-commit pre-release from `main`, not a stable release), pass `dev-latest`:
Install a specific version

```bash
<(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
```

Install the latest development build
```bash
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
<(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 All three of these commands lost their leading bash and are no longer runnable. Lines 79, 85 and 90.

<(…) is not a command — bash expands the process substitution to a path like /dev/fd/63 and then tries to execve that pipe, which fails with bash: /dev/fd/63: Permission denied (exit 126). install.sh never runs, and the trailing v3.4.0 / dev-latest is just an argument to the non-command. Under sh/dash it is a syntax error outright.

The bash prefix was present on all three before this PR:

https://github.com/MHSanaei/3x-ui/blob/f727d0470e832c1a2c30d0e3d9e58fb52d15b81c/README.md#L71-L73

Combined with the pipe form above (which cannot accept a positional tag), this leaves no working documented way to install a pinned version or the dev build. These also drop the sudo that the recommended line uses, and install.sh hard-exits for a non-root user:

3x-ui/install.sh

Lines 12 to 14 in 0cde3b6

# check root
[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1

Restoring bash on each of the three blocks fixes all of this, since bash <(…) v3.4.0 does pass $1 through correctly.

Comment thread README.md
<(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
```

Install the latest development build

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The warning that dev-latest is not a stable release was dropped. The previous wording said "the rolling dev build (latest per-commit pre-release from main, not a stable release)"; "the latest development build" now reads like "the newest version", which invites people to run a per-commit pre-release in production. The installer itself warns about exactly this at install.sh#L1455-L1457.

Suggested change
Install the latest development build
Install the rolling **dev** build (latest per-commit pre-release from `main`, not a stable release):

Comment thread README.md
Comment on lines +93 to +102
After installation:

Run the command x-ui
The management menu will open
From there you can view/reset credentials, change port, path, manage SSL certificates, and more

Important: A random username, password, and access path are generated during installation.

Make sure to save them immediately.
Full documentation is available in the project Wiki.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 This block renders worse than what it replaced, which cuts against the PR's stated goal of improving readability.

Three problems, all in these ten lines:

  1. Lines 95–97 have no list markers and no blank lines between them, so GFM soft-wraps them into one paragraph. Rendered, it reads: "Run the command x-ui The management menu will open From there you can view/reset credentials, change port, path, manage SSL certificates, and more". Same for lines 101–102.
  2. x-ui lost its backticks on line 95, so the command name is no longer distinguishable from prose.
  3. The Wiki hyperlink became plain text on line 102 — the URL is gone entirely, and it appears nowhere else in the section. Previously: README.md#L88-L89.

Suggested fix: make 95–97 a real numbered or bulleted list, restore the backticks on x-ui, and restore [project Wiki](https://github.com/MHSanaei/3x-ui/wiki) as a link on its own paragraph.

@github-actions

Copy link
Copy Markdown
Contributor

Code review

2 🔴 / 4 🟡 / 0 🟣

The rewrite is well-intentioned, but it breaks the install commands it reformats. Three of the four blocks are no longer executable, and the one that is now installs the panel differently than the prose around it says.

🔴 Important

  1. Three install commands lost their bash prefix and cannot run — README.md:79, :85, :90. <(curl -Ls …) in command position expands to /dev/fd/63 and bash tries to execute the pipe: Permission denied, exit 126. install.sh never runs. Every documented way to install a pinned version or the dev build is now a copy-paste that fails. (inline)
  2. The new recommended curl … | sudo bash switches installs to unattended, HTTP-only — README.md:74. Piping makes stdin a pipe, so [[ ! -t 0 ]] at install.sh:46 sets NONINTERACTIVE=1 — the script's own comment names curl ... | bash as the trigger. The SSL default then flips from ssl_choice="2" (Let's Encrypt IP cert) to "4" = Skip SSL, which sets SSL_SCHEME="http" (install.sh:828-832, :982 vs :839-844); the loopback-bind opt-in at :990 is never offered; and no version tag can be passed (install_x-ui $1, install.sh:1757). It also contradicts the Unattended install section directly below, which defines "pipe with no TTY" as the cloud-init path. The installer does print a loud warning in the skip-SSL branch, so the user is warned — just never asked. (inline)

🟡 Nits

  1. The dev-latest "not a stable release" warning was dropped; "the latest development build" reads like "newest version". (inline)
  2. The post-install block renders as two run-on paragraphs (no list markers on README.md:95-97 and :101-102), x-ui lost its backticks, and the project Wiki hyperlink became plain text with the URL discarded. (inline)
  3. Only the English README changed, so the install command now diverges from every other place that documents it: README.ru_RU.md, README.zh_CN.md, README.fa_IR.md, README.ar_EG.md, README.es_ES.md, README.tr_TR.md (all at :72, :78, :84), docs/content/docs/{en,ru,zh,fa}/guide/installation.mdx, x-ui.sh:306, and docs/lib/xray/install.ts:29-31, whose buildScriptCommand() still emits bash <(curl -Ls …) and is pinned by golden fixtures in install.test.ts. CLAUDE.md asks for docs/lib/xray/ to be checked whenever install-command output changes. Fixing the two 🔴 items mostly resolves this by reverting to the shared form.
  4. Commit headline Revise installation instructions in README is not a conventional commit — CLAUDE.md requires type(area): short imperative summary from fix|feat|chore|refactor|perf|docs|style. The PR title (docs: improve Quick Start section) is fine, so this only matters if the merge does not squash to the title.

Coverage

  • Head 0cde3b6983d82e868f10e88454bcbc3f4ee8caf1; diff is 1 file, +22/-8, entirely README.md "Quick Start" (lines 69-103).
  • Read all four command blocks and the rewritten prose in the head checkout; compared each against the base form it replaced.
  • Traced install.sh for the claims above: TTY detection (:43-47), SSL choice in both modes (:828-844, :975-982), bind_local (:985-991), panel port (:1198-1214), DB choice (:1077-1086), root check (:13), arg handling (:1451, :1757). Panel port and DB defaults are identical in both modes — not a regression, excluded.
  • Grepped the repo for the same install command: 6 translated READMEs, 4 docs-site installation pages, docs/app/[lang]/(home)/page.tsx, x-ui.sh, docs/lib/xray/install.ts — all still on the old form (finding 5).
  • CI: the only check-runs on this head are issue-analyst, mention, resolve-conflicts (all skipped) and review (in progress). ci.yml is path-filtered to **.go/go.mod/go.sum/frontend/**/.nvmrc/Makefile, so it correctly did not run — there is no build or test evidence for this head, and none is expected for a docs-only change.
  • Not verified by execution: nothing was run. The shell behaviour above is read off install.sh and standard bash process-substitution semantics; executing PR code is not permitted in this job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant