diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 344b95ee..d0b31d4d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -29,3 +29,4 @@ _(Optional: add before/after screenshots, GIFs, or console output)_ - [ ] Code follows project style guidelines - [ ] Supports mobile and desktop UI/app (if applicable) - [ ] I have read [Contributing.md](https://github.com/Termix-SSH/Termix/blob/main/CONTRIBUTING.md) +- [ ] This is not a translation request. See [docs](https://docs.termix.site/translations) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 34f78ea8..d5352b14 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -17,7 +17,7 @@ on: jobs: build: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-8vcpu-ubuntu-2404 steps: - name: Checkout repository uses: actions/checkout@v5 diff --git a/.github/workflows/electron.yml b/.github/workflows/electron.yml index 7c087e03..56ed3acb 100644 --- a/.github/workflows/electron.yml +++ b/.github/workflows/electron.yml @@ -688,7 +688,7 @@ jobs: retention-days: 30 submit-to-flatpak: - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'linux' || github.event.inputs.build_type == '') needs: [] permissions: diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 5d0df61f..664c9538 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -6,7 +6,7 @@ on: jobs: lint-and-build: - runs-on: ubuntu-latest + runs-on: blacksmith-2vcpu-ubuntu-2404 steps: - name: Checkout code diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml deleted file mode 100644 index 7c9db568..00000000 --- a/.github/workflows/translate.yml +++ /dev/null @@ -1,437 +0,0 @@ -name: Auto Translate - -on: - workflow_dispatch: - -permissions: - contents: write - pull-requests: write - -jobs: - translate-zh: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t zh --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-zh - path: src/locales/zh.json - continue-on-error: true - - translate-ru: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ru --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-ru - path: src/locales/ru.json - continue-on-error: true - - translate-pt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t pt --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-pt - path: src/locales/pt.json - continue-on-error: true - - translate-fr: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t fr --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-fr - path: src/locales/fr.json - continue-on-error: true - - translate-es: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t es --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-es - path: src/locales/es.json - continue-on-error: true - - translate-de: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t de --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-de - path: src/locales/de.json - continue-on-error: true - - translate-hi: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t hi --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-hi - path: src/locales/hi.json - continue-on-error: true - - translate-bn: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t bn --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-bn - path: src/locales/bn.json - continue-on-error: true - - translate-ja: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ja --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-ja - path: src/locales/ja.json - continue-on-error: true - - translate-vi: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t vi --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-vi - path: src/locales/vi.json - continue-on-error: true - - translate-tr: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t tr --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-tr - path: src/locales/tr.json - continue-on-error: true - - translate-ko: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ko --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-ko - path: src/locales/ko.json - continue-on-error: true - - translate-it: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t it --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-it - path: src/locales/it.json - continue-on-error: true - - translate-he: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t he --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-he - path: src/locales/he.json - continue-on-error: true - - translate-ar: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ar --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-ar - path: src/locales/ar.json - continue-on-error: true - - translate-pl: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t pl --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-pl - path: src/locales/pl.json - continue-on-error: true - - translate-nl: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t nl --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-nl - path: src/locales/nl.json - continue-on-error: true - - translate-sv: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t sv --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-sv - path: src/locales/sv.json - continue-on-error: true - - translate-id: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t id --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-id - path: src/locales/id.json - continue-on-error: true - - translate-th: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t th --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-th - path: src/locales/th.json - continue-on-error: true - - translate-uk: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t uk --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-uk - path: src/locales/uk.json - continue-on-error: true - - translate-cs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t cs --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-cs - path: src/locales/cs.json - continue-on-error: true - - translate-ro: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ro --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-ro - path: src/locales/ro.json - continue-on-error: true - - translate-el: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t el --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-el - path: src/locales/el.json - continue-on-error: true - - translate-nb: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: "20" - - run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t nb --maxLinesPerRequest 1 - - uses: actions/upload-artifact@v4 - with: - name: translations-nb - path: src/locales/nb.json - continue-on-error: true - - create-pr: - needs: - [ - translate-zh, - translate-ru, - translate-pt, - translate-fr, - translate-es, - translate-de, - translate-hi, - translate-bn, - translate-ja, - translate-vi, - translate-tr, - translate-ko, - translate-it, - translate-he, - translate-ar, - translate-pl, - translate-nl, - translate-sv, - translate-id, - translate-th, - translate-uk, - translate-cs, - translate-ro, - translate-el, - translate-nb, - ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.GHCR_TOKEN }} - - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: translations-temp - - - name: Move translations to src/locales - run: | - cp translations-temp/translations-zh/zh.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-ru/ru.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-pt/pt.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-fr/fr.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-es/es.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-de/de.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-hi/hi.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-bn/bn.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-ja/ja.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-vi/vi.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-tr/tr.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-ko/ko.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-it/it.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-he/he.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-ar/ar.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-pl/pl.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-nl/nl.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-sv/sv.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-id/id.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-th/th.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-uk/uk.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-cs/cs.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-ro/ro.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-el/el.json src/locales/ 2>/dev/null || true - cp translations-temp/translations-nb/nb.json src/locales/ 2>/dev/null || true - rm -rf translations-temp - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 - with: - token: ${{ secrets.GHCR_TOKEN }} - commit-message: "chore: auto-translate to multiple languages" - branch: translations-update - delete-branch: true - title: "chore: Update translations for all languages" diff --git a/README-CN.md b/README-CN.md index 593c6a23..5c224730 100644 --- a/README-CN.md +++ b/README-CN.md @@ -16,17 +16,6 @@ 2025年9月1日获得

-#### 核心技术 - -[![React Badge](https://img.shields.io/badge/-React-61DBFB?style=flat-square&labelColor=black&logo=react&logoColor=61DBFB)](#) -[![TypeScript Badge](https://img.shields.io/badge/-TypeScript-3178C6?style=flat-square&labelColor=black&logo=typescript&logoColor=3178C6)](#) -[![Node.js Badge](https://img.shields.io/badge/-Node.js-3C873A?style=flat-square&labelColor=black&logo=node.js&logoColor=3C873A)](#) -[![Vite Badge](https://img.shields.io/badge/-Vite-646CFF?style=flat-square&labelColor=black&logo=vite&logoColor=646CFF)](#) -[![Tailwind CSS Badge](https://img.shields.io/badge/-TailwindCSS-38B2AC?style=flat-square&labelColor=black&logo=tailwindcss&logoColor=38B2AC)](#) -[![Docker Badge](https://img.shields.io/badge/-Docker-2496ED?style=flat-square&labelColor=black&logo=docker&logoColor=2496ED)](#) -[![SQLite Badge](https://img.shields.io/badge/-SQLite-003B57?style=flat-square&labelColor=black&logo=sqlite&logoColor=003B57)](#) -[![Radix UI Badge](https://img.shields.io/badge/-Radix%20UI-161618?style=flat-square&labelColor=black&logo=radixui&logoColor=161618)](#) -

@@ -61,12 +50,14 @@ Termix 是一个开源、永久免费、自托管的一体化服务器管理平 - **数据导出/导入** - 导出和导入 SSH 主机、凭据和文件管理器数据 - **自动 SSL 设置** - 内置 SSL 证书生成和管理,支持 HTTPS 重定向 - **现代用户界面** - 使用 React、Tailwind CSS 和 Shadcn 构建的简洁的桌面/移动设备友好界面。可选择基于深色或浅色模式的用户界面。 -- **语言** - 内置支持约 30 种语言(通过 Google 翻译批量翻译,结果可能有所不同) -- **平台支持** - 可作为 Web 应用程序、桌面应用程序(Windows、Linux 和 macOS)以及适用于 iOS 和 Android 的专用移动/平板电脑应用程序。 +- **语言** - 内置支持约 30 种语言(由 [Crowdin](https://docs.termix.site/translations) 管理) +- **平台支持** - 可作为 Web 应用程序、桌面应用程序(Windows、Linux 和 macOS)、PWA 以及适用于 iOS 和 Android 的专用移动/平板电脑应用程序。 - **SSH 工具** - 创建可重用的命令片段,单击即可执行。在多个打开的终端上同时运行一个命令。 - **命令历史** - 自动完成并查看以前运行的 SSH 命令 +- **快速连接** - 无需保存连接数据即可连接到服务器 - **命令面板** - 双击左 Shift 键可快速使用键盘访问 SSH 连接 -- **SSH 功能丰富** - 支持跳板机、warpgate、基于 TOTP 的连接、SOCKS5、密码自动填充等。 +- **SSH 功能丰富** - 支持跳板机、Warpgate、基于 TOTP 的连接、SOCKS5、密码自动填充等。 +- **网络图** - 自定义您的仪表板,根据您的 SSH 连接可视化您的家庭实验室,支持状态显示 # 计划功能 @@ -76,20 +67,21 @@ Termix 是一个开源、永久免费、自托管的一体化服务器管理平 支持的设备: -- 网站(任何平台上的任何现代浏览器,如 Chrome、Safari 和 Firefox) +- 网站(任何平台上的任何现代浏览器,如 Chrome、Safari 和 Firefox)(包括 PWA 支持) - Windows(x64/ia32) - 便携版 - MSI 安装程序 - - Chocolatey 软件包管理器(即将推出) + - Chocolatey 软件包管理器 - Linux(x64/ia32) - 便携版 + - AUR - AppImage - Deb - - Flatpak(即将推出) + - Flatpak - macOS(x64/ia32 on v12.0+) - - Apple App Store(即将推出) + - Apple App Store - DMG - - Homebrew(即将推出) + - Homebrew - iOS/iPadOS(v15.1+) - Apple App Store - ISO @@ -117,6 +109,22 @@ volumes: driver: local ``` +# 赞助商 + +

+ + DigitalOcean + +          + + Crowdin + +          + + Crowdin + +

+ # 支持 如果你需要 Termix 的帮助或想要请求功能,请访问 [Issues](https://github.com/Termix-SSH/Support/issues) 页面,登录并点击 `New Issue`。 @@ -125,6 +133,8 @@ volumes: # 展示 +[![](https://utfs.io/f/nGnSqDveMsqxqiKJF5EnObSopHatulx93N0E1KVsP7hvjMfF)](https://www.youtube.com/watch?v=j1_I1mkhUkE) +

Termix Demo 1 Termix Demo 2 @@ -147,14 +157,14 @@ volumes:

Termix Demo 9 - Termix Demo 110 + Termix Demo 10

- + Termix Demo 11 + Termix Demo 12

+ 某些视频和图像可能已过时或可能无法完美展示功能。 # 许可证 diff --git a/README.md b/README.md index d01a3aab..4fcf603e 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,6 @@ Achieved on September 1st, 2025

-#### Top Technologies - -[![React Badge](https://img.shields.io/badge/-React-61DBFB?style=flat-square&labelColor=black&logo=react&logoColor=61DBFB)](#) -[![TypeScript Badge](https://img.shields.io/badge/-TypeScript-3178C6?style=flat-square&labelColor=black&logo=typescript&logoColor=3178C6)](#) -[![Node.js Badge](https://img.shields.io/badge/-Node.js-3C873A?style=flat-square&labelColor=black&logo=node.js&logoColor=3C873A)](#) -[![Vite Badge](https://img.shields.io/badge/-Vite-646CFF?style=flat-square&labelColor=black&logo=vite&logoColor=646CFF)](#) -[![Tailwind CSS Badge](https://img.shields.io/badge/-TailwindCSS-38B2AC?style=flat-square&labelColor=black&logo=tailwindcss&logoColor=38B2AC)](#) -[![Docker Badge](https://img.shields.io/badge/-Docker-2496ED?style=flat-square&labelColor=black&logo=docker&logoColor=2496ED)](#) -[![SQLite Badge](https://img.shields.io/badge/-SQLite-003B57?style=flat-square&labelColor=black&logo=sqlite&logoColor=003B57)](#) -[![Radix UI Badge](https://img.shields.io/badge/-Radix%20UI-161618?style=flat-square&labelColor=black&logo=radixui&logoColor=161618)](#) -

@@ -51,24 +40,26 @@ free and self-hosted alternative to Termius available for all platforms. # Features - **SSH Terminal Access** - Full-featured terminal with split-screen support (up to 4 panels) with a browser-like tab system. Includes support for customizing the terminal including common terminal themes, fonts, and other components -- **SSH Tunnel Management** - Create and manage SSH tunnels with automatic reconnection and health monitoring -- **Remote File Manager** - Manage files directly on remote servers with support for viewing and editing code, images, audio, and video. Upload, download, rename, delete, and move files seamlessly +- **SSH Tunnel Management** - Create and manage SSH tunnels with automatic reconnection and health monitoring and support for -l or -r connections +- **Remote File Manager** - Manage files directly on remote servers with support for viewing and editing code, images, audio, and video. Upload, download, rename, delete, and move files seamlessly with sudo support. - **Docker Management** - Start, stop, pause, remove containers. View container stats. Control container using docker exec terminal. It was not made to replace Portainer or Dockge but rather to simply manage your containers compared to creating them. - **SSH Host Manager** - Save, organize, and manage your SSH connections with tags and folders, and easily save reusable login info while being able to automate the deployment of SSH keys -- **Server Stats** - View CPU, memory, and disk usage along with network, uptime, and system information on any SSH server +- **Server Stats** - View CPU, memory, and disk usage along with network, uptime, system information, firewall, port monitor, on most Linux based servers - **Dashboard** - View server information at a glance on your dashboard - **RBAC** - Create roles and share hosts across users/roles - **User Authentication** - Secure user management with admin controls and OIDC and 2FA (TOTP) support. View active user sessions across all platforms and revoke permissions. Link your OIDC/Local accounts together. - **Database Encryption** - Backend stored as encrypted SQLite database files. View [docs](https://docs.termix.site/security) for more. - **Data Export/Import** - Export and import SSH hosts, credentials, and file manager data - **Automatic SSL Setup** - Built-in SSL certificate generation and management with HTTPS redirects -- **Modern UI** - Clean desktop/mobile-friendly interface built with React, Tailwind CSS, and Shadcn. Choose between dark or light mode based UI. -- **Languages** - Built-in support ~30 languages (bulk translated via Google Translate, results may vary ofc) -- **Platform Support** - Available as a web app, desktop application (Windows, Linux, and macOS), and dedicated mobile/tablet app for iOS and Android. +- **Modern UI** - Clean desktop/mobile-friendly interface built with React, Tailwind CSS, and Shadcn. Choose between dark or light mode based UI. Use URL routes to open any connection in full-screen. +- **Languages** - Built-in support ~30 languages (managed by [Crowdin](https://docs.termix.site/translations)) +- **Platform Support** - Available as a web app, desktop application (Windows, Linux, and macOS), PWA, and dedicated mobile/tablet app for iOS and Android. - **SSH Tools** - Create reusable command snippets that execute with a single click. Run one command simultaneously across multiple open terminals. - **Command History** - Auto-complete and view previously ran SSH commands +- **Quick Connect** - Connect to a server without having to save the connection data - **Command Palette** - Double tap left shift to quickly access SSH connections with your keyboard -- **SSH Feature Rich** - Supports jump hosts, warpgate, TOTP based connections, SOCKS5, password autofill, etc. +- **SSH Feature Rich** - Supports jump hosts, Warpgate, TOTP based connections, SOCKS5, password autofill, etc. +- **Network Graph** - Customize your Dashboard to visualize your homelab based off your SSH connections with status support # Planned Features @@ -78,13 +69,14 @@ See [Projects](https://github.com/orgs/Termix-SSH/projects/2) for all planned fe Supported Devices: -- Website (any modern browser on any platform like Chrome, Safari, and Firefox) +- Website (any modern browser on any platform like Chrome, Safari, and Firefox) (includes PWA support) - Windows (x64/ia32) - Portable - MSI Installer - Chocolatey Package Manager - Linux (x64/ia32) - - Portable [(AUR available)](https://aur.archlinux.org/packages/termix-bin) + - Portable + - AUR - AppImage - Deb - Flatpak @@ -120,6 +112,22 @@ volumes: driver: local ``` +# Sponsors + +

+ + DigitalOcean + +          + + Crowdin + +          + + Crowdin + +

+ # Support If you need help or want to request a feature with Termix, visit the [Issues](https://github.com/Termix-SSH/Support/issues) page, log in, and press `New Issue`. @@ -128,6 +136,8 @@ channel, however, response times may be longer. # Screenshots +[![](https://utfs.io/f/nGnSqDveMsqxqiKJF5EnObSopHatulx93N0E1KVsP7hvjMfF)](https://www.youtube.com/watch?v=j1_I1mkhUkE) +

Termix Demo 1 Termix Demo 2 @@ -150,14 +160,14 @@ channel, however, response times may be longer.

Termix Demo 9 - Termix Demo 110 + Termix Demo 10

- + Termix Demo 11 + Termix Demo 12

+ Some videos and images may be out of date or may not perfectly showcase features. # License diff --git a/docker/Dockerfile b/docker/Dockerfile index ae669003..38869770 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -74,6 +74,9 @@ VOLUME ["/app/data"] EXPOSE ${PORT} 30001 30002 30003 30004 30005 30006 +HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ + CMD node -e "require('http').get('http://localhost:30001/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))" + COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh diff --git a/docker/nginx-https.conf b/docker/nginx-https.conf index 7788848b..3e0b389f 100644 --- a/docker/nginx-https.conf +++ b/docker/nginx-https.conf @@ -1,3 +1,5 @@ +worker_processes 1; +master_process off; pid /app/nginx/nginx.pid; error_log /app/nginx/logs/error.log warn; @@ -199,6 +201,18 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /ssh/quick-connect { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /ssh/ { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; @@ -267,6 +281,15 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /ssh/file_manager/sudo-password { + proxy_pass http://127.0.0.1:30004; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /ssh/file_manager/ssh/ { client_max_body_size 5G; client_body_timeout 300s; @@ -286,6 +309,15 @@ http { proxy_buffering off; } + location ~ ^/network-topology(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /health { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; @@ -335,6 +367,15 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location ~ ^/dashboard/preferences(/.*)?$ { + proxy_pass http://127.0.0.1:30006; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location ^~ /docker/console/ { proxy_pass http://127.0.0.1:30008/; proxy_http_version 1.1; diff --git a/docker/nginx.conf b/docker/nginx.conf index ac6b7112..5637cb6c 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -1,3 +1,5 @@ +worker_processes 1; +master_process off; pid /app/nginx/nginx.pid; error_log /app/nginx/logs/error.log warn; @@ -188,6 +190,18 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /ssh/quick-connect { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /ssh/ { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; @@ -256,6 +270,15 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /ssh/file_manager/sudo-password { + proxy_pass http://127.0.0.1:30004; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /ssh/file_manager/ssh/ { client_max_body_size 5G; client_body_timeout 300s; @@ -275,6 +298,15 @@ http { proxy_buffering off; } + location ~ ^/network-topology(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /health { proxy_pass http://127.0.0.1:30001; proxy_http_version 1.1; @@ -324,6 +356,15 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location ~ ^/dashboard/preferences(/.*)?$ { + proxy_pass http://127.0.0.1:30006; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location ^~ /docker/console/ { proxy_pass http://127.0.0.1:30008/; proxy_http_version 1.1; diff --git a/index.html b/index.html index b376f7cd..09531776 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,16 @@ + + + + + + + Termix