install.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Pure builders for 3x-ui install commands (script + Docker). No React/DOM.
  2. export type InstallMethod = 'script' | 'docker';
  3. export interface InstallOptions {
  4. method: InstallMethod;
  5. /** A release tag like `v3.4.1`, or empty/`latest` for the latest release. */
  6. version: string;
  7. enableFail2ban: boolean;
  8. panelPort: string;
  9. webBasePath: string;
  10. }
  11. const REPO_RAW = 'https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh';
  12. const IMAGE = 'ghcr.io/mhsanaei/3x-ui:latest';
  13. function isLatest(version: string): boolean {
  14. const v = version.trim().toLowerCase();
  15. return v === '' || v === 'latest';
  16. }
  17. /**
  18. * The one-line script install command. The master install script reads the
  19. * version as its first argument: empty = latest stable release, a tag like
  20. * `v3.4.0` = that release, and `dev-latest` = the rolling per-commit dev build.
  21. */
  22. export function buildScriptCommand(options: InstallOptions): string {
  23. if (isLatest(options.version)) {
  24. return `bash <(curl -Ls ${REPO_RAW})`;
  25. }
  26. return `bash <(curl -Ls ${REPO_RAW}) ${options.version.trim()}`;
  27. }
  28. /** A `docker run` command reflecting the chosen options. */
  29. export function buildDockerRun(options: InstallOptions): string {
  30. const lines = ['docker run -itd'];
  31. lines.push(` -e XRAY_VMESS_AEAD_FORCED=false`);
  32. lines.push(` -e XUI_ENABLE_FAIL2BAN=${options.enableFail2ban ? 'true' : 'false'}`);
  33. if (options.panelPort.trim()) lines.push(` -e XUI_PORT=${options.panelPort.trim()}`);
  34. if (options.webBasePath.trim())
  35. lines.push(` -e XUI_INIT_WEB_BASE_PATH=${options.webBasePath.trim()}`);
  36. lines.push(` -v $PWD/db/:/etc/x-ui/`);
  37. lines.push(` -v $PWD/cert/:/root/cert/`);
  38. lines.push(` --network=host`);
  39. lines.push(` --restart=unless-stopped`);
  40. lines.push(` --name 3x-ui`);
  41. lines.push(` ${IMAGE}`);
  42. return lines.join(' \\\n');
  43. }
  44. /** A `docker-compose.yml` reflecting the chosen options. */
  45. export function buildDockerCompose(options: InstallOptions): string {
  46. const env: string[] = [
  47. ` XRAY_VMESS_AEAD_FORCED: 'false'`,
  48. ` XUI_ENABLE_FAIL2BAN: '${options.enableFail2ban ? 'true' : 'false'}'`,
  49. ];
  50. if (options.panelPort.trim()) env.push(` XUI_PORT: '${options.panelPort.trim()}'`);
  51. if (options.webBasePath.trim())
  52. env.push(` XUI_INIT_WEB_BASE_PATH: '${options.webBasePath.trim()}'`);
  53. return [
  54. `services:`,
  55. ` 3x-ui:`,
  56. ` image: ${IMAGE}`,
  57. ` container_name: 3x-ui`,
  58. ` volumes:`,
  59. ` - ./db/:/etc/x-ui/`,
  60. ` - ./cert/:/root/cert/`,
  61. ` environment:`,
  62. ...env,
  63. ` network_mode: host`,
  64. ` restart: unless-stopped`,
  65. ].join('\n');
  66. }