mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
Compare commits
35
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b309e9582 | ||
|
|
40df00bd95 | ||
|
|
6c342f3957 | ||
|
|
c019f4a9c9 | ||
|
|
0ce0fe71a6 | ||
|
|
6b708106e1 | ||
|
|
5786eaccbb | ||
|
|
307667ce0f | ||
|
|
28e74de452 | ||
|
|
3643e7af97 | ||
|
|
49fa488093 | ||
|
|
dc8287c22f | ||
|
|
961d18455b | ||
|
|
86befa4977 | ||
|
|
99506899da | ||
|
|
4a17b6ef02 | ||
|
+16 |
fef8a5f28a | ||
|
|
9c04860821 | ||
|
|
e3cc72f1dd | ||
|
|
4a76cfcde7 | ||
|
|
b6cd2a6b5c | ||
|
|
1282bf6b71 | ||
|
|
42f8270c20 | ||
|
|
749dc3d865 | ||
|
|
8f7501203b | ||
|
|
46d4626f03 | ||
|
|
80191409e8 | ||
|
|
a6874cea95 | ||
|
|
fbf267fe5f | ||
|
|
76fd9eedbf | ||
|
|
566b908daf | ||
|
|
d6e8ee4784 | ||
|
|
8af4cbdec4 | ||
|
|
e17b21ff62 | ||
|
|
a15372a224 |
No files matched your search
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Resolve newest dev branch and compute beta version
|
||||
id: dev
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
REFS=$(gh api "repos/${{ github.repository }}/branches" --paginate -q '.[].name')
|
||||
if DEV_BRANCH=$(printf '%s\n' "$REFS" | node scripts/latest-dev-branch.cjs 2>/dev/null); then
|
||||
@@ -75,17 +75,24 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build plugin SDK
|
||||
run: npm run build:sdk
|
||||
|
||||
- name: Run ESLint
|
||||
run: npx eslint .
|
||||
|
||||
- name: Type check
|
||||
run: npm run type-check
|
||||
|
||||
# Before the tests: the plugin boot tests load the built bundles.
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Run unit tests
|
||||
run: npm run test
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Run plugin tests
|
||||
run: npm run test:plugins
|
||||
|
||||
create-release:
|
||||
needs: [prep, verify]
|
||||
@@ -103,22 +110,42 @@ jobs:
|
||||
- name: Resolve previous beta commit
|
||||
id: prev
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
SHA="${{ needs.prep.outputs.sha }}"
|
||||
PREV_SHA=$(gh release view beta --repo ${{ github.repository }} --json targetCommitish -q .targetCommitish 2>/dev/null || true)
|
||||
if [ -n "$PREV_SHA" ] && git cat-file -e "$PREV_SHA" 2>/dev/null && git merge-base --is-ancestor "$PREV_SHA" "${{ needs.prep.outputs.sha }}"; then
|
||||
echo "sha=$PREV_SHA" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "sha=" >> "$GITHUB_OUTPUT"
|
||||
if [ -z "$PREV_SHA" ] || ! git cat-file -e "$PREV_SHA^{commit}" 2>/dev/null; then
|
||||
PREV_SHA=$(git rev-parse -q --verify "refs/tags/beta^{commit}" || true)
|
||||
fi
|
||||
# The last beta may come from an older dev branch, so diff from where the two meet.
|
||||
if [ -n "$PREV_SHA" ] && ! git merge-base --is-ancestor "$PREV_SHA" "$SHA"; then
|
||||
PREV_SHA=$(git merge-base "$PREV_SHA" "$SHA" || true)
|
||||
fi
|
||||
echo "Previous beta commit: ${PREV_SHA:-none}"
|
||||
echo "sha=$PREV_SHA" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate rolling beta release notes
|
||||
run: |
|
||||
if [ -n "${{ steps.prev.outputs.sha }}" ]; then
|
||||
CHANGES=$(git log --oneline --no-merges "${{ steps.prev.outputs.sha }}..${{ needs.prep.outputs.sha }}" -- . ':!package-lock.json' | sed 's/^/- /')
|
||||
fi
|
||||
if [ -z "$CHANGES" ]; then
|
||||
CHANGES="- No new commits since the last beta."
|
||||
PREV="${{ steps.prev.outputs.sha }}"
|
||||
SHA="${{ needs.prep.outputs.sha }}"
|
||||
MAX=150
|
||||
if [ -z "$PREV" ]; then
|
||||
CHANGES="- Could not find the previous beta commit."
|
||||
else
|
||||
LOG=$(git log --oneline --no-merges "$PREV..$SHA" -- . ':!package-lock.json')
|
||||
COUNT=$(printf '%s' "$LOG" | grep -c . || true)
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
CHANGES="- No new commits since the last beta."
|
||||
else
|
||||
CHANGES=$(printf '%s\n' "$LOG" | head -n "$MAX" | sed 's/^/- /')
|
||||
if [ "$COUNT" -gt "$MAX" ]; then
|
||||
CHANGES="$CHANGES
|
||||
- ...and $((COUNT - MAX)) more"
|
||||
fi
|
||||
CHANGES="$CHANGES
|
||||
|
||||
[Full diff](https://github.com/${{ github.repository }}/compare/$PREV...$SHA)"
|
||||
fi
|
||||
fi
|
||||
|
||||
cat > BETA_RELEASE_BODY.md << EOF
|
||||
@@ -138,11 +165,14 @@ jobs:
|
||||
|
||||
- name: Create or update rolling beta release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
TAG="beta"
|
||||
TITLE="Beta (rolling) - ${{ needs.prep.outputs.beta_version }}"
|
||||
if gh release view "$TAG" --repo ${{ github.repository }} >/dev/null 2>&1; then
|
||||
# --target only applies to a new tag, so move the existing one by hand.
|
||||
gh api -X PATCH "repos/${{ github.repository }}/git/refs/tags/$TAG" \
|
||||
-f sha="${{ needs.prep.outputs.sha }}" -F force=true >/dev/null
|
||||
gh release edit "$TAG" --repo ${{ github.repository }} \
|
||||
--title "$TITLE" --notes-file BETA_RELEASE_BODY.md \
|
||||
--prerelease --target "${{ needs.prep.outputs.sha }}"
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ steps.branch.outputs.name }}
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GHCR_TOKEN }}
|
||||
token: ${{ secrets.TERMIX_PAT }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v7
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Upload sources to Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
uses: crowdin/github-action@v3
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
@@ -51,13 +51,13 @@ jobs:
|
||||
env:
|
||||
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_KEY }}
|
||||
|
||||
- name: Machine pre-translate untranslated strings
|
||||
- name: Pre-translate untranslated strings
|
||||
env:
|
||||
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
|
||||
run: node scripts/crowdin-pretranslate.cjs
|
||||
|
||||
- name: Download translations from Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
uses: crowdin/github-action@v3
|
||||
with:
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
git config user.name "LukeGus"
|
||||
git config user.email "bugattiguy527@gmail.com"
|
||||
|
||||
git add src/ui/locales/translated
|
||||
git add src/ui/locales/translated plugins/*/locales/translated
|
||||
if git diff --cached --quiet; then
|
||||
echo "No translation changes to commit."
|
||||
exit 0
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Resolve newest dev branch
|
||||
id: dev
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
REFS=$(gh api "repos/${{ github.repository }}/branches" --paginate -q '.[].name')
|
||||
# The helper exits non-zero when no dev-X.Y.Z branch exists; treat that
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: Retarget and merge Dependabot PRs
|
||||
if: ${{ steps.dev.outputs.branch != '' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
DEV_BRANCH: ${{ steps.dev.outputs.branch }}
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
name: Deploy Helm
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
namespace:
|
||||
description: "Kubernetes namespace"
|
||||
required: true
|
||||
default: termix
|
||||
release:
|
||||
description: "Helm release name"
|
||||
required: true
|
||||
default: termix
|
||||
values_file:
|
||||
description: "Values file to use"
|
||||
required: true
|
||||
default: charts/termix/values-gitops-example.yaml
|
||||
image_tag:
|
||||
description: "Image tag to deploy"
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
environment: production
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v5
|
||||
with:
|
||||
version: v3.15.4
|
||||
|
||||
- name: Configure kubeconfig
|
||||
env:
|
||||
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
|
||||
run: |
|
||||
test -n "$KUBE_CONFIG"
|
||||
echo "$KUBE_CONFIG" | base64 -d > "$RUNNER_TEMP/kubeconfig"
|
||||
chmod 600 "$RUNNER_TEMP/kubeconfig"
|
||||
|
||||
- name: Lint chart
|
||||
run: helm lint charts/termix
|
||||
|
||||
- name: Deploy
|
||||
env:
|
||||
KUBECONFIG: ${{ runner.temp }}/kubeconfig
|
||||
IMAGE_TAG: ${{ inputs.image_tag }}
|
||||
RELEASE_NAME: ${{ inputs.release }}
|
||||
TARGET_NAMESPACE: ${{ inputs.namespace }}
|
||||
VALUES_FILE: ${{ inputs.values_file }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
[[ "$RELEASE_NAME" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]
|
||||
[[ "$TARGET_NAMESPACE" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]
|
||||
case "$VALUES_FILE" in
|
||||
charts/termix/*.yaml) ;;
|
||||
*) echo "values_file must be a YAML file under charts/termix" >&2; exit 1 ;;
|
||||
esac
|
||||
test -f "$VALUES_FILE"
|
||||
ARGS=()
|
||||
if [ -n "$IMAGE_TAG" ]; then
|
||||
ARGS+=(--set "image.tag=$IMAGE_TAG")
|
||||
fi
|
||||
helm upgrade --install "$RELEASE_NAME" charts/termix \
|
||||
--namespace "$TARGET_NAMESPACE" \
|
||||
--create-namespace \
|
||||
--values "$VALUES_FILE" \
|
||||
--atomic \
|
||||
--timeout 10m \
|
||||
"${ARGS[@]}"
|
||||
@@ -61,6 +61,8 @@ jobs:
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: useblacksmith/setup-docker-builder@v2
|
||||
with:
|
||||
cache-key: termix-ssh/termix
|
||||
|
||||
- name: Determine tags
|
||||
id: tags
|
||||
@@ -98,7 +100,7 @@ jobs:
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: lukegus
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
password: ${{ secrets.TERMIX_PAT }}
|
||||
|
||||
- name: Login to Docker Hub (prod and beta only)
|
||||
if: ${{ (inputs.build_type == 'Production' || inputs.build_type == 'Beta') && !inputs.dry_run }}
|
||||
@@ -121,8 +123,6 @@ jobs:
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ env.SOURCE_SHA }}
|
||||
org.opencontainers.image.created=${{ github.run_id }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: ${{ inputs.dry_run && 'type=cacheonly' || 'type=registry,compression=zstd' }}
|
||||
|
||||
- name: Cleanup Docker
|
||||
|
||||
@@ -427,6 +427,7 @@ jobs:
|
||||
npm ci
|
||||
npm install --force @rollup/rollup-darwin-arm64
|
||||
npm install dmg-license
|
||||
node scripts/install-macos-sharp.cjs
|
||||
|
||||
- name: Check for Code Signing Certificates
|
||||
id: check_certs
|
||||
@@ -538,12 +539,27 @@ jobs:
|
||||
fi
|
||||
npx electron-builder --mac dmg --universal --x64 --arm64 --publish never
|
||||
|
||||
- name: Verify macOS sharp packaging
|
||||
run: |
|
||||
artifacts=(release/termix_macos_*_dmg.dmg)
|
||||
MAS_PKG=$(find release -name "termix_macos_universal_mas.pkg" -type f | head -n 1)
|
||||
if [ -n "$MAS_PKG" ]; then
|
||||
artifacts+=("$MAS_PKG")
|
||||
fi
|
||||
node scripts/verify-macos-sharp.cjs "${artifacts[@]}"
|
||||
|
||||
- name: Locate macOS MAS PKG
|
||||
id: locate_mas_pkg
|
||||
run: |
|
||||
MAS_PKG=$(find release -name "termix_macos_universal_mas.pkg" -type f | head -n 1)
|
||||
echo "path=$MAS_PKG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload macOS MAS PKG
|
||||
if: steps.check_certs.outputs.has_certs == 'true' && hashFiles('release/termix_macos_universal_mas.pkg') != '' && (inputs.artifact_destination == 'file' || inputs.artifact_destination == 'release' || inputs.artifact_destination == 'submit')
|
||||
if: steps.check_certs.outputs.has_certs == 'true' && steps.locate_mas_pkg.outputs.path != '' && (inputs.artifact_destination == 'file' || inputs.artifact_destination == 'release' || inputs.artifact_destination == 'submit')
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: termix_macos_universal_mas
|
||||
path: release/termix_macos_universal_mas.pkg
|
||||
path: ${{ steps.locate_mas_pkg.outputs.path }}
|
||||
retention-days: 30
|
||||
if-no-files-found: warn
|
||||
|
||||
@@ -923,6 +939,9 @@ jobs:
|
||||
echo "dmg_name=$DMG_NAME" >> $GITHUB_OUTPUT
|
||||
echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Verify macOS sharp packaging
|
||||
run: node scripts/verify-macos-sharp.cjs release_asset/termix_macos_universal_dmg.dmg
|
||||
|
||||
- name: Prepare Homebrew submission files
|
||||
run: |
|
||||
VERSION="${{ steps.package-version.outputs.version }}"
|
||||
@@ -1013,6 +1032,7 @@ jobs:
|
||||
npm ci
|
||||
npm install --force @rollup/rollup-darwin-arm64
|
||||
npm install dmg-license
|
||||
node scripts/install-macos-sharp.cjs
|
||||
|
||||
- name: Check for Code Signing Certificates
|
||||
id: check_certs
|
||||
@@ -1154,6 +1174,16 @@ jobs:
|
||||
BUILD_VERSION="${{ steps.build_number.outputs.build_version || github.run_number }}"
|
||||
npm run build && npx electron-builder --mac mas --universal --config.buildVersion="$BUILD_VERSION"
|
||||
|
||||
- name: Verify macOS sharp packaging
|
||||
if: steps.check_certs.outputs.has_certs == 'true'
|
||||
run: |
|
||||
MAS_PKG=$(find release -name "termix_macos_universal_mas.pkg" -type f | head -n 1)
|
||||
if [ -z "$MAS_PKG" ]; then
|
||||
echo "MAS pkg not found under release/; aborting."
|
||||
exit 1
|
||||
fi
|
||||
node scripts/verify-macos-sharp.cjs "$MAS_PKG"
|
||||
|
||||
- name: Generate App Store release notes
|
||||
id: asc_notes
|
||||
if: steps.check_certs.outputs.has_certs == 'true' && steps.check_asc_creds.outputs.has_credentials == 'true'
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
name: Helm
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "charts/**"
|
||||
- ".github/workflows/helm.yml"
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "charts/**"
|
||||
- ".github/workflows/helm.yml"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
publish:
|
||||
description: "Publish chart to GHCR OCI registry"
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v5
|
||||
with:
|
||||
version: v3.15.4
|
||||
|
||||
- name: Lint chart
|
||||
run: helm lint charts/termix
|
||||
|
||||
- name: Render default chart
|
||||
run: helm template termix charts/termix --namespace termix
|
||||
|
||||
- name: Render GitOps example
|
||||
run: helm template termix charts/termix --values charts/termix/values-gitops-example.yaml --namespace termix
|
||||
|
||||
- name: Render Traefik example
|
||||
run: helm template termix charts/termix --values charts/termix/values-traefik.yaml --namespace termix
|
||||
|
||||
publish:
|
||||
needs: lint
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.publish
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v5
|
||||
with:
|
||||
version: v3.15.4
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io --username "${{ github.actor }}" --password-stdin
|
||||
|
||||
- name: Package chart
|
||||
run: helm package charts/termix --destination .helm-packages
|
||||
|
||||
- name: Push chart
|
||||
run: |
|
||||
OWNER="$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')"
|
||||
helm push .helm-packages/termix-*.tgz "oci://ghcr.io/$OWNER/charts"
|
||||
@@ -24,6 +24,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build plugin SDK
|
||||
run: npm run build:sdk
|
||||
|
||||
- name: Lint
|
||||
# npm run lint, not npx eslint — the script also checks that the
|
||||
# generated dialect schemas match schema.ts, which eslint cannot see.
|
||||
@@ -38,6 +41,12 @@ jobs:
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Run unit tests
|
||||
run: npm run test
|
||||
|
||||
- name: Run plugin tests
|
||||
run: npm run test:plugins
|
||||
|
||||
database-dialects:
|
||||
name: Postgres and MySQL
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
@@ -88,6 +97,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build plugin SDK
|
||||
run: npm run build:sdk
|
||||
|
||||
# Each run applies the migrations to an empty database first, so a
|
||||
# migration that does not apply cleanly fails the build.
|
||||
- name: Verify Postgres
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: Redirect issues
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
close:
|
||||
if: github.event.issue.author_association != 'OWNER' && github.event.issue.author_association != 'COLLABORATOR'
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const n = context.issue.number;
|
||||
await github.rest.issues.createComment({
|
||||
...context.repo, issue_number: n,
|
||||
body: "Do not create issues here. Use the dedicated support repo and issue template system: https://github.com/Termix-SSH/Support"
|
||||
});
|
||||
await github.rest.issues.update({ ...context.repo, issue_number: n, state: "closed", state_reason: "not_planned" });
|
||||
await github.rest.issues.lock({ ...context.repo, issue_number: n, lock_reason: "off-topic" });
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ needs.prep.outputs.dev_branch }}
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GHCR_TOKEN }}
|
||||
token: ${{ secrets.TERMIX_PAT }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v7
|
||||
@@ -100,14 +100,26 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
# Manifest validation in lint loads the built SDK.
|
||||
- name: Build SDK
|
||||
run: npm run build:sdk
|
||||
|
||||
- name: Lint and format
|
||||
run: |
|
||||
npm run lint:fix || true
|
||||
npm run lint:fix
|
||||
npm run format
|
||||
npm run lint
|
||||
|
||||
# The plugin boot tests load the built bundles.
|
||||
- name: Build plugins
|
||||
run: npm run build:plugins
|
||||
|
||||
- name: Run unit tests
|
||||
run: npm run test
|
||||
|
||||
- name: Run plugin tests
|
||||
run: npm run test:plugins
|
||||
|
||||
- name: Sync version
|
||||
run: node scripts/sync-version.cjs --version "${{ needs.prep.outputs.version }}"
|
||||
|
||||
@@ -141,7 +153,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ needs.prep.outputs.dev_branch }}
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GHCR_TOKEN }}
|
||||
token: ${{ secrets.TERMIX_PAT }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v7
|
||||
@@ -159,7 +171,7 @@ jobs:
|
||||
- name: Clean up stale Crowdin git integration branch
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --head i18n_translate --state open --json number -q '.[0].number' || true)
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
@@ -168,7 +180,7 @@ jobs:
|
||||
git push origin --delete i18n_translate || true
|
||||
|
||||
- name: Upload sources to Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
uses: crowdin/github-action@v3
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
@@ -180,13 +192,15 @@ jobs:
|
||||
env:
|
||||
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_KEY }}
|
||||
|
||||
- name: Machine pre-translate untranslated strings
|
||||
# Off until the machine translation credits are topped up.
|
||||
- name: Pre-translate untranslated strings
|
||||
if: false
|
||||
env:
|
||||
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
|
||||
run: node scripts/crowdin-pretranslate.cjs
|
||||
|
||||
- name: Download translations from Crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
uses: crowdin/github-action@v3
|
||||
with:
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
@@ -203,7 +217,7 @@ jobs:
|
||||
git config user.name "LukeGus"
|
||||
git config user.email "bugattiguy527@gmail.com"
|
||||
|
||||
git add src/ui/locales/translated
|
||||
git add src/ui/locales/translated plugins/*/locales/translated
|
||||
if git diff --cached --quiet; then
|
||||
echo "No translation changes to commit."
|
||||
exit 0
|
||||
@@ -240,7 +254,7 @@ jobs:
|
||||
- name: Open and squash-merge PR to main
|
||||
id: merge
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
DEV_BRANCH="${{ needs.prep.outputs.dev_branch }}"
|
||||
TITLE="release-${{ needs.prep.outputs.version }}"
|
||||
@@ -311,7 +325,7 @@ jobs:
|
||||
- name: Clear existing release artifacts (overwrite mode)
|
||||
if: ${{ inputs.mode == 'Overwrite release' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
TAG="${{ needs.prep.outputs.release_tag }}"
|
||||
if ! gh release view "$TAG" --repo ${{ github.repository }} >/dev/null 2>&1; then
|
||||
@@ -334,7 +348,7 @@ jobs:
|
||||
- name: Create or update GitHub release
|
||||
if: ${{ inputs.mode != 'Overwrite release' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
TAG="${{ needs.prep.outputs.release_tag }}"
|
||||
TITLE="release-${{ needs.prep.outputs.version }}"
|
||||
@@ -377,7 +391,7 @@ jobs:
|
||||
with:
|
||||
ref: main
|
||||
fetch-depth: 1
|
||||
token: ${{ secrets.GHCR_TOKEN }}
|
||||
token: ${{ secrets.TERMIX_PAT }}
|
||||
|
||||
- name: Bump and commit Homebrew cask
|
||||
env:
|
||||
@@ -438,18 +452,26 @@ jobs:
|
||||
repository: Termix-SSH/Docs
|
||||
ref: main
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GHCR_TOKEN }}
|
||||
token: ${{ secrets.TERMIX_PAT }}
|
||||
path: docs-repo
|
||||
|
||||
- name: Create docs release branch
|
||||
working-directory: docs-repo
|
||||
run: git checkout -B "dev-${{ needs.prep.outputs.version }}"
|
||||
run: |
|
||||
BRANCH="dev-${{ needs.prep.outputs.version }}"
|
||||
if git ls-remote --exit-code origin "refs/heads/$BRANCH" >/dev/null 2>&1; then
|
||||
echo "Reusing existing docs branch $BRANCH."
|
||||
git checkout -B "$BRANCH" "origin/$BRANCH"
|
||||
else
|
||||
git checkout -B "$BRANCH"
|
||||
fi
|
||||
|
||||
- name: Overwrite OpenAPI spec and regenerate API docs
|
||||
working-directory: docs-repo
|
||||
run: |
|
||||
cp ../termix/openapi.json static/openapi.json
|
||||
npm ci
|
||||
npm run docusaurus clean-api-docs termix
|
||||
npm run docusaurus gen-api-docs termix
|
||||
|
||||
- name: Commit and push docs branch
|
||||
@@ -471,13 +493,13 @@ jobs:
|
||||
|
||||
git add -A
|
||||
git commit -m "feat: update API docs for ${{ needs.prep.outputs.version }}"
|
||||
git push --force origin "dev-${{ needs.prep.outputs.version }}"
|
||||
git push origin "dev-${{ needs.prep.outputs.version }}"
|
||||
|
||||
- name: Open and squash-merge docs PR
|
||||
if: ${{ inputs.mode != 'Dry run' }}
|
||||
working-directory: docs-repo
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
BRANCH="dev-${{ needs.prep.outputs.version }}"
|
||||
if ! git ls-remote --exit-code origin "refs/heads/$BRANCH" >/dev/null 2>&1; then
|
||||
@@ -534,24 +556,25 @@ jobs:
|
||||
docs,
|
||||
publish-youtube,
|
||||
]
|
||||
if: ${{ always() && (inputs.mode == 'Everything' || inputs.mode == 'Skip submit') && needs.merge-to-main.result == 'success' && needs.electron-release.result == 'success' }}
|
||||
if: ${{ always() && (inputs.mode == 'Everything' || inputs.mode == 'Skip submit') && needs.merge-to-main.result == 'success' && needs.docs.result == 'success' }}
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Delete dev branch in Termix
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
git push https://x-access-token:${{ secrets.GHCR_TOKEN }}@github.com/${{ github.repository }}.git \
|
||||
git push https://x-access-token:${{ secrets.TERMIX_PAT }}@github.com/${{ github.repository }}.git \
|
||||
--delete "${{ needs.prep.outputs.dev_branch }}" || true
|
||||
|
||||
- name: Delete dev branch in Docs
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.TERMIX_PAT }}
|
||||
run: |
|
||||
git push https://x-access-token:${{ secrets.GHCR_TOKEN }}@github.com/Termix-SSH/Docs.git \
|
||||
git push https://x-access-token:${{ secrets.TERMIX_PAT }}@github.com/Termix-SSH/Docs.git \
|
||||
--delete "dev-${{ needs.prep.outputs.version }}" || true
|
||||
@@ -13,6 +13,14 @@ dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
# Plugin build output. termix-plugin build writes it, the packaged server
|
||||
# gets its copy under dist/plugins.
|
||||
/plugins/*/dist/
|
||||
*.tmxplug
|
||||
*.tmxplug.sig
|
||||
termix-plugin-signing.key
|
||||
/src/**/*.js
|
||||
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
.idea
|
||||
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
npx lint-staged
|
||||
# The .cmd shims on Windows add their own paths to each command, so keep
|
||||
# lint-staged's chunks well under cmd.exe's 8191 character limit.
|
||||
npx lint-staged --max-arg-length 4000
|
||||
@@ -20,3 +20,6 @@ openapi.json
|
||||
|
||||
# Generated by drizzle-kit; formatting is the tool's own
|
||||
drizzle/
|
||||
|
||||
# Helm templates contain Go template syntax, not plain YAML
|
||||
charts/*/templates/
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
cask "termix" do
|
||||
version "2.6.1"
|
||||
sha256 "716fcbd4ad4aef3dc19f2eb84cee8c46179860eaac180c98cdcadbceca0dacc6"
|
||||
version "2.9.1"
|
||||
sha256 "6d8847e18508314db8ed4380c63bf0dd31437102a288b8e861879c92ba25a254"
|
||||
|
||||
url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_dmg.dmg"
|
||||
name "Termix"
|
||||
|
||||
@@ -89,7 +89,7 @@ Local, remote, and dynamic SOCKS forwarding with auto reconnect and health check
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**File Manager:**
|
||||
Browse, edit, upload, download, rename, move, and delete files over SFTP, with sudo support. View and edit code, images, audio, and video. Copy files straight from one server to another, with the fastest route picked for you and transfers checked for integrity.
|
||||
Browse, edit, upload, download, rename, move, and delete files over SFTP, with sudo support. View and edit code, images, audio, and video. Copy files straight from one server to another in a dedicated transfer tab, with the fastest route picked for you and transfers checked for integrity. The desktop app also has a side-by-side local and remote view.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -111,7 +111,7 @@ Save and organize hosts with tags and nested folders you can name and color. Reu
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Host Metrics:**
|
||||
CPU, memory, disk, network, temperature, uptime, processes, ports, logins, and system info on most Linux servers, with history graphs. Manager cards let you handle services, cron jobs, packages, users, firewall rules, WireGuard, Tailscale, SSL certs, logs, and health checks without leaving Termix.
|
||||
CPU, memory, disk, network, temperature, NVIDIA GPU, uptime, processes, ports, logins, and system info on most Linux servers, with history graphs. Manager cards let you handle services, cron jobs, packages, users, firewall rules, WireGuard, Tailscale, SSL certs, logs, and health checks without leaving Termix.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Save a set of tabs with their split layout and reopen the whole thing in one cli
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Guided Setup:**
|
||||
A short setup walks you through picking an interface preset, your theme, the features you want, and your first host. Simple mode hides what you do not use, and you can rerun setup or switch presets any time.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Desktop Standalone and Sync:**
|
||||
The desktop app runs on its own with a local backend and database, no server needed. You can also connect it to a Termix server for two-way sync of hosts, credentials, snippets, and more, and choose whether connections start locally or through the server.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Command Line Interface:**
|
||||
A `termix` CLI for your shell and your scripts. Open terminals, run a command on one host or a whole fleet, move files over SFTP, and manage hosts, snippets, and credentials. Install with `npm install -g @termix-cli/cli` or grab a standalone binary. See the [CLI docs](https://docs.termix.site/cli).
|
||||
A `termix` CLI for your shell and your scripts. Open terminals, run a command on one host or a whole fleet, move files over SFTP, and manage hosts, snippets, and credentials. Install with `npm install -g @termix-ssh/cli` or grab a standalone binary. See the [CLI docs](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ A `termix` CLI for your shell and your scripts. Open terminals, run a command on
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Security:**
|
||||
Passwords, keys, and other secrets are encrypted per user, and the database files themselves can be encrypted on disk. See the [docs](https://docs.termix.site/security) for how it works.
|
||||
Passwords, keys, and other secrets are encrypted per user, and the database files themselves can be encrypted on disk. See the [docs](https://docs.termix.site/features/authentication/security/) for how it works.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Around 30 languages built in, managed through [Crowdin](https://docs.termix.site
|
||||
- **Keyboard Shortcuts** - Move between tabs, close tabs, and more, all rebindable
|
||||
- **Wake-on-LAN** - Wake a machine from Termix or from an automation step
|
||||
- **Trusted Proxy Auth** - Let a reverse proxy handle sign-in and pass the user through
|
||||
- **SSH Feature Rich** - Jump hosts, Warpgate, TOTP prompts, SOCKS5, host key verification, password autofill, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, terminal logging, agent forwarding, Bitwarden SSH agent, HashiCorp Vault SSH signing, and more
|
||||
- **White Label** - Admins can rebrand the instance with their own name, logo, and colors
|
||||
- **Web Endpoints** - Open a host's own web UI, like a router admin page, embedded inside Termix instead of a separate tab
|
||||
- **Collaboration Rooms** - Persistent rooms where a group can jump between sessions together, with a presenter stage and invites
|
||||
- **SSH Feature Rich** - Jump hosts, Warpgate, TOTP prompts, SOCKS5, host key verification, password autofill, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, terminal logging, agent forwarding, Bitwarden SSH agent, HashiCorp Vault SSH signing, Step CA, 1Password Connect, and more
|
||||
- **Termix ID** - A built-in take on sshid.io. Claim a handle, publish your public keys at a resolver URL, and issue SSH certificates from the built-in CA
|
||||
- **Command History Autosuggestions** - Inline suggestions in the terminal as you type, based on your command history
|
||||
- **Desktop Standalone and Sync** - The desktop app runs on its own with a local backend and database, and can optionally sync with a Termix server
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,10 @@ Around 30 languages built in, managed through [Crowdin](https://docs.termix.site
|
||||
|
||||
Visit the [Termix Docs](https://docs.termix.site/install) for full installation instructions across all platforms.
|
||||
|
||||
Deploying to Kubernetes? The Helm chart is in `charts/termix`, and setup instructions
|
||||
covering Ingress, Traefik, Argo CD, GitHub Actions, and GitLab CI are at
|
||||
[docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes).
|
||||
|
||||
Sample Docker Compose file (you can omit `guacd` and the network if you don't plan on using remote desktop features):
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +350,7 @@ networks:
|
||||
Termix also has a CLI, so you can manage your servers from a terminal and use Termix in your own scripts.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +367,9 @@ You can run the Termix server on a VPS instead of inside your own network. If Te
|
||||
|
||||
## Telemetry
|
||||
|
||||
Termix sends a small anonymous ping once a day so I can see how many instances are running and which features get used. It contains a random instance ID, how many users and hosts you have, the app version, and which features (terminal, file manager, tunnels, docker, etc.) were used in the last 24 hours. It never contains usernames, hostnames, IP addresses, credentials, or anything else that identifies you or your servers.
|
||||
Termix sends a small anonymous report once a day so I can see how many instances are running and which features get used. It contains a random instance ID, the app version, and how many users and hosts you have. It can also include your platform (OS, architecture, Node.js version, database type, and whether you run Docker, the desktop app or a plain server), how often each kind of tab was opened and how many SSH logins happened, and which built-in features are running. It never contains usernames, hostnames, IP addresses, credentials, or anything else that identifies you or your servers.
|
||||
|
||||
It is on by default. Turn it off in Admin Settings under General, or set `ENABLE_TELEMETRY=false` before you ever start Termix.
|
||||
It is on by default. Turn it off, or choose what it includes, in Admin Settings under Usage Statistics, where you can also preview the exact report. Each user can leave out their own feature usage in their profile. Setting `ENABLE_TELEMETRY=false` turns it off and locks the switch.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +385,52 @@ Termix is free and open source with no subscriptions or paid plans. If you find
|
||||
|
||||
Interested in a paid placement to support development? Email [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Support
|
||||
|
||||
+6
-105
@@ -1,6 +1,6 @@
|
||||
<!-- SUMMARY -->
|
||||
|
||||
Termix AI, automations, fleets, workspaces, subhosts, Proxmox metrics, a context aware terminal toolbar, split screen tabs, onboarding, PostgreSQL/MySQL support, and a large batch of fixes.
|
||||
An urgent patch for 2.9.1 that fixes the server writing huge amounts of data to disk, which could add up to 100 GB every few hours. Update as soon as you can.
|
||||
|
||||
<!-- /SUMMARY -->
|
||||
|
||||
@@ -12,114 +12,15 @@ https://youtu.be/lngaePO96tM
|
||||
|
||||
<!-- UPDATE_LOG -->
|
||||
|
||||
- Added completely optional and disabled/removed by default Termix AI, an assistant that can work with your hosts and terminals
|
||||
- This feature was added based off a 60% (yes) to 40% (no) Discord vote.
|
||||
- The assistant cannot change anything on its own. It can only read a limited set of your Termix data and propose actions, and every change or command runs only after you approve it, using your own account and permissions.
|
||||
- It has no access to credentials, SSH keys, vaults, users, roles, sessions, SSO, certificates, audit logs, or instance settings. Secrets are also stripped from anything sent to a model provider.
|
||||
- Both an admin and each user must turn it on before it does anything, and it stays off after upgrading.
|
||||
- Added automations with events, channels, and steps
|
||||
- Added a fleet system with snippets, packages, files, and inventory
|
||||
- Added workspaces to save and restore your tab layout
|
||||
- Added subhosts so hosts can be organized under a parent host
|
||||
- Added Proxmox metrics integration
|
||||
- Added a context aware terminal toolbar with quick links, host info, image pasting, and a movable desktop layout
|
||||
- Added interactive terminal macros
|
||||
- Added first-class split screen tabs
|
||||
- Added a file manager trash instead of permanent deletes
|
||||
- Added a local terminal to the desktop app
|
||||
- Added inheritable connection defaults so hosts can share settings
|
||||
- Added an onboarding flow with an interface simplicity system
|
||||
- Added PostgreSQL and MySQL support alongside SQLite
|
||||
- Added a redesigned host and credential sidebar with synced preferences and drag-to-reorder
|
||||
- Added the option to open some app rail tabs as their own tab or in a right sidebar
|
||||
- Added folder select to host multi select
|
||||
- Added connection logs for RDP, VNC, and Telnet hosts
|
||||
- Added native RDP launching on Windows desktop
|
||||
- Added a drive file browser and drag-and-drop upload for RDP
|
||||
- Added terminal image handoff so images open on your local machine
|
||||
- Added custom terminal font selection
|
||||
- Added trusted proxy authentication
|
||||
- Added global touch input settings
|
||||
- Added adaptive transfers that pick the fastest route and verify integrity
|
||||
- Added adaptive polling and preloading that respond to activity and network cost
|
||||
- Added adaptive SSH local echo for high latency connections
|
||||
- Added custom disk and network metric options
|
||||
- Added the ability to exclude specific mounts from disk usage metrics
|
||||
- Added expanded snippet options
|
||||
- Added downloadable session logs as text files
|
||||
- Added keyboard shortcuts to move between open tabs
|
||||
- Added Discord webhook notification channels
|
||||
- Added paste support when not running over HTTPS
|
||||
- Added Headscale API key and custom API endpoint support
|
||||
- Added a Meta key option for terminals
|
||||
- Added BE-AZERTY keyboard layout for remote desktop
|
||||
- Added PKCE to the OIDC login flow
|
||||
- Added Proxmox VMID and Docker tags to discovered guests
|
||||
- Added custom SSL certificate support in admin settings
|
||||
- Greatly improved performance across metrics polling and host management for large setups
|
||||
- Background database saves now happen at most once every 30 seconds, so disk writes no longer grow with the number of hosts
|
||||
- Plugin database and storage reads are now logged to the audit log once per start instead of on every read
|
||||
- On first start, 2.9.2 clears the plugin read entries that 2.9.1 piled up in the audit log
|
||||
|
||||
<!-- /UPDATE_LOG -->
|
||||
|
||||
<!-- BUG_FIXES -->
|
||||
|
||||
- Periodic SSH terminal stalls caused by SQLite telemetry writes
|
||||
- Missing OPKSSH binary breaking installs without internet access
|
||||
- Session recording writes slowing down terminals
|
||||
- SGR mouse tracking escape codes printing as text
|
||||
- Terminal display distortion with special characters
|
||||
- Windows Ctrl+W not closing the active tab
|
||||
- Tray Quit not terminating the desktop app
|
||||
- Mobile terminal scrollback not matching xterm wheel behavior
|
||||
- tmux breaking on UTF-8 paths
|
||||
- Sudo password auto-fill not persisting
|
||||
- SSH and sudo passwords not being saved or auto-filled
|
||||
- Switching SSH authentication away from Vault failing
|
||||
- Host edits being discarded without a warning
|
||||
- Quick-created credentials not being selected
|
||||
- Saved RDP connection settings not being preserved
|
||||
- RDP domain credentials not being prompted for
|
||||
- Windows key mapping in remote desktop sessions
|
||||
- VNC failing to connect to macOS screen sharing
|
||||
- Mouse input breaking on touch-capable devices in RDP and VNC
|
||||
- Docker runtime selection not persisting, plus Docker manager UI issues
|
||||
- Desktop Docker console WebSocket not being authenticated
|
||||
- Folders intermittently disappearing from duplicate requests
|
||||
- Folder deletion not refreshing the host list
|
||||
- Proxmox guest identity being lost on edit
|
||||
- Long host names shifting dashboard metrics
|
||||
- Host list rows resizing unexpectedly
|
||||
- Metrics collection all firing at once on startup
|
||||
- Session activity writes hitting the database too often
|
||||
- Reachable and available hosts being treated the same
|
||||
- SSH keepalives could not be disabled
|
||||
- OIDC group claims from multiple sources not being merged
|
||||
- OIDC discovery issuers with trailing slashes failing
|
||||
- LDAP logins not using preferred_username
|
||||
- Trusted MFA devices not being bound to a specific client install
|
||||
- 2FA could not be disabled with a single credential
|
||||
- Profile API keys not being shown after creation
|
||||
- SSH agent authentication being unclear in the host editor
|
||||
- Tunnel status stream not requiring authentication
|
||||
- SFTP and Docker console accepting a mismatched host id
|
||||
- SSH connections whose host id resolved elsewhere being accepted
|
||||
- User-managed CA certificates not being applied over SFTP
|
||||
- Already-shared hosts losing their SSH authentication
|
||||
- Real client IP not being captured for SSH login alerts behind a reverse proxy
|
||||
- Audit log IPs not using the real client IP
|
||||
- Homepage System Overview update indicator never firing
|
||||
- Webhook notification channels not working
|
||||
- Remote sync failing behind an nginx proxy
|
||||
- First server sync not refreshing the UI
|
||||
- Desktop app not showing update prompts and hiding the version badge
|
||||
- Desktop Tailscale configuration being lost
|
||||
- Command palette not loading new activity, plus Enter now opens the first result
|
||||
- Database connection failures during login not being reported clearly
|
||||
- audit_logs.user_id not being nullable on fresh SQLite installs
|
||||
- Sync upserts writing to the wrong row
|
||||
- Database migration failures on tables without an id column
|
||||
- ssh_credentials rebuilds not matching the live schema
|
||||
- Sidebar reset and fullscreen buttons sharing the same icon
|
||||
- Host list icons not matching the tab bar icons
|
||||
- Keep Linux credential storage working on unrecognized desktops
|
||||
- The server rewriting its whole database to disk many times a second, causing very high disk writes (up to 100 GB every few hours) on 2.9.1
|
||||
- The audit log filling up with plugin entries and pushing out real ones
|
||||
|
||||
<!-- /BUG_FIXES -->
|
||||
+18
@@ -3,3 +3,21 @@
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report any vulnerabilities to [GitHub Security](https://github.com/Termix-SSH/Termix/security/advisories).
|
||||
|
||||
## External secret storage
|
||||
|
||||
By default, a single-container installation generates its keys in the Termix
|
||||
data directory for ease of recovery. Production deployments that keep backups
|
||||
or database files outside a trusted encrypted volume should set
|
||||
`TERMIX_REQUIRE_EXTERNAL_SECRETS=true` and provide all four keys through a
|
||||
secret manager:
|
||||
|
||||
- `JWT_SECRET` (at least 64 characters)
|
||||
- `DATABASE_KEY` (64 hexadecimal characters)
|
||||
- `ENCRYPTION_KEY` (64 hexadecimal characters)
|
||||
- `INTERNAL_AUTH_TOKEN` (at least 32 characters)
|
||||
|
||||
Each value can instead be mounted as a Docker or Kubernetes secret and supplied
|
||||
with its corresponding `_FILE` variable, such as `ENCRYPTION_KEY_FILE`.
|
||||
Hardened mode fails closed instead of writing a replacement key beside the
|
||||
encrypted database.
|
||||
@@ -0,0 +1,6 @@
|
||||
.git/
|
||||
.github/
|
||||
node_modules/
|
||||
dist/
|
||||
coverage/
|
||||
*.tgz
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v2
|
||||
name: termix
|
||||
description: Self-hosted SSH and remote desktop management for Kubernetes.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: 2.7.0
|
||||
home: https://github.com/Termix-SSH/Termix
|
||||
sources:
|
||||
- https://github.com/Termix-SSH/Termix
|
||||
maintainers:
|
||||
- name: Termix maintainers
|
||||
keywords:
|
||||
- ssh
|
||||
- remote-desktop
|
||||
- guacamole
|
||||
- terminal
|
||||
@@ -0,0 +1,17 @@
|
||||
Termix has been installed.
|
||||
|
||||
Service:
|
||||
{{ include "termix.fullname" . }}:{{ .Values.service.port }}
|
||||
|
||||
{{- if .Values.ingress.enabled }}
|
||||
Ingress hosts:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- {{ .host }}
|
||||
{{- end }}
|
||||
{{- else if .Values.traefik.ingressRoute.enabled }}
|
||||
Traefik IngressRoute:
|
||||
https://{{ .Values.traefik.ingressRoute.host }}{{ .Values.traefik.ingressRoute.pathPrefix }}
|
||||
{{- else }}
|
||||
Port-forward for local testing:
|
||||
kubectl -n {{ .Release.Namespace }} port-forward svc/{{ include "termix.fullname" . }} 8080:{{ .Values.service.port }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,45 @@
|
||||
{{- define "termix.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "termix.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "termix.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "termix.labels" -}}
|
||||
helm.sh/chart: {{ include "termix.chart" . }}
|
||||
app.kubernetes.io/name: {{ include "termix.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "termix.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "termix.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "termix.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
{{- default (include "termix.fullname" .) .Values.serviceAccount.name -}}
|
||||
{{- else -}}
|
||||
{{- default "default" .Values.serviceAccount.name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "termix.secretName" -}}
|
||||
{{- default (printf "%s-secret" (include "termix.fullname" .)) .Values.secrets.name -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,148 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
strategy:
|
||||
{{- toYaml .Values.strategy | nindent 4 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "termix.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "termix.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "termix.serviceAccountName" . }}
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: termix
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
env:
|
||||
{{- range $key, $value := .Values.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.guacd.enabled }}
|
||||
- name: GUACD_HOST
|
||||
value: "127.0.0.1"
|
||||
{{- else if .Values.guacd.host }}
|
||||
- name: GUACD_HOST
|
||||
value: {{ .Values.guacd.host | quote }}
|
||||
{{- end }}
|
||||
- name: GUACD_TUNNEL_HOST
|
||||
value: {{ include "termix.fullname" . | quote }}
|
||||
{{- if ne .Values.database.dialect "sqlite" }}
|
||||
- name: DATABASE_DIALECT
|
||||
value: {{ .Values.database.dialect | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.database.existingSecret.name }}
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.database.existingSecret.name }}
|
||||
key: {{ .Values.database.existingSecret.urlKey }}
|
||||
{{- end }}
|
||||
{{- if .Values.secrets.create }}
|
||||
{{- range $key, $value := .Values.secrets.data }}
|
||||
{{- if $value }}
|
||||
- name: {{ $key }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "termix.secretName" $ }}
|
||||
key: {{ $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnv }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.probes.liveness.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.probes.liveness.failureThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.probes.readiness.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.probes.readiness.failureThreshold }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /app/data
|
||||
{{- if .Values.guacd.enabled }}
|
||||
- name: guacd
|
||||
image: "{{ .Values.guacd.image.repository }}:{{ .Values.guacd.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.guacd.image.pullPolicy }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.guacd.securityContext | nindent 12 }}
|
||||
ports:
|
||||
- name: guacd
|
||||
containerPort: {{ .Values.guacd.service.port }}
|
||||
protocol: TCP
|
||||
resources:
|
||||
{{- toYaml .Values.guacd.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /termix-data
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ default (printf "%s-data" (include "termix.fullname" .)) .Values.persistence.existingClaim }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,22 @@
|
||||
{{- if .Values.autoscaling.enabled -}}
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "termix.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,35 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- toYaml .Values.ingress.tls | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "termix.fullname" $ }}
|
||||
port:
|
||||
name: http
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
{{- if .Values.networkPolicy.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "termix.selectorLabels" . | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
{{- toYaml .Values.networkPolicy.ingress | nindent 4 }}
|
||||
egress:
|
||||
{{- toYaml .Values.networkPolicy.egress | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.podDisruptionBudget.enabled -}}
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
spec:
|
||||
minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "termix.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}-data
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- toYaml .Values.persistence.accessModes | nindent 4 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size | quote }}
|
||||
{{- if .Values.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if .Values.secrets.create -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "termix.secretName" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
{{- range $key, $value := .Values.secrets.data }}
|
||||
{{- if $value }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "termix.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "termix.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,34 @@
|
||||
{{- if .Values.traefik.ingressRoute.enabled -}}
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: {{ include "termix.fullname" . }}
|
||||
labels:
|
||||
{{- include "termix.labels" . | nindent 4 }}
|
||||
{{- with .Values.traefik.ingressRoute.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
entryPoints:
|
||||
{{- toYaml .Values.traefik.ingressRoute.entryPoints | nindent 4 }}
|
||||
routes:
|
||||
- match: Host(`{{ .Values.traefik.ingressRoute.host }}`) && PathPrefix(`{{ .Values.traefik.ingressRoute.pathPrefix }}`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: {{ include "termix.fullname" . }}
|
||||
port: {{ .Values.service.port }}
|
||||
{{- with .Values.traefik.ingressRoute.middlewares }}
|
||||
middlewares:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.traefik.ingressRoute.tls.enabled }}
|
||||
tls:
|
||||
{{- if .Values.traefik.ingressRoute.tls.secretName }}
|
||||
secretName: {{ .Values.traefik.ingressRoute.tls.secretName }}
|
||||
{{- end }}
|
||||
{{- if .Values.traefik.ingressRoute.tls.certResolver }}
|
||||
certResolver: {{ .Values.traefik.ingressRoute.tls.certResolver }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if and .Values.ingress.enabled .Values.traefik.ingressRoute.enabled -}}
|
||||
{{- fail "ingress and traefik.ingressRoute cannot both be enabled" -}}
|
||||
{{- end -}}
|
||||
{{- if and (eq .Values.database.dialect "sqlite") (or (gt (int .Values.replicaCount) 1) .Values.autoscaling.enabled) -}}
|
||||
{{- fail "SQLite supports only one replica; use Postgres or MySQL before enabling replicas or autoscaling" -}}
|
||||
{{- end -}}
|
||||
{{- if and (not .Values.guacd.enabled) (not .Values.guacd.host) -}}
|
||||
{{- fail "guacd.host is required when the bundled guacd sidecar is disabled" -}}
|
||||
{{- end -}}
|
||||
{{- if and .Values.database.existingSecret.name .Values.secrets.create .Values.secrets.data.DATABASE_URL -}}
|
||||
{{- fail "DATABASE_URL must come from either database.existingSecret or secrets.data, not both" -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,28 @@
|
||||
image:
|
||||
repository: ghcr.io/termix-ssh/termix
|
||||
tag: "2.7.0"
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
hosts:
|
||||
- host: termix.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: termix-tls
|
||||
hosts:
|
||||
- termix.example.com
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 20Gi
|
||||
|
||||
secrets:
|
||||
create: false
|
||||
|
||||
database:
|
||||
dialect: sqlite
|
||||
|
||||
extraEnvFrom: []
|
||||
@@ -0,0 +1,32 @@
|
||||
ingress:
|
||||
enabled: false
|
||||
|
||||
traefik:
|
||||
ingressRoute:
|
||||
enabled: true
|
||||
entryPoints:
|
||||
- websecure
|
||||
host: termix.example.com
|
||||
pathPrefix: /
|
||||
tls:
|
||||
enabled: true
|
||||
certResolver: letsencrypt
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 20Gi
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
memory: 2Gi
|
||||
|
||||
guacd:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
@@ -0,0 +1,151 @@
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: ghcr.io/termix-ssh/termix
|
||||
pullPolicy: IfNotPresent
|
||||
tag: ""
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
automount: false
|
||||
annotations: {}
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
fsGroup: 1000
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
|
||||
securityContext: {}
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
annotations: {}
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts:
|
||||
- host: termix.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls: []
|
||||
|
||||
traefik:
|
||||
ingressRoute:
|
||||
enabled: false
|
||||
entryPoints:
|
||||
- websecure
|
||||
host: termix.example.com
|
||||
pathPrefix: /
|
||||
tls:
|
||||
enabled: true
|
||||
secretName: ""
|
||||
certResolver: ""
|
||||
middlewares: []
|
||||
annotations: {}
|
||||
|
||||
resources: {}
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 3
|
||||
targetCPUUtilizationPercentage: 80
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
size: 10Gi
|
||||
storageClass: ""
|
||||
annotations: {}
|
||||
existingClaim: ""
|
||||
|
||||
env:
|
||||
PORT: "8080"
|
||||
DATA_DIR: /app/data
|
||||
NODE_ENV: production
|
||||
TERMIX_REQUIRE_EXTERNAL_SECRETS: "false"
|
||||
GUACD_RECORDING_PATH: /termix-data/session_recordings/guacamole
|
||||
GUACD_RECORDING_BACKEND_PATH: /app/data/session_recordings/guacamole
|
||||
|
||||
extraEnv: []
|
||||
extraEnvFrom: []
|
||||
|
||||
secrets:
|
||||
create: false
|
||||
name: ""
|
||||
data:
|
||||
JWT_SECRET: ""
|
||||
DATABASE_KEY: ""
|
||||
ENCRYPTION_KEY: ""
|
||||
INTERNAL_AUTH_TOKEN: ""
|
||||
DATABASE_URL: ""
|
||||
GUACAMOLE_ENCRYPTION_KEY: ""
|
||||
|
||||
database:
|
||||
dialect: sqlite
|
||||
existingSecret:
|
||||
name: ""
|
||||
urlKey: DATABASE_URL
|
||||
|
||||
guacd:
|
||||
enabled: true
|
||||
host: ""
|
||||
image:
|
||||
repository: guacamole/guacd
|
||||
tag: 1.6.0
|
||||
pullPolicy: IfNotPresent
|
||||
resources: {}
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
service:
|
||||
port: 4822
|
||||
annotations: {}
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
strategy:
|
||||
type: Recreate
|
||||
|
||||
probes:
|
||||
liveness:
|
||||
enabled: true
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 3
|
||||
readiness:
|
||||
enabled: true
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
minAvailable: 1
|
||||
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
ingress: []
|
||||
egress: []
|
||||
@@ -1,6 +1,11 @@
|
||||
project_id: "858252"
|
||||
api_token: "env:CROWDIN_API_TOKEN"
|
||||
preserve_hierarchy: true
|
||||
|
||||
files:
|
||||
# Core has always lived at /en.json in Crowdin; moving it would orphan its translations.
|
||||
- source: /src/ui/locales/en.json
|
||||
dest: /en.json
|
||||
translation: /src/ui/locales/translated/%locale_with_underscore%.json
|
||||
- source: /plugins/*/locales/en.json
|
||||
translation: /%original_path%/translated/%locale_with_underscore%.json
|
||||
+64
-21
@@ -1,17 +1,30 @@
|
||||
# Stage 0: every plugin's package.json and manifest.json and nothing else.
|
||||
# npm ci needs each workspace package.json in place or it silently skips it,
|
||||
# and a glob COPY flattens paths, so the tree is trimmed here instead. The
|
||||
# deps layer below stays cached until one of these files changes.
|
||||
FROM node:26-slim AS workspace-manifests
|
||||
WORKDIR /src
|
||||
COPY plugins ./plugins
|
||||
RUN find plugins -mindepth 2 -maxdepth 2 ! -name package.json ! -name manifest.json -exec rm -rf {} +
|
||||
|
||||
# Stage 1: Install dependencies
|
||||
FROM node:24-slim AS deps
|
||||
# The builders only produce JS, so they run on the build machine's own arch
|
||||
# once instead of under QEMU per target. Rolldown hangs under arm64 emulation.
|
||||
FROM --platform=$BUILDPLATFORM node:26-slim AS deps
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY package*.json ./
|
||||
COPY packages/plugin-sdk/package.json ./packages/plugin-sdk/package.json
|
||||
COPY --from=workspace-manifests /src/plugins ./plugins
|
||||
COPY .npmrc ./
|
||||
COPY vendor ./vendor
|
||||
|
||||
COPY scripts/patch-guacamole-lite.cjs ./scripts/
|
||||
COPY scripts/patch-ssh2-agent.cjs ./scripts/
|
||||
|
||||
RUN npm ci --ignore-scripts && \
|
||||
node scripts/patch-guacamole-lite.cjs && \
|
||||
node scripts/patch-ssh2-agent.cjs && \
|
||||
npm cache clean --force
|
||||
|
||||
# Stage 2: Build frontend
|
||||
@@ -31,60 +44,82 @@ WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm rebuild better-sqlite3
|
||||
|
||||
RUN npm run build:backend
|
||||
|
||||
# Stage 4: Download OPKSSH binary for the target platform so the image works offline
|
||||
FROM node:24-slim AS opkssh-downloader
|
||||
FROM node:26-slim AS opkssh-downloader
|
||||
ARG TARGETARCH
|
||||
ARG OPKSSH_VERSION=v0.16.0
|
||||
ARG OPKSSH_SHA256_AMD64=c018c3e7baf98612b923e742dd87be38650bf61e3b755fb2bc90de177568b1bf
|
||||
ARG OPKSSH_SHA256_ARM64=9dd10c2b6ce99cde18e52c054877ca014134b291fd82afe71741c68db4f83d44
|
||||
WORKDIR /opkssh
|
||||
|
||||
RUN apt-get update && apt-get install -y curl ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN case "$TARGETARCH" in \
|
||||
amd64) OPKSSH_ARCH=amd64 ;; \
|
||||
arm64) OPKSSH_ARCH=arm64 ;; \
|
||||
amd64) OPKSSH_ARCH=amd64; OPKSSH_SHA256="$OPKSSH_SHA256_AMD64" ;; \
|
||||
arm64) OPKSSH_ARCH=arm64; OPKSSH_SHA256="$OPKSSH_SHA256_ARM64" ;; \
|
||||
*) echo "Unsupported architecture: $TARGETARCH" && exit 1 ;; \
|
||||
esac && \
|
||||
curl -fSL -o "opkssh-linux-${OPKSSH_ARCH}" \
|
||||
"https://github.com/openpubkey/opkssh/releases/download/${OPKSSH_VERSION}/opkssh-linux-${OPKSSH_ARCH}" && \
|
||||
echo "$OPKSSH_SHA256 opkssh-linux-${OPKSSH_ARCH}" | sha256sum -c - && \
|
||||
chmod 755 "opkssh-linux-${OPKSSH_ARCH}" && \
|
||||
echo -n "$OPKSSH_VERSION" > version.txt
|
||||
|
||||
# Stage 5: Production dependencies only
|
||||
FROM node:24-slim AS production-deps
|
||||
FROM node:26-slim AS production-deps
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY package*.json ./
|
||||
# The plugin SDK is a workspace package core imports at runtime, so npm ci
|
||||
# has to see it to link it and install its dependencies.
|
||||
COPY packages/plugin-sdk/package.json ./packages/plugin-sdk/package.json
|
||||
COPY .npmrc ./
|
||||
COPY vendor ./vendor
|
||||
|
||||
COPY scripts/patch-guacamole-lite.cjs ./scripts/
|
||||
COPY scripts/patch-ssh2-agent.cjs scripts/install-native-plugin-deps.cjs ./scripts/
|
||||
# Plugin manifests only, for their nativeDependencies. Outside plugins/ so npm
|
||||
# ci does not treat them as workspaces: everything else a plugin uses is
|
||||
# already inside its bundle.
|
||||
COPY --from=workspace-manifests /src/plugins ./plugin-manifests
|
||||
|
||||
RUN npm ci --omit=dev --ignore-scripts && \
|
||||
node scripts/patch-guacamole-lite.cjs && \
|
||||
npm rebuild better-sqlite3 bcryptjs ssh2 && \
|
||||
node scripts/install-native-plugin-deps.cjs plugin-manifests && \
|
||||
rm -rf plugin-manifests && \
|
||||
node scripts/patch-ssh2-agent.cjs && \
|
||||
rm -rf node_modules/better-sqlite3/prebuilds && \
|
||||
npm run build-release --prefix node_modules/better-sqlite3 && \
|
||||
test -f node_modules/better-sqlite3/build/Release/better_sqlite3.node && \
|
||||
npm rebuild bcryptjs ssh2 && \
|
||||
npm cache clean --force
|
||||
|
||||
# Stage 6: Final optimized image
|
||||
FROM node:24-slim
|
||||
FROM node:26-slim
|
||||
WORKDIR /app
|
||||
|
||||
ENV DATA_DIR=/app/data \
|
||||
PORT=8080 \
|
||||
NODE_ENV=production \
|
||||
POSTHOG_API_KEY=phc_xM8UznirsFxUkGE68gH4jzeqevf4kh76wGw7Ci7hH2dd
|
||||
# The release the opkssh-downloader stage baked in, so the plugin trusts that
|
||||
# binary when the build picks a version other than its pinned one.
|
||||
ARG OPKSSH_VERSION=v0.16.0
|
||||
ARG OPKSSH_SHA256_AMD64=c018c3e7baf98612b923e742dd87be38650bf61e3b755fb2bc90de177568b1bf
|
||||
ARG OPKSSH_SHA256_ARM64=9dd10c2b6ce99cde18e52c054877ca014134b291fd82afe71741c68db4f83d44
|
||||
|
||||
RUN apt-get update && apt-get install -y nginx gettext-base openssl ca-certificates gosu wget certbot python3-certbot-dns-cloudflare && \
|
||||
ENV DATA_DIR=/app/data \
|
||||
OPKSSH_BUNDLED_DIR=/app/opkssh-bundled \
|
||||
OPKSSH_VERSION=$OPKSSH_VERSION \
|
||||
OPKSSH_SHA256_AMD64=$OPKSSH_SHA256_AMD64 \
|
||||
OPKSSH_SHA256_ARM64=$OPKSSH_SHA256_ARM64 \
|
||||
PORT=8080 \
|
||||
NODE_ENV=production
|
||||
|
||||
RUN apt-get update && apt-get install -y nginx gettext-base openssl ca-certificates gosu wget && \
|
||||
update-ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
mkdir -p /app/data /app/uploads /app/data/.opk /app/nginx /tmp/nginx && \
|
||||
mkdir -p /app/data /app/uploads /app/nginx /tmp/nginx && \
|
||||
chown -R node:node /app /tmp/nginx && \
|
||||
chmod 755 /app/data /app/uploads /app/data/.opk /app/nginx /tmp/nginx
|
||||
chmod 755 /app/data /app/uploads /app/nginx /tmp/nginx
|
||||
|
||||
COPY docker/nginx.conf /app/nginx/nginx.conf.template
|
||||
COPY docker/nginx-https.conf /app/nginx/nginx-https.conf.template
|
||||
@@ -93,6 +128,14 @@ COPY --chown=node:node --from=frontend-builder /app/dist /app/html
|
||||
|
||||
COPY --chown=node:node --from=production-deps /app/node_modules /app/node_modules
|
||||
COPY --chown=node:node --from=backend-builder /app/dist/backend ./dist/backend
|
||||
# Bundled first-party plugins, resolved as dist/plugins by
|
||||
# getBundledPluginsDir().
|
||||
COPY --chown=node:node --from=backend-builder /app/dist/plugins ./dist/plugins
|
||||
# Target of node_modules/@termix/plugin-sdk, which core and the plugins import.
|
||||
COPY --chown=node:node --from=backend-builder /app/packages/plugin-sdk/package.json ./packages/plugin-sdk/package.json
|
||||
COPY --chown=node:node --from=backend-builder /app/packages/plugin-sdk/dist ./packages/plugin-sdk/dist
|
||||
# Pre-baked OPKSSH binary. The opkssh plugin uses it when its checksum
|
||||
# matches, so an offline install never downloads one.
|
||||
COPY --chown=node:node --from=opkssh-downloader /opkssh /app/opkssh-bundled
|
||||
COPY --chown=node:node package.json ./
|
||||
# Schema for Postgres and MySQL. Unused by the default SQLite deployment, which
|
||||
@@ -101,7 +144,7 @@ COPY --chown=node:node drizzle ./drizzle
|
||||
|
||||
VOLUME ["/app/data"]
|
||||
|
||||
EXPOSE ${PORT} 30001 30002 30003 30004 30005 30006 30007 30008 30009 30010 30011 30012
|
||||
EXPOSE ${PORT}
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD wget -q -O /dev/null http://localhost:30001/health || exit 1
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"id": "acme-ssl",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "ai",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "alerts",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "automations",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "docker",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "file-manager",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "fleets",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "homepage",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "host-metrics",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "ldap",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "network-topology",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "opkssh",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "proxmox",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "remote-desktop",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "secret-sources",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "serial",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "session-recording",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "session-sharing",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "snippets",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "ssh-terminal",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "sso",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "step-ca",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "tailscale",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "telemetry",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "termix-identity",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "tmux-monitor",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "totp",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "tunnels",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "vault",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "wake-on-lan",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "warpgate",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "web-endpoint",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "webauthn",
|
||||
"source": "workspace"
|
||||
},
|
||||
{
|
||||
"id": "workspaces",
|
||||
"source": "workspace"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -15,6 +15,10 @@ services:
|
||||
GUACD_HOST: "guacd-dev"
|
||||
GUACD_TUNNEL_HOST: "termix-dev"
|
||||
GUACD_RECORDING_PATH: "/termix-data/session_recordings/guacamole"
|
||||
GUACD_DRIVE_PATH: "/termix-data/rdp-drive"
|
||||
# REDIS_URL: "redis://redis:6379"
|
||||
# TERMIX_REDIS_PREFIX: "termix:collab"
|
||||
# TERMIX_STEP_CA_REDIS_PREFIX: "termix:step-ca"
|
||||
depends_on:
|
||||
- guacd-dev
|
||||
networks:
|
||||
|
||||
@@ -12,6 +12,19 @@ services:
|
||||
GUACD_HOST: "guacd"
|
||||
GUACD_TUNNEL_HOST: "termix"
|
||||
GUACD_RECORDING_PATH: "/termix-data/session_recordings/guacamole"
|
||||
# Where guacd stores files for RDP drive redirection (one folder per
|
||||
# user is created underneath). Must be writable by guacd's user.
|
||||
GUACD_DRIVE_PATH: "/termix-data/rdp-drive"
|
||||
# Multi-instance deployments should point every backend at the same
|
||||
# Redis. Without it, collaboration rooms keep their single-instance
|
||||
# in-memory fallback.
|
||||
# REDIS_URL: "redis://redis:6379"
|
||||
# TERMIX_REDIS_PREFIX: "termix:collab"
|
||||
# TERMIX_STEP_CA_REDIS_PREFIX: "termix:step-ca"
|
||||
# Hardened deployments can require keys from environment variables or
|
||||
# Docker secrets mounted through JWT_SECRET_FILE, DATABASE_KEY_FILE,
|
||||
# ENCRYPTION_KEY_FILE and INTERNAL_AUTH_TOKEN_FILE.
|
||||
# TERMIX_REQUIRE_EXTERNAL_SECRETS: "true"
|
||||
# Trusted reverse-proxy authentication is disabled by default. When
|
||||
# enabled, do not expose this container directly to untrusted clients.
|
||||
# TRUSTED_PROXY_AUTH_ENABLED: "true"
|
||||
|
||||
+45
-21
@@ -23,6 +23,18 @@ if [ "$(id -u)" = "0" ]; then
|
||||
fi
|
||||
|
||||
DATA_DIR=${DATA_DIR:-/app/data}
|
||||
|
||||
RUNTIME_ENABLE_SSL_SET=${ENABLE_SSL+x}
|
||||
RUNTIME_ENABLE_SSL=${ENABLE_SSL-}
|
||||
RUNTIME_SSL_PORT_SET=${SSL_PORT+x}
|
||||
RUNTIME_SSL_PORT=${SSL_PORT-}
|
||||
RUNTIME_SSL_CERT_PATH_SET=${SSL_CERT_PATH+x}
|
||||
RUNTIME_SSL_CERT_PATH=${SSL_CERT_PATH-}
|
||||
RUNTIME_SSL_KEY_PATH_SET=${SSL_KEY_PATH+x}
|
||||
RUNTIME_SSL_KEY_PATH=${SSL_KEY_PATH-}
|
||||
RUNTIME_SSL_DOMAIN_SET=${SSL_DOMAIN+x}
|
||||
RUNTIME_SSL_DOMAIN=${SSL_DOMAIN-}
|
||||
|
||||
if [ -f "$DATA_DIR/.env" ]; then
|
||||
echo "Loading persisted SSL settings from $DATA_DIR/.env"
|
||||
set -a
|
||||
@@ -30,11 +42,18 @@ if [ -f "$DATA_DIR/.env" ]; then
|
||||
set +a
|
||||
fi
|
||||
|
||||
[ "$RUNTIME_ENABLE_SSL_SET" = "x" ] && ENABLE_SSL=$RUNTIME_ENABLE_SSL
|
||||
[ "$RUNTIME_SSL_PORT_SET" = "x" ] && SSL_PORT=$RUNTIME_SSL_PORT
|
||||
[ "$RUNTIME_SSL_CERT_PATH_SET" = "x" ] && SSL_CERT_PATH=$RUNTIME_SSL_CERT_PATH
|
||||
[ "$RUNTIME_SSL_KEY_PATH_SET" = "x" ] && SSL_KEY_PATH=$RUNTIME_SSL_KEY_PATH
|
||||
[ "$RUNTIME_SSL_DOMAIN_SET" = "x" ] && SSL_DOMAIN=$RUNTIME_SSL_DOMAIN
|
||||
|
||||
export PORT=${PORT:-8080}
|
||||
export ENABLE_SSL=${ENABLE_SSL:-false}
|
||||
export SSL_PORT=${SSL_PORT:-8443}
|
||||
export SSL_CERT_PATH=${SSL_CERT_PATH:-/app/data/ssl/termix.crt}
|
||||
export SSL_KEY_PATH=${SSL_KEY_PATH:-/app/data/ssl/termix.key}
|
||||
export TERMIX_SSL_TERMINATED_BY_NGINX=true
|
||||
|
||||
echo "Configuring web UI to run on port: $PORT"
|
||||
|
||||
@@ -49,31 +68,21 @@ fi
|
||||
mkdir -p /tmp/nginx
|
||||
envsubst '${PORT} ${SSL_PORT} ${SSL_CERT_PATH} ${SSL_KEY_PATH}' < $NGINX_CONF_SOURCE > /tmp/nginx/nginx.conf
|
||||
|
||||
mkdir -p /app/data /app/uploads /app/data/.opk /app/data/acme-webroot/.well-known/acme-challenge
|
||||
chmod 755 /app/data /app/uploads /app/data/.opk 2>/dev/null || true
|
||||
if [ "$ENABLE_SSL" = "true" ] && [ "$PORT" = "$SSL_PORT" ]; then
|
||||
echo "HTTP and HTTPS use port $SSL_PORT; disabling the HTTP redirect listener"
|
||||
sed -i '/# BEGIN HTTP_REDIRECT_SERVER/,/# END HTTP_REDIRECT_SERVER/d' /tmp/nginx/nginx.conf
|
||||
fi
|
||||
|
||||
mkdir -p /app/data /app/uploads
|
||||
chmod 755 /app/data /app/uploads 2>/dev/null || true
|
||||
|
||||
if [ -w /app/data ]; then
|
||||
echo "Data directory is writable"
|
||||
else
|
||||
echo "WARNING: Data directory is not writable. OPKSSH may fail."
|
||||
echo "WARNING: Data directory is not writable. Plugins that keep files (OPKSSH, recordings) may fail."
|
||||
ls -ld /app/data
|
||||
fi
|
||||
|
||||
if [ -w /app/data/.opk ]; then
|
||||
echo "OPKSSH directory is writable"
|
||||
else
|
||||
echo "WARNING: OPKSSH directory is not writable. OPKSSH authentication will fail."
|
||||
ls -ld /app/data/.opk
|
||||
fi
|
||||
|
||||
OPKSSH_DIR="${DATA_DIR:-/app/data}/opkssh"
|
||||
if [ ! -d "$OPKSSH_DIR" ]; then
|
||||
echo "OPKSSH binary directory not found at $OPKSSH_DIR"
|
||||
echo "OPKSSH will be installed from the bundled copy on first use (falls back to downloading if unavailable)."
|
||||
else
|
||||
echo "OPKSSH binary directory found at $OPKSSH_DIR"
|
||||
fi
|
||||
|
||||
if [ "$ENABLE_SSL" = "true" ]; then
|
||||
echo "Checking SSL certificate configuration..."
|
||||
mkdir -p /app/data/ssl
|
||||
@@ -87,8 +96,16 @@ if [ "$ENABLE_SSL" = "true" ]; then
|
||||
if openssl x509 -in /app/data/ssl/termix.crt -checkend 2592000 -noout >/dev/null 2>&1; then
|
||||
echo "SSL certificates are valid and will be reused for domain: $DOMAIN"
|
||||
else
|
||||
echo "SSL certificate is expired or expiring soon, regenerating..."
|
||||
rm -f /app/data/ssl/termix.crt /app/data/ssl/termix.key
|
||||
SUBJECT=$(openssl x509 -in /app/data/ssl/termix.crt -noout -subject 2>/dev/null | sed 's/^subject=//')
|
||||
ISSUER=$(openssl x509 -in /app/data/ssl/termix.crt -noout -issuer 2>/dev/null | sed 's/^issuer=//')
|
||||
# Only replace our own self-signed certificate. A CA-issued one is
|
||||
# kept until it expires, even when nothing renews it.
|
||||
if [ -n "$SUBJECT" ] && [ "$SUBJECT" = "$ISSUER" ]; then
|
||||
echo "Self-signed SSL certificate is expired or expiring soon, regenerating..."
|
||||
rm -f /app/data/ssl/termix.crt /app/data/ssl/termix.key
|
||||
else
|
||||
echo "WARNING: SSL certificate expires within 30 days and was not issued by Termix. Renew it."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "SSL certificates not found, will generate new ones..."
|
||||
@@ -148,7 +165,14 @@ if [ -n "$BASE_PATH" ]; then
|
||||
echo "Injecting BASE_PATH: $BASE_PATH"
|
||||
# Strip trailing slash for use as a path prefix
|
||||
CLEAN_BASE_PATH="${BASE_PATH%/}"
|
||||
find /app/html -name "index.html" -exec sed -i "s|window.__TERMIX_BASE_PATH__ = \"\"|window.__TERMIX_BASE_PATH__ = \"$CLEAN_BASE_PATH\"|g" {} \;
|
||||
case "$CLEAN_BASE_PATH" in
|
||||
/*) ;;
|
||||
*) echo "BASE_PATH must start with /" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$CLEAN_BASE_PATH" in
|
||||
*[!A-Za-z0-9_./~-]*) echo "BASE_PATH contains unsupported characters" >&2; exit 1 ;;
|
||||
esac
|
||||
find /app/html -name "index.html" -exec sed -i "s|name=\"termix-base-path\" content=\"\"|name=\"termix-base-path\" content=\"$CLEAN_BASE_PATH\"|g" {} \;
|
||||
# Patch sw.js static asset paths with the base path prefix
|
||||
find /app/html -name "sw.js" -exec sed -i "s|__TERMIX_SW_BASE_PATH__|$CLEAN_BASE_PATH|g" {} \;
|
||||
else
|
||||
|
||||
+121
-551
@@ -69,12 +69,25 @@ http {
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# BEGIN HTTP_REDIRECT_SERVER
|
||||
server {
|
||||
listen ${PORT};
|
||||
server_name _;
|
||||
|
||||
return 301 https://$host:${SSL_PORT}$request_uri;
|
||||
# ACME http-01 checks arrive on plain HTTP and must not be redirected.
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host:${SSL_PORT}$request_uri;
|
||||
}
|
||||
}
|
||||
# END HTTP_REDIRECT_SERVER
|
||||
|
||||
server {
|
||||
listen ${SSL_PORT} ssl;
|
||||
@@ -90,9 +103,11 @@ http {
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /app/data/acme-webroot;
|
||||
default_type "text/plain";
|
||||
try_files $uri =404;
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location = /sw.js {
|
||||
@@ -159,6 +174,10 @@ http {
|
||||
root /app/html;
|
||||
index index.html index.htm;
|
||||
expires off;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'sha256-gQLhWUEDVfLtBiv83VAckuSAVmhxOpOHbNpFbODgPN0='; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: http: https:; font-src 'self' data:; connect-src 'self' http: https: ws: wss:; media-src 'self' data: blob: http: https:; worker-src 'self' blob:; frame-src http: https:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||||
@@ -203,66 +222,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/alerts(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/ai(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
# The chat endpoint streams server-sent events; buffering would
|
||||
# hold tokens back until the whole reply finished.
|
||||
proxy_read_timeout 600s;
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
}
|
||||
|
||||
location ~ ^/automations(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/alert-rules(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/notification-channels(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/alert-firings(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/rbac(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -285,31 +244,7 @@ http {
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location ~ ^/snippets(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/fleets(/.*)?$ {
|
||||
client_max_body_size 200m;
|
||||
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
}
|
||||
|
||||
location ~ ^/vault(/.*)?$ {
|
||||
location ~ ^/ssh-auth(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
@@ -327,36 +262,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/termix-id(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 ~ ^/proxmox(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 120s;
|
||||
proxy_read_timeout 120s;
|
||||
}
|
||||
|
||||
location ~ ^/c2s-tunnel-presets(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/audit-logs(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -366,7 +271,7 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/terminal(/.*)?$ {
|
||||
location ~ ^/plugins(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
@@ -375,6 +280,93 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
# Plugin frontend bundles, stylesheets and locales. Public like
|
||||
# /assets; the backend picks the cache policy from the ?v= query.
|
||||
location ^~ /plugin-assets/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
# 2.8 URLs that something outside Termix still calls: the Vault OIDC
|
||||
# callback, the Termix ID resolver and automation webhooks. The
|
||||
# backend redirects each to the plugin that serves it now (see
|
||||
# contributes.http in each plugin's manifest). New plugins never add
|
||||
# a block here.
|
||||
location = /vault/oidc/callback {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ^~ /termix-id/u/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 ^~ /automations/webhook/ {
|
||||
rewrite ^/automations/webhook/(.*)$ /plugin-api/automations/webhook/$1 last;
|
||||
}
|
||||
|
||||
# Every plugin's HTTP routes. One block, no per-plugin entries: a
|
||||
# plugin serves at /plugin-api/<id>/ on the main backend and never
|
||||
# gets a port or a block of its own. Buffering is off so SSE streams
|
||||
# (AI, Proxmox discovery) reach the browser as they are produced, and
|
||||
# request buffering is off so large uploads stream through.
|
||||
location ^~ /plugin-api/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
client_max_body_size 0;
|
||||
}
|
||||
|
||||
# Every plugin's WebSockets: terminal, Guacamole display, Docker
|
||||
# console. Served at /plugin-ws/<id>/<path> from the same backend.
|
||||
location ^~ /plugin-ws/ {
|
||||
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 $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
location ~ ^/open-tabs(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -384,15 +376,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/workspaces(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/user-preferences(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -448,25 +431,6 @@ http {
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location ~ ^/db(/.*)?$ {
|
||||
client_max_body_size 5G;
|
||||
client_body_timeout 300s;
|
||||
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location ~ ^/encryption(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -488,40 +452,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/host/opkssh-chooser(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001/host/opkssh-chooser$1$is_args$args;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_cache_bypass 1;
|
||||
proxy_no_cache 1;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||||
}
|
||||
|
||||
location ~ ^/host/opkssh-callback(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001/host/opkssh-callback$1$is_args$args;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_cache_bypass 1;
|
||||
proxy_no_cache 1;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||||
}
|
||||
|
||||
location /host/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -531,206 +461,10 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /session_logs/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /tailscale/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /ssh/websocket/ {
|
||||
proxy_pass http://127.0.0.1:30002/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
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_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
location ^~ /guacamole/websocket/ {
|
||||
proxy_pass http://127.0.0.1:30008/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
location ~ ^/guacamole(/.*)?$ {
|
||||
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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/session-sharing(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/tunnel/ {
|
||||
proxy_pass http://127.0.0.1:30003;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /ssh/tunnel/ {
|
||||
proxy_pass http://127.0.0.1:30003;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
}
|
||||
|
||||
location /host/file_manager/recent {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/file_manager/pinned {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/file_manager/shortcuts {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/file_manager/sudo-password {
|
||||
proxy_pass http://127.0.0.1:30004;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /ssh/file_manager/ {
|
||||
client_max_body_size 5G;
|
||||
client_body_timeout 300s;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
||||
|
||||
proxy_pass http://127.0.0.1:30004;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location /host/file_manager/ssh/ {
|
||||
client_max_body_size 5G;
|
||||
client_body_timeout 300s;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
||||
|
||||
proxy_pass http://127.0.0.1:30004;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location ~ ^/network-topology(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
# File manager routes (recent/pinned/shortcuts, SFTP, transfers) moved
|
||||
# to the file-manager plugin, served under /plugin-api/file-manager/.
|
||||
# Session logs moved to the session-recording plugin, served under
|
||||
# /plugin-api/session-recording/.
|
||||
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
@@ -741,8 +475,11 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/status(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
# Service links and the homepage widget canvas moved to the homepage
|
||||
# plugin, served under /plugin-api/homepage/.
|
||||
|
||||
location /dashboard/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
@@ -750,173 +487,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/metrics(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location ~ ^/(refresh|host-updated)$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/host-metrics(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
}
|
||||
|
||||
location ~ ^/proxmox-stats(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
}
|
||||
|
||||
location ~ ^/global-settings(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/uptime(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30006;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/activity(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30006;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/service-links(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30006;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/homepage(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30012;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ^~ /docker/console/ {
|
||||
proxy_pass http://127.0.0.1:30009/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
# --- tmux-monitor begin ---
|
||||
location ~ ^/tmux_monitor(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30010;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
# --- tmux-monitor end ---
|
||||
|
||||
location ~ ^/docker(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30007;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location ^~ /serial/websocket/ {
|
||||
proxy_pass http://127.0.0.1:30011/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /app/html;
|
||||
|
||||
+107
-546
@@ -79,9 +79,11 @@ http {
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /app/data/acme-webroot;
|
||||
default_type "text/plain";
|
||||
try_files $uri =404;
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location = /sw.js {
|
||||
@@ -142,6 +144,10 @@ http {
|
||||
root /app/html;
|
||||
index index.html index.htm;
|
||||
expires off;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'sha256-gQLhWUEDVfLtBiv83VAckuSAVmhxOpOHbNpFbODgPN0='; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: http: https:; font-src 'self' data:; connect-src 'self' http: https: ws: wss:; media-src 'self' data: blob: http: https:; worker-src 'self' blob:; frame-src http: https:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||||
try_files $uri $uri/ /index.html;
|
||||
@@ -185,66 +191,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/alerts(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/ai(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
# The chat endpoint streams server-sent events; buffering would
|
||||
# hold tokens back until the whole reply finished.
|
||||
proxy_read_timeout 600s;
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
}
|
||||
|
||||
location ~ ^/automations(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/alert-rules(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/notification-channels(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/alert-firings(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/rbac(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -267,31 +213,7 @@ http {
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location ~ ^/snippets(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/fleets(/.*)?$ {
|
||||
client_max_body_size 200m;
|
||||
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
}
|
||||
|
||||
location ~ ^/vault(/.*)?$ {
|
||||
location ~ ^/ssh-auth(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
@@ -309,36 +231,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/termix-id(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 ~ ^/proxmox(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 120s;
|
||||
proxy_read_timeout 120s;
|
||||
}
|
||||
|
||||
location ~ ^/c2s-tunnel-presets(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/audit-logs(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -348,7 +240,7 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/terminal(/.*)?$ {
|
||||
location ~ ^/plugins(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
@@ -357,6 +249,93 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
# Plugin frontend bundles, stylesheets and locales. Public like
|
||||
# /assets; the backend picks the cache policy from the ?v= query.
|
||||
location ^~ /plugin-assets/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
# 2.8 URLs that something outside Termix still calls: the Vault OIDC
|
||||
# callback, the Termix ID resolver and automation webhooks. The
|
||||
# backend redirects each to the plugin that serves it now (see
|
||||
# contributes.http in each plugin's manifest). New plugins never add
|
||||
# a block here.
|
||||
location = /vault/oidc/callback {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ^~ /termix-id/u/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 ^~ /automations/webhook/ {
|
||||
rewrite ^/automations/webhook/(.*)$ /plugin-api/automations/webhook/$1 last;
|
||||
}
|
||||
|
||||
# Every plugin's HTTP routes. One block, no per-plugin entries: a
|
||||
# plugin serves at /plugin-api/<id>/ on the main backend and never
|
||||
# gets a port or a block of its own. Buffering is off so SSE streams
|
||||
# (AI, Proxmox discovery) reach the browser as they are produced, and
|
||||
# request buffering is off so large uploads stream through.
|
||||
location ^~ /plugin-api/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
client_max_body_size 0;
|
||||
}
|
||||
|
||||
# Every plugin's WebSockets: terminal, Guacamole display, Docker
|
||||
# console. Served at /plugin-ws/<id>/<path> from the same backend.
|
||||
location ^~ /plugin-ws/ {
|
||||
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 $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
location ~ ^/open-tabs(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -366,15 +345,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/workspaces(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/user-preferences(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -430,25 +400,6 @@ http {
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location ~ ^/db(/.*)?$ {
|
||||
client_max_body_size 5G;
|
||||
client_body_timeout 300s;
|
||||
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location ~ ^/encryption(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -470,38 +421,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/host/opkssh-chooser(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001/host/opkssh-chooser$1$is_args$args;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_cache_bypass 1;
|
||||
proxy_no_cache 1;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||||
}
|
||||
|
||||
location ~ ^/host/opkssh-callback(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001/host/opkssh-callback$1$is_args$args;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_cache_bypass 1;
|
||||
proxy_no_cache 1;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||||
}
|
||||
|
||||
location /host/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
@@ -511,204 +430,10 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /session_logs/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /tailscale/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /ssh/websocket/ {
|
||||
proxy_pass http://127.0.0.1:30002/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
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_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
location ^~ /guacamole/websocket/ {
|
||||
proxy_pass http://127.0.0.1:30008/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
location ~ ^/guacamole(/.*)?$ {
|
||||
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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/session-sharing(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/tunnel/ {
|
||||
proxy_pass http://127.0.0.1:30003;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /ssh/tunnel/ {
|
||||
proxy_pass http://127.0.0.1:30003;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
}
|
||||
|
||||
location /host/file_manager/recent {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/file_manager/pinned {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/file_manager/shortcuts {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /host/file_manager/sudo-password {
|
||||
proxy_pass http://127.0.0.1:30004;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location /ssh/file_manager/ {
|
||||
client_max_body_size 5G;
|
||||
client_body_timeout 300s;
|
||||
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
||||
|
||||
proxy_pass http://127.0.0.1:30004;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location /host/file_manager/ssh/ {
|
||||
client_max_body_size 5G;
|
||||
client_body_timeout 300s;
|
||||
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
||||
|
||||
proxy_pass http://127.0.0.1:30004;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location ~ ^/network-topology(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
# File manager routes (recent/pinned/shortcuts, SFTP, transfers) moved
|
||||
# to the file-manager plugin, served under /plugin-api/file-manager/.
|
||||
# Session logs moved to the session-recording plugin, served under
|
||||
# /plugin-api/session-recording/.
|
||||
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
@@ -719,8 +444,11 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/status(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
# Service links and the homepage widget canvas moved to the homepage
|
||||
# plugin, served under /plugin-api/homepage/.
|
||||
|
||||
location /dashboard/ {
|
||||
proxy_pass http://127.0.0.1:30001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
@@ -728,173 +456,6 @@ http {
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/metrics(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location ~ ^/(refresh|host-updated)$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/host-metrics(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
}
|
||||
|
||||
location ~ ^/proxmox-stats(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
}
|
||||
|
||||
location ~ ^/global-settings(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30005;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/uptime(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30006;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/activity(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30006;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/service-links(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30006;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ~ ^/homepage(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30012;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
}
|
||||
|
||||
location ^~ /docker/console/ {
|
||||
proxy_pass http://127.0.0.1:30009/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
}
|
||||
|
||||
# --- tmux-monitor begin ---
|
||||
location ~ ^/tmux_monitor(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30010;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
# --- tmux-monitor end ---
|
||||
|
||||
location ~ ^/docker(/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:30007;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location ^~ /serial/websocket/ {
|
||||
proxy_pass http://127.0.0.1:30011/;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_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 $proxy_x_forwarded_proto;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_connect_timeout 10s;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /app/html;
|
||||
|
||||
+22
-13
@@ -229,7 +229,7 @@ RDP وVNC وTelnet داخل المتصفح، في علامات تبويب وشا
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**سطر الأوامر:**
|
||||
أداة `termix` لسطر الأوامر تعمل في الطرفية وفي سكربتاتك. افتح الطرفيات، ونفّذ أمرًا على مضيف واحد أو على أسطول كامل، وانقل الملفات عبر SFTP، وأدر المضيفات والمقتطفات وبيانات الدخول. ثبّتها عبر `npm install -g @termix-cli/cli` أو استخدم ملفًا تنفيذيًا مستقلًا. راجع [وثائق سطر الأوامر](https://docs.termix.site/cli).
|
||||
أداة `termix` لسطر الأوامر تعمل في الطرفية وفي سكربتاتك. افتح الطرفيات، ونفّذ أمرًا على مضيف واحد أو على أسطول كامل، وانقل الملفات عبر SFTP، وأدر المضيفات والمقتطفات وبيانات الدخول. ثبّتها عبر `npm install -g @termix-ssh/cli` أو استخدم ملفًا تنفيذيًا مستقلًا. راجع [وثائق سطر الأوامر](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +237,7 @@ RDP وVNC وTelnet داخل المتصفح، في علامات تبويب وشا
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**الأمان:**
|
||||
تُشفَّر كلمات المرور والمفاتيح والأسرار الأخرى لكل مستخدم على حدة، ويمكن تشفير ملفات قاعدة البيانات نفسها على القرص. راجع [الوثائق](https://docs.termix.site/security) لمعرفة آلية العمل.
|
||||
تُشفَّر كلمات المرور والمفاتيح والأسرار الأخرى لكل مستخدم على حدة، ويمكن تشفير ملفات قاعدة البيانات نفسها على القرص. راجع [الوثائق](https://docs.termix.site/features/authentication/security/) لمعرفة آلية العمل.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -355,7 +355,7 @@ networks:
|
||||
يوفر Termix أيضًا أداة سطر أوامر، لتدير خوادمك من الطرفية وتستخدم Termix داخل سكربتاتك.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +372,9 @@ termix ssh 1
|
||||
|
||||
## بيانات الاستخدام
|
||||
|
||||
يرسل Termix إشارة صغيرة مجهولة مرة واحدة يوميًا، لأعرف عدد النسخ العاملة والميزات المستخدمة فعلًا. تحتوي على معرّف عشوائي للنسخة، وعدد المستخدمين والمضيفات لديك، وإصدار التطبيق، والميزات التي استُخدمت خلال آخر 24 ساعة (الطرفية ومدير الملفات والأنفاق وdocker وغيرها). ولا تحتوي أبدًا على أسماء مستخدمين أو أسماء مضيفات أو عناوين IP أو بيانات دخول أو أي شيء يعرّف بك أو بخوادمك.
|
||||
يرسل Termix تقريرًا صغيرًا مجهول الهوية مرة واحدة يوميًا حتى أعرف عدد النسخ العاملة والميزات المستخدمة. يحتوي على معرّف عشوائي للنسخة، وإصدار التطبيق، وعدد المستخدمين والأجهزة لديك. ويمكن أن يتضمن أيضًا منصتك (نظام التشغيل، والمعمارية، وإصدار Node.js، ونوع قاعدة البيانات، وهل تستخدم Docker أو تطبيق سطح المكتب أو خادمًا عاديًا)، وعدد مرات فتح كل نوع من التبويبات وعدد عمليات تسجيل الدخول عبر SSH، والميزات المدمجة التي تعمل. لا يحتوي أبدًا على أسماء المستخدمين أو أسماء الأجهزة أو عناوين IP أو بيانات الدخول أو أي شيء آخر يعرّف بك أو بخوادمك.
|
||||
|
||||
وهي مفعّلة افتراضيًا. يمكنك إيقافها من إعدادات المسؤول ضمن قسم عام، أو ضبط `ENABLE_TELEMETRY=false` قبل تشغيل Termix أصلًا.
|
||||
وهي مفعّلة افتراضيًا. يمكنك إيقافها أو اختيار ما تتضمنه من إعدادات المسؤول ضمن قسم Usage Statistics، وهناك يمكنك أيضًا معاينة التقرير كما سيُرسل تمامًا. ويمكن لكل مستخدم استبعاد استخدامه الشخصي للميزات من ملفه الشخصي. ضبط `ENABLE_TELEMETRY=false` يوقفها ويقفل المفتاح.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +390,52 @@ Termix مجاني ومفتوح المصدر، بلا اشتراكات ولا خ
|
||||
|
||||
هل تهتم بمساحة إعلانية مدفوعة لدعم التطوير؟ راسلنا على [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## الدعم
|
||||
|
||||
+35
-31
@@ -89,7 +89,7 @@ Termix 是一个免费、开源、自托管的服务器管理平台。它把 SSH
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**文件管理器:**
|
||||
通过 SFTP 浏览、编辑、上传、下载、重命名、移动和删除文件,支持 sudo。可以查看和编辑代码、图片、音频和视频。文件可以直接从一台服务器复制到另一台,系统会自动选择最快的路径并校验传输完整性。
|
||||
通过 SFTP 浏览、编辑、上传、下载、重命名、移动和删除文件,支持 sudo。可以查看和编辑代码、图片、音频和视频。在专属的传输标签页里把文件直接从一台服务器复制到另一台,系统会自动选择最快的路径并校验传输完整性。桌面端还提供本地和远程并排显示的视图。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -111,7 +111,7 @@ Termix 是一个免费、开源、自托管的服务器管理平台。它把 SSH
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**主机指标:**
|
||||
在大多数 Linux 服务器上查看 CPU、内存、磁盘、网络、温度、运行时间、进程、端口、登录记录和系统信息,并附带历史曲线图。管理卡片让你无需离开 Termix 就能处理服务、定时任务、软件包、用户、防火墙规则、WireGuard、Tailscale、SSL 证书、日志和健康检查。
|
||||
在大多数 Linux 服务器上查看 CPU、内存、磁盘、网络、温度、NVIDIA GPU、运行时间、进程、端口、登录记录和系统信息,并附带历史曲线图。管理卡片让你无需离开 Termix 就能处理服务、定时任务、软件包、用户、防火墙规则、WireGuard、Tailscale、SSL 证书、日志和健康检查。
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Termix 是一个免费、开源、自托管的服务器管理平台。它把 SSH
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**引导设置:**
|
||||
一个简短的引导流程会带你选择界面预设、主题、需要的功能,以及第一台主机。简洁模式会隐藏你用不到的东西,你随时可以重新运行引导或切换预设。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**桌面独立运行与同步:**
|
||||
桌面应用可以完全独立运行,自带本地后端和数据库,不需要服务器。你也可以把它连到 Termix 服务器,双向同步主机、凭据、代码片段等内容,并选择连接是在本地发起还是通过服务器发起。
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**命令行工具:**
|
||||
`termix` 命令行工具,可用于你的终端和脚本。打开终端、在单台主机或整个机群上执行命令、通过 SFTP 传输文件,以及管理主机、代码片段和凭据。用 `npm install -g @termix-cli/cli` 安装,或者直接下载独立的可执行文件。详见 [CLI 文档](https://docs.termix.site/cli)。
|
||||
`termix` 命令行工具,可用于你的终端和脚本。打开终端、在单台主机或整个机群上执行命令、通过 SFTP 传输文件,以及管理主机、代码片段和凭据。用 `npm install -g @termix-ssh/cli` 安装,或者直接下载独立的可执行文件。详见 [CLI 文档](https://docs.termix.site/cli)。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Termix 是一个免费、开源、自托管的服务器管理平台。它把 SSH
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**安全:**
|
||||
密码、密钥和其他机密按用户加密,数据库文件本身也可以在磁盘上加密。具体原理请查看[文档](https://docs.termix.site/security)。
|
||||
密码、密钥和其他机密按用户加密,数据库文件本身也可以在磁盘上加密。具体原理请查看[文档](https://docs.termix.site/features/authentication/security/)。
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Termix 是一个免费、开源、自托管的服务器管理平台。它把 SSH
|
||||
- **键盘快捷键** - 在标签页之间切换、关闭标签页等,全部可以重新绑定
|
||||
- **网络唤醒** - 从 Termix 或自动化步骤中唤醒一台机器
|
||||
- **受信任代理认证** - 由反向代理完成登录,并把用户信息传递进来
|
||||
- **丰富的 SSH 功能** - 跳板机、Warpgate、TOTP 验证、SOCKS5、主机密钥验证、密码自动填充、[OPKSSH](https://github.com/openpubkey/opkssh)、tmux、端口敲门、终端日志、代理转发、Bitwarden SSH 代理、HashiCorp Vault SSH 签名等等
|
||||
- **白标定制** - 管理员可以用自己的名称、图标和配色为实例重新品牌化
|
||||
- **Web 端点** - 在 Termix 内嵌打开主机自己的网页界面,比如路由器的管理页面,而不是另开一个标签页
|
||||
- **协作房间** - 持久化的房间,一群人可以一起在会话之间跳转,有主持人舞台和邀请功能
|
||||
- **丰富的 SSH 功能** - 跳板机、Warpgate、TOTP 验证、SOCKS5、主机密钥验证、密码自动填充、[OPKSSH](https://github.com/openpubkey/opkssh)、tmux、端口敲门、终端日志、代理转发、Bitwarden SSH 代理、HashiCorp Vault SSH 签名、Step CA、1Password Connect 等等
|
||||
- **Termix ID** - 内置的 sshid.io 式功能。认领一个用户名,在解析地址上发布你的公钥,并用内置 CA 签发 SSH 证书
|
||||
- **命令历史自动建议** - 在终端中输入时,根据你的命令历史给出行内建议
|
||||
- **桌面独立运行与同步** - 桌面应用自带本地后端和数据库可以独立运行,也可以选择和 Termix 服务器同步
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,9 @@ Termix 是一个免费、开源、自托管的服务器管理平台。它把 SSH
|
||||
|
||||
访问 [Termix 文档](https://docs.termix.site/install) 查看所有平台的完整安装说明。
|
||||
|
||||
要部署到 Kubernetes?Helm chart 在 `charts/termix` 目录下,涵盖 Ingress、Traefik、Argo CD、GitHub Actions 和 GitLab CI 的完整搭建说明见
|
||||
[docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes)。
|
||||
|
||||
Docker Compose 示例(如果你不打算使用远程桌面功能,可以省略 `guacd` 和相关网络配置):
|
||||
|
||||
```yaml
|
||||
@@ -352,10 +346,10 @@ networks:
|
||||
|
||||
### 命令行工具
|
||||
|
||||
Termix 还提供命令行工具,你可以在终端里管理服务器,也可以把 Termix 用在自己的脚本中。
|
||||
Termix 还提供命令行工具,让你可以在终端里管理服务器,也可以把 Termix 用在自己的脚本中。
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +366,9 @@ termix ssh 1
|
||||
|
||||
## 遥测
|
||||
|
||||
Termix 每天会发送一次匿名的小型统计信息,让我了解有多少实例在运行、哪些功能被用到。内容包括一个随机的实例 ID、你有多少用户和主机、应用版本,以及过去 24 小时内使用了哪些功能(终端、文件管理器、隧道、Docker 等)。它绝不包含用户名、主机名、IP 地址、凭据,或任何能识别你和你服务器的信息。
|
||||
Termix 每天会发送一次匿名的小型报告,让我知道有多少实例在运行、哪些功能被使用。报告包含一个随机的实例 ID、应用版本,以及你的用户数和主机数。它还可以包含你的平台信息(操作系统、架构、Node.js 版本、数据库类型,以及你是用 Docker、桌面应用还是普通服务器运行)、每种标签页被打开的次数和 SSH 登录次数,以及正在运行的内置功能。它绝不会包含用户名、主机名、IP 地址、凭据或任何能识别你或你的服务器的信息。
|
||||
|
||||
该功能默认开启。你可以在管理设置的“通用”中关闭它,或者在启动 Termix 之前设置 `ENABLE_TELEMETRY=false`。
|
||||
该功能默认开启。你可以在管理设置的"Usage Statistics"中关闭它或选择要包含的内容,还可以在那里预览将要发送的完整报告。每个用户都可以在个人资料中排除自己的功能使用数据。设置 `ENABLE_TELEMETRY=false` 会关闭它并锁定开关。
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +384,52 @@ Termix 免费且开源,没有订阅也没有付费方案。如果你觉得它
|
||||
|
||||
有意通过付费展示位支持开发吗?请发邮件到 [mail@termix.site](mailto:mail@termix.site)。
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## 支持
|
||||
@@ -498,3 +501,4 @@ Termix 免费且开源,没有订阅也没有付费方案。如果你觉得它
|
||||
## 许可证
|
||||
|
||||
基于 Apache License 2.0 发布。详见 `LICENSE`。
|
||||
</content>
|
||||
+33
-29
@@ -111,7 +111,7 @@ Hosts mit Tags und verschachtelten Ordnern ordnen, die du benennen und einfärbe
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Host-Metriken:**
|
||||
CPU, Speicher, Festplatte, Netzwerk, Temperatur, Laufzeit, Prozesse, Ports, Anmeldungen und Systeminfos auf den meisten Linux-Servern, mit Verlaufsgrafiken. Über Verwaltungskarten kümmerst du dich um Dienste, Cronjobs, Pakete, Benutzer, Firewallregeln, WireGuard, Tailscale, SSL-Zertifikate, Logs und Statusprüfungen, ohne Termix zu verlassen.
|
||||
CPU, Speicher, Festplatte, Netzwerk, Temperatur, NVIDIA-GPU, Laufzeit, Prozesse, Ports, Anmeldungen und Systeminfos auf den meisten Linux-Servern, mit Verlaufsgrafiken. Über Verwaltungskarten kümmerst du dich um Dienste, Cronjobs, Pakete, Benutzer, Firewallregeln, WireGuard, Tailscale, SSL-Zertifikate, Logs und Statusprüfungen, ohne Termix zu verlassen.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Speichere eine Reihe von Tabs samt Aufteilung und öffne alles mit einem Klick w
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Geführte Einrichtung:**
|
||||
Eine kurze Einrichtung führt dich durch die Wahl einer Oberflächenvorlage, deines Themas, der gewünschten Funktionen und deines ersten Hosts. Der einfache Modus blendet aus, was du nicht nutzt, und du kannst die Einrichtung jederzeit erneut starten oder die Vorlage wechseln.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Desktop eigenständig und Synchronisierung:**
|
||||
Die Desktop-App läuft eigenständig mit lokalem Backend und eigener Datenbank, ganz ohne Server. Du kannst sie auch mit einem Termix-Server verbinden, um Hosts, Zugangsdaten, Snippets und mehr in beide Richtungen abzugleichen, und wählen, ob Verbindungen lokal oder über den Server aufgebaut werden.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Kommandozeile:**
|
||||
Ein `termix`-CLI für deine Shell und deine Skripte. Terminals öffnen, einen Befehl auf einem Host oder einer ganzen Flotte ausführen, Dateien per SFTP verschieben und Hosts, Snippets und Zugangsdaten verwalten. Installiere es mit `npm install -g @termix-cli/cli` oder nimm eine eigenständige Binärdatei. Siehe die [CLI-Dokumentation](https://docs.termix.site/cli).
|
||||
Ein `termix`-CLI für deine Shell und deine Skripte. Terminals öffnen, einen Befehl auf einem Host oder einer ganzen Flotte ausführen, Dateien per SFTP verschieben und Hosts, Snippets und Zugangsdaten verwalten. Installiere es mit `npm install -g @termix-ssh/cli` oder nimm eine eigenständige Binärdatei. Siehe die [CLI-Dokumentation](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Ein `termix`-CLI für deine Shell und deine Skripte. Terminals öffnen, einen Be
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Sicherheit:**
|
||||
Passwörter, Schlüssel und andere Geheimnisse werden pro Benutzer verschlüsselt, und die Datenbankdateien selbst lassen sich auf der Festplatte verschlüsseln. Wie das funktioniert, steht in der [Dokumentation](https://docs.termix.site/security).
|
||||
Passwörter, Schlüssel und andere Geheimnisse werden pro Benutzer verschlüsselt, und die Datenbankdateien selbst lassen sich auf der Festplatte verschlüsseln. Wie das funktioniert, steht in der [Dokumentation](https://docs.termix.site/features/authentication/security/).
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Rund 30 Sprachen sind eingebaut, verwaltet über [Crowdin](https://docs.termix.s
|
||||
- **Tastenkürzel** - Zwischen Tabs wechseln, Tabs schließen und mehr, alles neu belegbar
|
||||
- **Wake-on-LAN** - Einen Rechner aus Termix heraus oder aus einem Automatisierungsschritt aufwecken
|
||||
- **Vertrauenswürdiger Proxy** - Einen Reverse Proxy die Anmeldung erledigen und den Benutzer durchreichen lassen
|
||||
- **Viele SSH-Funktionen** - Sprunghosts, Warpgate, TOTP-Abfragen, SOCKS5, Prüfung von Hostschlüsseln, automatisches Ausfüllen von Passwörtern, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, Port Knocking, Terminalprotokolle, Agent-Weiterleitung, Bitwarden SSH-Agent, SSH-Signierung über HashiCorp Vault und mehr
|
||||
- **White Label** - Administratoren können die Instanz mit eigenem Namen, Logo und Farben versehen
|
||||
- **Web-Endpunkte** - Öffne die eigene Weboberfläche eines Hosts, etwa die Verwaltungsseite eines Routers, eingebettet in Termix statt in einem eigenen Tab
|
||||
- **Kollaborationsräume** - Feste Räume, in denen eine Gruppe gemeinsam zwischen Sitzungen wechselt, mit Präsentationsbühne und Einladungen
|
||||
- **Viele SSH-Funktionen** - Sprunghosts, Warpgate, TOTP-Abfragen, SOCKS5, Prüfung von Hostschlüsseln, automatisches Ausfüllen von Passwörtern, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, Port Knocking, Terminalprotokolle, Agent-Weiterleitung, Bitwarden SSH-Agent, SSH-Signierung über HashiCorp Vault, Step CA, 1Password Connect und mehr
|
||||
- **Termix ID** - Eine eingebaute Variante von sshid.io. Sichere dir einen Namen, veröffentliche deine öffentlichen Schlüssel unter einer Resolver-URL und stelle SSH-Zertifikate über die eingebaute CA aus
|
||||
- **Autovervollständigung im Befehlsverlauf** - Vorschläge direkt im Terminal beim Tippen, basierend auf deinem Befehlsverlauf
|
||||
- **Desktop eigenständig und Synchronisierung** - Die Desktop-App läuft eigenständig mit lokalem Backend und eigener Datenbank und kann sich optional mit einem Termix-Server synchronisieren
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,10 @@ Rund 30 Sprachen sind eingebaut, verwaltet über [Crowdin](https://docs.termix.s
|
||||
|
||||
In der [Termix-Dokumentation](https://docs.termix.site/install) findest du die vollständigen Installationsanleitungen für alle Plattformen.
|
||||
|
||||
Willst du auf Kubernetes bereitstellen? Das Helm-Chart liegt in `charts/termix`, und die Einrichtung
|
||||
für Ingress, Traefik, Argo CD, GitHub Actions und GitLab CI steht unter
|
||||
[docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes).
|
||||
|
||||
Beispiel für eine Docker-Compose-Datei (`guacd` und das Netzwerk kannst du weglassen, wenn du keinen Remotedesktop brauchst):
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +350,7 @@ networks:
|
||||
Termix hat auch ein CLI, damit du deine Server vom Terminal aus verwalten und Termix in eigenen Skripten nutzen kannst.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +367,9 @@ Du kannst den Termix-Server auf einem VPS laufen lassen statt im eigenen Netz. L
|
||||
|
||||
## Telemetrie
|
||||
|
||||
Termix schickt einmal am Tag ein kleines anonymes Signal, damit ich sehen kann, wie viele Instanzen laufen und welche Funktionen genutzt werden. Enthalten sind eine zufällige Instanz-ID, wie viele Benutzer und Hosts du hast, die App-Version und welche Funktionen (Terminal, Dateimanager, Tunnel, Docker usw.) in den letzten 24 Stunden benutzt wurden. Niemals enthalten sind Benutzernamen, Hostnamen, IP-Adressen, Zugangsdaten oder irgendetwas anderes, das dich oder deine Server identifiziert.
|
||||
Termix schickt einmal am Tag einen kleinen anonymen Bericht, damit ich sehe, wie viele Instanzen laufen und welche Funktionen genutzt werden. Er enthält eine zufällige Instanz-ID, die App-Version und wie viele Benutzer und Hosts du hast. Er kann außerdem deine Plattform enthalten (Betriebssystem, Architektur, Node.js-Version, Datenbanktyp und ob du Docker, die Desktop-App oder einen normalen Server nutzt), wie oft jede Art von Tab geöffnet wurde und wie viele SSH-Logins es gab, sowie welche eingebauten Funktionen laufen. Er enthält nie Benutzernamen, Hostnamen, IP-Adressen, Zugangsdaten oder sonst etwas, das dich oder deine Server erkennbar macht.
|
||||
|
||||
Es ist standardmäßig an. Schalte es in den Administrationseinstellungen unter Allgemein aus oder setze `ENABLE_TELEMETRY=false`, bevor du Termix überhaupt startest.
|
||||
Es ist standardmäßig an. Schalte es in den Administrationseinstellungen unter Usage Statistics aus oder wähle dort, was gesendet wird. Dort kannst du dir auch den genauen Bericht vorab ansehen. Jeder Benutzer kann seine eigene Funktionsnutzung in seinem Profil ausschließen. `ENABLE_TELEMETRY=false` schaltet es aus und sperrt den Schalter.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +385,52 @@ Termix ist kostenlos und quelloffen, ohne Abo und ohne Bezahlmodell. Wenn es dir
|
||||
|
||||
Interesse an einer bezahlten Platzierung zur Unterstützung der Entwicklung? Schreib an [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Support
|
||||
|
||||
+33
-29
@@ -111,7 +111,7 @@ Guarda y organiza hosts con etiquetas y carpetas anidadas que puedes nombrar y c
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Métricas de host:**
|
||||
CPU, memoria, disco, red, temperatura, tiempo encendido, procesos, puertos, inicios de sesión e información del sistema en la mayoría de servidores Linux, con gráficas de histórico. Las tarjetas de gestión te dejan manejar servicios, tareas cron, paquetes, usuarios, reglas del cortafuegos, WireGuard, Tailscale, certificados SSL, registros y comprobaciones de estado sin salir de Termix.
|
||||
CPU, memoria, disco, red, temperatura, GPU NVIDIA, tiempo encendido, procesos, puertos, inicios de sesión e información del sistema en la mayoría de servidores Linux, con gráficas de histórico. Las tarjetas de gestión te dejan manejar servicios, tareas cron, paquetes, usuarios, reglas del cortafuegos, WireGuard, Tailscale, certificados SSL, registros y comprobaciones de estado sin salir de Termix.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Guarda un conjunto de pestañas con su distribución dividida y reábrelo entero
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Configuración guiada:**
|
||||
Una configuración corta te lleva por elegir un preajuste de interfaz, tu tema, las funciones que quieres y tu primer host. El modo sencillo esconde lo que no usas, y puedes repetir la configuración o cambiar de preajuste cuando quieras.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Escritorio independiente y sincronización:**
|
||||
La aplicación de escritorio funciona sola, con su backend y su base de datos locales, sin necesidad de servidor. También puedes conectarla a un servidor Termix para sincronizar en ambos sentidos hosts, credenciales, fragmentos y más, y decidir si las conexiones salen de tu equipo o pasan por el servidor.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Línea de comandos:**
|
||||
Un CLI `termix` para tu shell y tus scripts. Abre terminales, ejecuta un comando en un host o en una flota entera, mueve archivos por SFTP y gestiona hosts, fragmentos y credenciales. Instálalo con `npm install -g @termix-cli/cli` o coge un binario independiente. Consulta la [documentación del CLI](https://docs.termix.site/cli).
|
||||
Un CLI `termix` para tu shell y tus scripts. Abre terminales, ejecuta un comando en un host o en una flota entera, mueve archivos por SFTP y gestiona hosts, fragmentos y credenciales. Instálalo con `npm install -g @termix-ssh/cli` o coge un binario independiente. Consulta la [documentación del CLI](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Un CLI `termix` para tu shell y tus scripts. Abre terminales, ejecuta un comando
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Seguridad:**
|
||||
Las contraseñas, las claves y otros secretos se cifran por usuario, y los propios archivos de la base de datos se pueden cifrar en disco. Mira la [documentación](https://docs.termix.site/security) para saber cómo funciona.
|
||||
Las contraseñas, las claves y otros secretos se cifran por usuario, y los propios archivos de la base de datos se pueden cifrar en disco. Mira la [documentación](https://docs.termix.site/features/authentication/security/) para saber cómo funciona.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Unos 30 idiomas incluidos, gestionados a través de [Crowdin](https://docs.termi
|
||||
- **Atajos de teclado** - Moverte entre pestañas, cerrarlas y más, todo reasignable
|
||||
- **Wake-on-LAN** - Enciende una máquina desde Termix o desde un paso de automatización
|
||||
- **Proxy de confianza** - Deja que un proxy inverso gestione el acceso y pase al usuario
|
||||
- **SSH muy completo** - Hosts de salto, Warpgate, peticiones TOTP, SOCKS5, verificación de claves de host, autorrelleno de contraseñas, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, registro del terminal, reenvío de agente, agente SSH de Bitwarden, firma SSH con HashiCorp Vault y más
|
||||
- **Marca blanca** - Los administradores pueden personalizar la instancia con su propio nombre, logo y colores
|
||||
- **Puntos de acceso web** - Abre la propia interfaz web de un host, como la página de administración de un router, integrada dentro de Termix en lugar de en una pestaña aparte
|
||||
- **Salas de colaboración** - Salas persistentes donde un grupo salta entre sesiones junto, con un escenario para presentador e invitaciones
|
||||
- **SSH muy completo** - Hosts de salto, Warpgate, peticiones TOTP, SOCKS5, verificación de claves de host, autorrelleno de contraseñas, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, registro del terminal, reenvío de agente, agente SSH de Bitwarden, firma SSH con HashiCorp Vault, Step CA, 1Password Connect y más
|
||||
- **Termix ID** - Una versión integrada de sshid.io. Reserva un identificador, publica tus claves públicas en una URL de resolución y emite certificados SSH desde la CA integrada
|
||||
- **Autosugerencias del historial de comandos** - Sugerencias en línea en el terminal mientras escribes, basadas en tu historial de comandos
|
||||
- **Escritorio independiente y sincronización** - La aplicación de escritorio funciona sola, con su propio backend y base de datos locales, y puede sincronizarse opcionalmente con un servidor Termix
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,10 @@ Unos 30 idiomas incluidos, gestionados a través de [Crowdin](https://docs.termi
|
||||
|
||||
Visita la [documentación de Termix](https://docs.termix.site/install) para ver las instrucciones completas de instalación en todas las plataformas.
|
||||
|
||||
¿Vas a desplegar en Kubernetes? El chart de Helm está en `charts/termix`, y las instrucciones
|
||||
de configuración para Ingress, Traefik, Argo CD, GitHub Actions y GitLab CI están en
|
||||
[docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes).
|
||||
|
||||
Ejemplo de archivo Docker Compose (puedes quitar `guacd` y la red si no piensas usar el escritorio remoto):
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +350,7 @@ networks:
|
||||
Termix también tiene un CLI, para que gestiones tus servidores desde un terminal y uses Termix en tus propios scripts.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +367,9 @@ Puedes ejecutar el servidor de Termix en un VPS en lugar de dentro de tu propia
|
||||
|
||||
## Telemetría
|
||||
|
||||
Termix envía una vez al día un pequeño aviso anónimo para que pueda ver cuántas instancias hay funcionando y qué funciones se usan. Contiene un identificador de instancia aleatorio, cuántos usuarios y hosts tienes, la versión de la aplicación y qué funciones (terminal, gestor de archivos, túneles, docker, etc.) se han usado en las últimas 24 horas. Nunca contiene nombres de usuario, nombres de host, direcciones IP, credenciales ni nada que te identifique a ti o a tus servidores.
|
||||
Termix envía una vez al día un pequeño informe anónimo para que pueda ver cuántas instancias hay funcionando y qué funciones se usan. Incluye un ID de instancia aleatorio, la versión de la app y cuántos usuarios y hosts tienes. También puede incluir tu plataforma (sistema operativo, arquitectura, versión de Node.js, tipo de base de datos y si usas Docker, la app de escritorio o un servidor normal), cuántas veces se abrió cada tipo de pestaña y cuántos inicios de sesión SSH hubo, y qué funciones integradas están activas. Nunca incluye nombres de usuario, nombres de host, direcciones IP, credenciales ni nada que te identifique a ti o a tus servidores.
|
||||
|
||||
Viene activado. Puedes desactivarlo en los ajustes de administración, en General, o poner `ENABLE_TELEMETRY=false` antes incluso de arrancar Termix.
|
||||
Viene activado. Puedes desactivarlo o elegir qué incluye en los ajustes de administración, en Usage Statistics, donde también puedes ver el informe exacto antes de enviarlo. Cada usuario puede excluir su propio uso de funciones desde su perfil. Poner `ENABLE_TELEMETRY=false` lo desactiva y bloquea el interruptor.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +385,52 @@ Termix es gratuito y de código abierto, sin suscripciones ni planes de pago. Si
|
||||
|
||||
¿Te interesa un espacio de pago para apoyar el desarrollo? Escribe a [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Soporte
|
||||
|
||||
+31
-29
@@ -111,7 +111,7 @@ Rangez vos hôtes avec des étiquettes et des dossiers imbriqués que vous pouve
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Métriques des hôtes:**
|
||||
CPU, mémoire, disque, réseau, température, temps de fonctionnement, processus, ports, connexions et informations système sur la plupart des serveurs Linux, avec des graphiques d'historique. Les cartes de gestion vous permettent de gérer les services, les tâches cron, les paquets, les utilisateurs, les règles de pare-feu, WireGuard, Tailscale, les certificats SSL, les journaux et les vérifications d'état sans quitter Termix.
|
||||
CPU, mémoire, disque, réseau, température, GPU NVIDIA, temps de fonctionnement, processus, ports, connexions et informations système sur la plupart des serveurs Linux, avec des graphiques d'historique. Les cartes de gestion vous permettent de gérer les services, les tâches cron, les paquets, les utilisateurs, les règles de pare-feu, WireGuard, Tailscale, les certificats SSL, les journaux et les vérifications d'état sans quitter Termix.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Enregistrez un ensemble d'onglets avec leur disposition en écran divisé et rou
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Configuration guidée:**
|
||||
Une courte configuration vous aide à choisir un préréglage d'interface, votre thème, les fonctionnalités que vous voulez et votre premier hôte. Le mode simple masque ce que vous n'utilisez pas, et vous pouvez relancer la configuration ou changer de préréglage quand vous voulez.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Application de bureau autonome et synchronisation:**
|
||||
L'application de bureau fonctionne toute seule, avec son propre backend et sa base de données, sans serveur. Vous pouvez aussi la relier à un serveur Termix pour synchroniser dans les deux sens les hôtes, les identifiants, les extraits et le reste, et choisir si les connexions partent de votre machine ou passent par le serveur.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Ligne de commande:**
|
||||
Un CLI `termix` pour votre shell et vos scripts. Ouvrez des terminaux, lancez une commande sur un hôte ou une flotte entière, déplacez des fichiers en SFTP et gérez hôtes, extraits et identifiants. Installez-le avec `npm install -g @termix-cli/cli` ou récupérez un binaire autonome. Voir la [documentation du CLI](https://docs.termix.site/cli).
|
||||
Un CLI `termix` pour votre shell et vos scripts. Ouvrez des terminaux, lancez une commande sur un hôte ou une flotte entière, déplacez des fichiers en SFTP et gérez hôtes, extraits et identifiants. Installez-le avec `npm install -g @termix-ssh/cli` ou récupérez un binaire autonome. Voir la [documentation du CLI](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Un CLI `termix` pour votre shell et vos scripts. Ouvrez des terminaux, lancez un
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Sécurité:**
|
||||
Les mots de passe, les clés et les autres secrets sont chiffrés par utilisateur, et les fichiers de base de données eux-mêmes peuvent être chiffrés sur le disque. Voir la [documentation](https://docs.termix.site/security) pour le détail.
|
||||
Les mots de passe, les clés et les autres secrets sont chiffrés par utilisateur, et les fichiers de base de données eux-mêmes peuvent être chiffrés sur le disque. Voir la [documentation](https://docs.termix.site/features/authentication/security/) pour le détail.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Une trentaine de langues intégrées, gérées via [Crowdin](https://docs.termix
|
||||
- **Raccourcis clavier** - Naviguer entre les onglets, les fermer et plus encore, tout est reconfigurable
|
||||
- **Wake-on-LAN** - Réveillez une machine depuis Termix ou depuis une étape d'automatisation
|
||||
- **Authentification par proxy de confiance** - Laissez un reverse proxy gérer la connexion et transmettre l'utilisateur
|
||||
- **SSH complet** - Hôtes de rebond, Warpgate, demandes TOTP, SOCKS5, vérification des clés d'hôte, remplissage automatique des mots de passe, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, journalisation du terminal, transfert d'agent, agent SSH Bitwarden, signature SSH HashiCorp Vault et plus encore
|
||||
- **Marque blanche** - Les administrateurs peuvent personnaliser l'instance avec leur propre nom, logo et couleurs
|
||||
- **Points d'accès web** - Ouvrez l'interface web d'un hôte, comme la page d'administration d'un routeur, directement dans Termix plutôt que dans un onglet séparé
|
||||
- **Salles de collaboration** - Des salles persistantes où un groupe peut passer d'une session à l'autre ensemble, avec une scène pour le présentateur et des invitations
|
||||
- **SSH complet** - Hôtes de rebond, Warpgate, demandes TOTP, SOCKS5, vérification des clés d'hôte, remplissage automatique des mots de passe, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, journalisation du terminal, transfert d'agent, agent SSH Bitwarden, signature SSH HashiCorp Vault, Step CA, 1Password Connect et plus encore
|
||||
- **Termix ID** - Une version intégrée de sshid.io. Réservez un identifiant, publiez vos clés publiques sur une URL de résolution et émettez des certificats SSH depuis l'autorité intégrée
|
||||
- **Suggestions automatiques d'historique de commandes** - Des suggestions en ligne dans le terminal pendant que vous tapez, basées sur votre historique de commandes
|
||||
- **Application de bureau autonome et synchronisation** - L'application de bureau fonctionne toute seule, avec son propre backend et sa base de données, et peut en option se synchroniser avec un serveur Termix
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,8 @@ Une trentaine de langues intégrées, gérées via [Crowdin](https://docs.termix
|
||||
|
||||
Consultez la [documentation Termix](https://docs.termix.site/install) pour les instructions d'installation complètes sur toutes les plateformes.
|
||||
|
||||
Vous déployez sur Kubernetes ? Le chart Helm se trouve dans `charts/termix`, et les instructions de configuration couvrant Ingress, Traefik, Argo CD, GitHub Actions et GitLab CI sont sur [docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes).
|
||||
|
||||
Exemple de fichier Docker Compose (vous pouvez retirer `guacd` et le réseau si vous ne comptez pas utiliser le bureau à distance) :
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +348,7 @@ networks:
|
||||
Termix propose aussi un CLI, pour gérer vos serveurs depuis un terminal et utiliser Termix dans vos propres scripts.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +365,9 @@ Vous pouvez faire tourner le serveur Termix sur un VPS plutôt que dans votre pr
|
||||
|
||||
## Télémétrie
|
||||
|
||||
Termix envoie une fois par jour un petit signal anonyme, pour que je puisse voir combien d'instances tournent et quelles fonctionnalités servent vraiment. Il contient un identifiant d'instance aléatoire, le nombre d'utilisateurs et d'hôtes, la version de l'application et les fonctionnalités utilisées ces dernières 24 heures (terminal, gestionnaire de fichiers, tunnels, docker, etc.). Il ne contient jamais de noms d'utilisateur, de noms d'hôtes, d'adresses IP, d'identifiants ni quoi que ce soit qui puisse vous identifier, vous ou vos serveurs.
|
||||
Termix envoie une fois par jour un petit rapport anonyme, pour que je puisse voir combien d'instances tournent et quelles fonctionnalités sont utilisées. Il contient un identifiant d'instance aléatoire, la version de l'application et le nombre d'utilisateurs et d'hôtes. Il peut aussi inclure votre plateforme (système, architecture, version de Node.js, type de base de données, et si vous utilisez Docker, l'application de bureau ou un simple serveur), combien de fois chaque type d'onglet a été ouvert et combien de connexions SSH ont eu lieu, ainsi que les fonctionnalités intégrées actives. Il ne contient jamais de noms d'utilisateur, de noms d'hôte, d'adresses IP, d'identifiants ni quoi que ce soit qui permette de vous identifier, vous ou vos serveurs.
|
||||
|
||||
C'est activé par défaut. Désactivez-le dans les paramètres d'administration, section Général, ou définissez `ENABLE_TELEMETRY=false` avant même de démarrer Termix.
|
||||
C'est activé par défaut. Désactivez-le ou choisissez ce qu'il contient dans les paramètres d'administration, section Usage Statistics, où vous pouvez aussi voir le rapport exact avant l'envoi. Chaque utilisateur peut exclure sa propre utilisation dans son profil. Définir `ENABLE_TELEMETRY=false` le désactive et verrouille l'interrupteur.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +383,52 @@ Termix est gratuit et open source, sans abonnement ni offre payante. S'il vous e
|
||||
|
||||
Intéressé par un emplacement payant pour soutenir le développement ? Écrivez à [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Support
|
||||
|
||||
+22
-13
@@ -229,7 +229,7 @@ CPU, मेमोरी और डिस्क जैसी होस्ट म
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**कमांड लाइन:**
|
||||
आपके शेल और स्क्रिप्ट के लिए `termix` CLI। टर्मिनल खोलें, किसी एक होस्ट या पूरे फ़्लीट पर कमांड चलाएँ, SFTP से फ़ाइलें भेजें, और होस्ट, स्निपेट व क्रेडेंशियल संभालें। `npm install -g @termix-cli/cli` से इंस्टॉल करें या अलग बाइनरी लें। [CLI दस्तावेज़](https://docs.termix.site/cli) देखें।
|
||||
आपके शेल और स्क्रिप्ट के लिए `termix` CLI। टर्मिनल खोलें, किसी एक होस्ट या पूरे फ़्लीट पर कमांड चलाएँ, SFTP से फ़ाइलें भेजें, और होस्ट, स्निपेट व क्रेडेंशियल संभालें। `npm install -g @termix-ssh/cli` से इंस्टॉल करें या अलग बाइनरी लें। [CLI दस्तावेज़](https://docs.termix.site/cli) देखें।
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +237,7 @@ CPU, मेमोरी और डिस्क जैसी होस्ट म
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**सुरक्षा:**
|
||||
पासवर्ड, कुंजियाँ और बाकी गोपनीय जानकारी हर उपयोगकर्ता के लिए अलग से एन्क्रिप्ट होती है, और डेटाबेस फ़ाइलें भी डिस्क पर एन्क्रिप्ट की जा सकती हैं। यह कैसे काम करता है, यह [दस्तावेज़](https://docs.termix.site/security) में देखें।
|
||||
पासवर्ड, कुंजियाँ और बाकी गोपनीय जानकारी हर उपयोगकर्ता के लिए अलग से एन्क्रिप्ट होती है, और डेटाबेस फ़ाइलें भी डिस्क पर एन्क्रिप्ट की जा सकती हैं। यह कैसे काम करता है, यह [दस्तावेज़](https://docs.termix.site/features/authentication/security/) में देखें।
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -355,7 +355,7 @@ networks:
|
||||
Termix में CLI भी है, ताकि आप टर्मिनल से अपने सर्वर संभाल सकें और Termix को अपनी स्क्रिप्ट में इस्तेमाल कर सकें।
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +372,9 @@ termix ssh 1
|
||||
|
||||
## टेलीमेट्री
|
||||
|
||||
Termix दिन में एक बार एक छोटा सा गुमनाम संकेत भेजता है, ताकि मुझे पता चले कि कितने इंस्टेंस चल रहे हैं और कौन सी सुविधाएँ सच में इस्तेमाल होती हैं। इसमें एक बेतरतीब इंस्टेंस आईडी, आपके पास कितने उपयोगकर्ता और होस्ट हैं, ऐप का संस्करण, और पिछले 24 घंटे में इस्तेमाल हुई सुविधाएँ (टर्मिनल, फ़ाइल मैनेजर, टनल, docker आदि) होती हैं। इसमें कभी भी उपयोगकर्ता नाम, होस्ट नाम, IP पते, क्रेडेंशियल या ऐसी कोई चीज़ नहीं होती जो आपकी या आपके सर्वर की पहचान बताए।
|
||||
Termix दिन में एक बार एक छोटी गुमनाम रिपोर्ट भेजता है ताकि मैं देख सकूं कि कितने इंस्टेंस चल रहे हैं और कौन से फ़ीचर इस्तेमाल हो रहे हैं। इसमें एक रैंडम इंस्टेंस ID, ऐप का वर्शन, और आपके यूज़र्स और होस्ट्स की संख्या होती है। इसमें आपका प्लेटफ़ॉर्म (OS, आर्किटेक्चर, Node.js वर्शन, डेटाबेस का प्रकार, और आप Docker, डेस्कटॉप ऐप या सामान्य सर्वर इस्तेमाल करते हैं), हर तरह का टैब कितनी बार खोला गया और कितने SSH लॉगिन हुए, और कौन से बिल्ट-इन फ़ीचर चल रहे हैं, यह भी हो सकता है। इसमें कभी भी यूज़रनेम, होस्टनेम, IP पते, क्रेडेंशियल या ऐसी कोई चीज़ नहीं होती जिससे आपकी या आपके सर्वर की पहचान हो।
|
||||
|
||||
यह डिफ़ॉल्ट रूप से चालू रहता है। इसे एडमिन सेटिंग्स में सामान्य के अंतर्गत बंद करें, या Termix शुरू करने से पहले ही `ENABLE_TELEMETRY=false` सेट कर दें।
|
||||
यह डिफ़ॉल्ट रूप से चालू रहता है। इसे एडमिन सेटिंग्स में Usage Statistics के अंतर्गत बंद करें या चुनें कि इसमें क्या शामिल हो, और वहीं भेजी जाने वाली रिपोर्ट पहले से देख भी सकते हैं। हर यूज़र अपनी प्रोफ़ाइल में अपना फ़ीचर इस्तेमाल हटा सकता है। `ENABLE_TELEMETRY=false` सेट करने से यह बंद हो जाता है और स्विच लॉक हो जाता है।
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +390,52 @@ Termix मुफ़्त और ओपन सोर्स है, न कोई
|
||||
|
||||
विकास में सहयोग के लिए पेड प्लेसमेंट में रुचि है? [mail@termix.site](mailto:mail@termix.site) पर ईमेल करें।
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## सहायता
|
||||
|
||||
+38
-32
@@ -83,13 +83,13 @@ RDP, VNC e Telnet nel browser, in schede e schermo diviso come qualsiasi altra s
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Tunnel SSH:**
|
||||
Inoltro locale, remoto e SOCKS dinamico, con riconnessione automatica e controlli di stato. I tunnel da client a server dell'app desktop restano su quella macchina, e puoi salvare delle preimpostazioni sul server per portare una configurazione su un altro computer.
|
||||
Inoltro locale, remoto e SOCKS dinamico, con riconnessione automatica e controlli di stato. I tunnel da client a server dell'app desktop restano su quella macchina, e puoi salvare delle preimpostazioni sul server per portare una configurazione su un altro client.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Gestore file:**
|
||||
Sfoglia, modifica, carica, scarica, rinomina, sposta ed elimina file via SFTP, anche con sudo. Guarda e modifica codice, immagini, audio e video. Copia i file direttamente da un server all'altro: il percorso più veloce viene scelto per te e i trasferimenti vengono verificati.
|
||||
Sfoglia, modifica, carica, scarica, rinomina, sposta ed elimina file via SFTP, anche con sudo. Guarda e modifica codice, immagini, audio e video. Copia i file direttamente da un server all'altro in una scheda dedicata di trasferimento, con il percorso più veloce scelto per te e i trasferimenti controllati per integrità. L'app desktop ha anche una vista affiancata di locale e remoto.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -111,7 +111,7 @@ Salva e organizza gli host con etichette e cartelle annidate a cui puoi dare nom
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Metriche host:**
|
||||
CPU, memoria, disco, rete, temperatura, tempo di accensione, processi, porte, accessi e informazioni di sistema sulla maggior parte dei server Linux, con grafici storici. Le schede di gestione ti fanno seguire servizi, cron, pacchetti, utenti, regole del firewall, WireGuard, Tailscale, certificati SSL, log e controlli di stato senza uscire da Termix.
|
||||
CPU, memoria, disco, rete, temperatura, GPU NVIDIA, tempo di accensione, processi, porte, accessi e informazioni di sistema sulla maggior parte dei server Linux, con grafici storici. Le schede di gestione ti fanno seguire servizi, cron, pacchetti, utenti, regole del firewall, WireGuard, Tailscale, certificati SSL, log e controlli di stato senza uscire da Termix.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Salva un insieme di schede con la loro disposizione divisa e riapri tutto con un
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Configurazione guidata:**
|
||||
Una breve configurazione ti accompagna nella scelta di una preimpostazione dell'interfaccia, del tema, delle funzionalità che vuoi e del primo host. La modalità semplice nasconde quello che non usi, e puoi rifare la configurazione o cambiare preimpostazione quando vuoi.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Desktop autonomo e sincronizzazione:**
|
||||
L'app desktop funziona da sola, con backend e database locali, senza bisogno di un server. Puoi anche collegarla a un server Termix per sincronizzare nei due sensi host, credenziali, frammenti e altro, e scegliere se le connessioni partono dal tuo computer o passano dal server.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Riga di comando:**
|
||||
Una CLI `termix` per la tua shell e i tuoi script. Apri terminali, esegui un comando su un host o su un'intera flotta, sposta file via SFTP e gestisci host, frammenti e credenziali. Installala con `npm install -g @termix-cli/cli` oppure prendi un binario autonomo. Vedi la [documentazione della CLI](https://docs.termix.site/cli).
|
||||
Una CLI `termix` per la tua shell e i tuoi script. Apri terminali, esegui un comando su un host o su un'intera flotta, sposta file via SFTP e gestisci host, frammenti e credenziali. Installala con `npm install -g @termix-ssh/cli` oppure prendi un binario autonomo. Vedi la [documentazione della CLI](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Una CLI `termix` per la tua shell e i tuoi script. Apri terminali, esegui un com
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Sicurezza:**
|
||||
Password, chiavi e altri segreti sono cifrati per ogni utente, e gli stessi file del database possono essere cifrati su disco. Guarda la [documentazione](https://docs.termix.site/security) per capire come funziona.
|
||||
Password, chiavi e altri segreti sono cifrati per ogni utente, e gli stessi file del database possono essere cifrati su disco. Guarda la [documentazione](https://docs.termix.site/features/authentication/security/) per capire come funziona.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Circa 30 lingue incluse, gestite tramite [Crowdin](https://docs.termix.site/tran
|
||||
- **Scorciatoie da tastiera** - Spostarsi tra le schede, chiuderle e altro, tutto riassegnabile
|
||||
- **Wake-on-LAN** - Accendi una macchina da Termix o da un passaggio di un'automazione
|
||||
- **Autenticazione tramite proxy fidato** - Lascia che un reverse proxy gestisca l'accesso e passi l'utente
|
||||
- **SSH molto completo** - Host di salto, Warpgate, richieste TOTP, SOCKS5, verifica delle chiavi host, riempimento automatico della password, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, log del terminale, inoltro dell'agente, agente SSH di Bitwarden, firma SSH con HashiCorp Vault e altro
|
||||
- **White label** - Gli amministratori possono rimarchiare l'istanza con nome, logo e colori propri
|
||||
- **Endpoint web** - Apri l'interfaccia web di un host, come la pagina di amministrazione di un router, incorporata dentro Termix invece che in una scheda separata
|
||||
- **Stanze di collaborazione** - Stanze persistenti dove un gruppo può passare insieme da una sessione all'altra, con un palco per il presentatore e inviti
|
||||
- **SSH molto completo** - Host di salto, Warpgate, richieste TOTP, SOCKS5, verifica delle chiavi host, riempimento automatico della password, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, log del terminale, inoltro dell'agente, agente SSH di Bitwarden, firma SSH con HashiCorp Vault, Step CA, 1Password Connect e altro
|
||||
- **Termix ID** - Una versione integrata di sshid.io. Prendi un identificativo, pubblica le tue chiavi pubbliche su un URL di risoluzione ed emetti certificati SSH dalla CA integrata
|
||||
- **Suggerimenti automatici nella cronologia comandi** - Suggerimenti in linea nel terminale mentre scrivi, basati sulla tua cronologia comandi
|
||||
- **Desktop autonomo e sincronizzazione** - L'app desktop funziona da sola, con backend e database locali, e può facoltativamente sincronizzarsi con un server Termix
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,10 @@ Circa 30 lingue incluse, gestite tramite [Crowdin](https://docs.termix.site/tran
|
||||
|
||||
Vai alla [documentazione di Termix](https://docs.termix.site/install) per le istruzioni complete di installazione su tutte le piattaforme.
|
||||
|
||||
Vuoi installare su Kubernetes? Il chart Helm è in `charts/termix`, e le istruzioni di configurazione
|
||||
per Ingress, Traefik, Argo CD, GitHub Actions e GitLab CI sono su
|
||||
[docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes).
|
||||
|
||||
Esempio di file Docker Compose (puoi togliere `guacd` e la rete se non pensi di usare il desktop remoto):
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +350,7 @@ networks:
|
||||
Termix ha anche una CLI, così puoi gestire i tuoi server dal terminale e usare Termix nei tuoi script.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -364,7 +359,7 @@ Può aprire terminali, eseguire un comando su un host o su un'intera flotta, spo
|
||||
|
||||
### Hosting in cloud
|
||||
|
||||
Puoi far girare il server Termix su un VPS invece che dentro la tua rete. Se Termix gira sulla rete che gestisce, un guasto se lo porta via proprio quando ti servirebbe per sistemare le cose. Fuori resta raggiungibile, ti dà un IP fisso e ci entri da ovunque senza VPN né porte aperte.
|
||||
Puoi far girare il server Termix su un VPS invece che dentro la tua rete. Se Termix gira sulla rete che gestisce, un guasto se lo porta via proprio quando ti servirebbe per sistemare le cose. Farlo girare altrove lo mantiene raggiungibile, ti dà un IP fisso e ti permette di entrare da ovunque senza VPN né porte aperte.
|
||||
|
||||
[GINERNET](https://docs.termix.site/install/ginernet) sponsorizza Termix, e nella documentazione c'è una guida passo passo per il rilascio sulla loro piattaforma VPS.
|
||||
|
||||
@@ -372,9 +367,9 @@ Puoi far girare il server Termix su un VPS invece che dentro la tua rete. Se Ter
|
||||
|
||||
## Telemetria
|
||||
|
||||
Termix invia una volta al giorno un piccolo segnale anonimo, così posso vedere quante istanze sono attive e quali funzionalità vengono usate davvero. Contiene un ID istanza casuale, quanti utenti e host hai, la versione dell'app e quali funzionalità (terminale, gestore file, tunnel, docker, ecc.) sono state usate nelle ultime 24 ore. Non contiene mai nomi utente, nomi host, indirizzi IP, credenziali o qualsiasi altra cosa che identifichi te o i tuoi server.
|
||||
Termix invia una volta al giorno un piccolo report anonimo, così posso vedere quante istanze sono attive e quali funzioni vengono usate. Contiene un ID di istanza casuale, la versione dell'app e quanti utenti e host hai. Può includere anche la tua piattaforma (sistema operativo, architettura, versione di Node.js, tipo di database e se usi Docker, l'app desktop o un server normale), quante volte è stato aperto ogni tipo di scheda e quanti login SSH ci sono stati, e quali funzioni integrate sono attive. Non contiene mai nomi utente, nomi host, indirizzi IP, credenziali o altro che identifichi te o i tuoi server.
|
||||
|
||||
È attivo di base. Puoi spegnerlo nelle impostazioni di amministrazione, sezione Generale, oppure impostare `ENABLE_TELEMETRY=false` prima ancora di avviare Termix.
|
||||
È attivo di base. Puoi spegnerlo o scegliere cosa include nelle impostazioni di amministrazione, sezione Usage Statistics, dove puoi anche vedere il report esatto prima dell'invio. Ogni utente può escludere il proprio uso delle funzioni dal suo profilo. Impostare `ENABLE_TELEMETRY=false` lo spegne e blocca l'interruttore.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +385,52 @@ Termix è gratuito e open source, senza abbonamenti né piani a pagamento. Se ti
|
||||
|
||||
Ti interessa uno spazio a pagamento per sostenere lo sviluppo? Scrivi a [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Supporto
|
||||
@@ -498,3 +502,5 @@ Tutte le funzionalità pianificate sono su [Projects](https://github.com/orgs/Te
|
||||
## Licenza
|
||||
|
||||
Distribuito con licenza Apache versione 2.0. Vedi `LICENSE` per maggiori informazioni.
|
||||
</content>
|
||||
</invoke>
|
||||
+35
-30
@@ -89,7 +89,7 @@ RDP、VNC、Telnet をブラウザから利用でき、他のセッションと
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**ファイルマネージャー:**
|
||||
SFTP でファイルの閲覧、編集、アップロード、ダウンロード、名前変更、移動、削除ができ、sudo にも対応しています。コード、画像、音声、動画を表示・編集できます。サーバー間で直接ファイルをコピーでき、最速の経路が自動で選ばれ、転送の整合性も検証されます。
|
||||
SFTP でファイルの閲覧、編集、アップロード、ダウンロード、名前変更、移動、削除ができ、sudo にも対応しています。コード、画像、音声、動画を表示・編集できます。専用の転送タブでサーバー間から直接ファイルをコピーでき、最速の経路が自動で選ばれ、転送の整合性も検証されます。デスクトップ版にはローカルとリモートを並べて表示する画面もあります。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -111,7 +111,7 @@ SFTP でファイルの閲覧、編集、アップロード、ダウンロード
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**ホストメトリクス:**
|
||||
たいていの Linux サーバーで CPU、メモリ、ディスク、ネットワーク、温度、稼働時間、プロセス、ポート、ログイン、システム情報を履歴グラフ付きで確認できます。マネージャーカードを使えば、サービス、cron、パッケージ、ユーザー、ファイアウォール、WireGuard、Tailscale、SSL 証明書、ログ、ヘルスチェックを Termix から離れずに扱えます。
|
||||
たいていの Linux サーバーで CPU、メモリ、ディスク、ネットワーク、温度、NVIDIA GPU、稼働時間、プロセス、ポート、ログイン、システム情報を履歴グラフ付きで確認できます。マネージャーカードを使えば、サービス、cron、パッケージ、ユーザー、ファイアウォール、WireGuard、Tailscale、SSL 証明書、ログ、ヘルスチェックを Termix から離れずに扱えます。
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Proxmox のインスタンスからそのままホストを取り込めます。
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**ガイド付きセットアップ:**
|
||||
短いセットアップが、画面のプリセット、テーマ、使いたい機能、最初のホストの選択を案内します。シンプルモードは使わないものを隠してくれます。セットアップはいつでもやり直せますし、プリセットも切り替えられます。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**デスクトップ単体利用と同期:**
|
||||
デスクトップアプリはローカルのバックエンドとデータベースを持ち、サーバーなしで単体で動きます。Termix サーバーにつなげば、ホスト、認証情報、スニペットなどを双方向で同期でき、接続をローカルから始めるかサーバー経由にするかも選べます。
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**コマンドラインツール:**
|
||||
シェルやスクリプトから使える `termix` CLI です。ターミナルを開き、ホスト 1 台またはフリート全体でコマンドを実行し、SFTP でファイルを移動し、ホストやスニペット、認証情報を管理できます。`npm install -g @termix-cli/cli` で入れるか、単体のバイナリを使ってください。詳しくは [CLI ドキュメント](https://docs.termix.site/cli)をご覧ください。
|
||||
シェルやスクリプトから使える `termix` CLI です。ターミナルを開き、ホスト 1 台またはフリート全体でコマンドを実行し、SFTP でファイルを移動し、ホストやスニペット、認証情報を管理できます。`npm install -g @termix-ssh/cli` で入れるか、単体のバイナリを使ってください。詳しくは [CLI ドキュメント](https://docs.termix.site/cli)をご覧ください。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Proxmox のインスタンスからそのままホストを取り込めます。
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**セキュリティ:**
|
||||
パスワードや鍵などの秘密情報はユーザーごとに暗号化され、データベースのファイル自体もディスク上で暗号化できます。仕組みは[ドキュメント](https://docs.termix.site/security)をご覧ください。
|
||||
パスワードや鍵などの秘密情報はユーザーごとに暗号化され、データベースのファイル自体もディスク上で暗号化できます。仕組みは[ドキュメント](https://docs.termix.site/features/authentication/security/)をご覧ください。
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Proxmox のインスタンスからそのままホストを取り込めます。
|
||||
- **キーボードショートカット** - タブの移動や閉じる操作など、すべて割り当て変更可能
|
||||
- **Wake-on-LAN** - Termix からでも自動化のステップからでもマシンを起動
|
||||
- **信頼済みプロキシ認証** - リバースプロキシにサインインを任せ、ユーザー情報を引き継ぎ
|
||||
- **充実した SSH 機能** - 踏み台ホスト、Warpgate、TOTP の入力、SOCKS5、ホスト鍵の検証、パスワードの自動入力、[OPKSSH](https://github.com/openpubkey/opkssh)、tmux、ポートノッキング、ターミナルのログ、エージェント転送、Bitwarden SSH エージェント、HashiCorp Vault の SSH 署名など
|
||||
- **ホワイトラベル** - 管理者が自分の名前、ロゴ、配色でインスタンスをブランド変更できます
|
||||
- **Web エンドポイント** - ルーターの管理画面のようなホスト自身の Web UI を、別タブではなく Termix の中に埋め込んで開けます
|
||||
- **コラボレーションルーム** - グループでセッションを行き来できる常設ルーム。プレゼンターの表示や招待機能もあります
|
||||
- **充実した SSH 機能** - 踏み台ホスト、Warpgate、TOTP の入力、SOCKS5、ホスト鍵の検証、パスワードの自動入力、[OPKSSH](https://github.com/openpubkey/opkssh)、tmux、ポートノッキング、ターミナルのログ、エージェント転送、Bitwarden SSH エージェント、HashiCorp Vault の SSH 署名、Step CA、1Password Connect など
|
||||
- **Termix ID** - sshid.io のような仕組みを内蔵。ハンドルを取得し、公開鍵をリゾルバー URL で公開し、内蔵 CA から SSH 証明書を発行できます
|
||||
- **コマンド履歴の自動候補** - ターミナルに入力すると、コマンド履歴をもとにしたインライン候補が表示されます
|
||||
- **デスクトップ単体利用と同期** - デスクトップアプリはローカルのバックエンドとデータベースを持ち単体でも動き、Termix サーバーと同期することもできます
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,10 @@ Proxmox のインスタンスからそのままホストを取り込めます。
|
||||
|
||||
すべてのプラットフォーム向けの詳しいインストール手順は [Termix ドキュメント](https://docs.termix.site/install)をご覧ください。
|
||||
|
||||
Kubernetes にデプロイしますか?Helm chart は `charts/termix` にあり、
|
||||
Ingress、Traefik、Argo CD、GitHub Actions、GitLab CI を扱うセットアップ手順は
|
||||
[docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes) にあります。
|
||||
|
||||
Docker Compose の例です(リモートデスクトップ機能を使わないなら `guacd` とネットワークの部分は省略できます):
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +350,7 @@ networks:
|
||||
Termix には CLI もあるので、ターミナルからサーバーを管理したり、自分のスクリプトに組み込んだりできます。
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +367,9 @@ Termix のサーバーは自分のネットワーク内ではなく、VPS で動
|
||||
|
||||
## テレメトリー
|
||||
|
||||
Termix は 1 日 1 回、匿名の小さなデータを送ります。どれくらいのインスタンスが動いていて、どの機能が使われているかを把握するためのものです。含まれるのはランダムなインスタンス ID、ユーザーとホストの数、アプリのバージョン、直近 24 時間に使われた機能(ターミナル、ファイルマネージャー、トンネル、Docker など)だけです。ユーザー名、ホスト名、IP アドレス、認証情報など、あなたやサーバーを特定できるものは一切含まれません。
|
||||
Termix は 1 日に 1 回、小さな匿名レポートを送信します。これで、どれだけのインスタンスが動いていて、どの機能が使われているかを把握しています。内容はランダムなインスタンス ID、アプリのバージョン、ユーザー数とホスト数です。さらに、プラットフォーム(OS、アーキテクチャ、Node.js のバージョン、データベースの種類、Docker・デスクトップアプリ・通常のサーバーのどれで動いているか)、各種タブが開かれた回数と SSH ログイン数、動作中の組み込み機能を含めることもできます。ユーザー名、ホスト名、IP アドレス、認証情報など、あなたやサーバーを特定できる情報は一切含みません。
|
||||
|
||||
初期状態では有効です。管理設定の「一般」から止められますし、Termix を起動する前に `ENABLE_TELEMETRY=false` を設定しておくこともできます。
|
||||
初期状態では有効です。管理設定の「Usage Statistics」から止めたり、含める内容を選んだりでき、送信されるレポートをそのまま事前に確認することもできます。各ユーザーはプロフィールで自分の機能利用データを除外できます。`ENABLE_TELEMETRY=false` を設定すると無効になり、スイッチもロックされます。
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +385,52 @@ Termix は無料でオープンソースで、サブスクリプションも有
|
||||
|
||||
有料掲載で開発を支援することにご興味がありますか。[mail@termix.site](mailto:mail@termix.site) までご連絡ください。
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## サポート
|
||||
@@ -498,3 +502,4 @@ Termix は無料でオープンソースで、サブスクリプションも有
|
||||
## ライセンス
|
||||
|
||||
Apache License 2.0 のもとで配布しています。詳しくは `LICENSE` をご覧ください。
|
||||
</content>
|
||||
+31
-29
@@ -111,7 +111,7 @@ SFTP로 파일을 살펴보고 편집하고 올리고 내려받고 이름을 바
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**호스트 지표:**
|
||||
대부분의 리눅스 서버에서 CPU, 메모리, 디스크, 네트워크, 온도, 가동 시간, 프로세스, 포트, 로그인, 시스템 정보를 기록 그래프와 함께 볼 수 있습니다. 관리 카드로 서비스와 cron 작업, 패키지, 사용자, 방화벽 규칙, WireGuard, Tailscale, SSL 인증서, 로그, 상태 확인을 Termix 안에서 처리할 수 있습니다.
|
||||
대부분의 리눅스 서버에서 CPU, 메모리, 디스크, 네트워크, 온도, NVIDIA GPU, 가동 시간, 프로세스, 포트, 로그인, 시스템 정보를 기록 그래프와 함께 볼 수 있습니다. 관리 카드로 서비스와 cron 작업, 패키지, 사용자, 방화벽 규칙, WireGuard, Tailscale, SSL 인증서, 로그, 상태 확인을 Termix 안에서 처리할 수 있습니다.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -214,22 +214,8 @@ Proxmox 인스턴스에서 호스트를 바로 가져오고, 노드와 게스트
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**설치 안내:**
|
||||
짧은 설정 과정이 화면 프리셋과 테마, 쓰고 싶은 기능, 첫 호스트를 고르도록 안내합니다. 간단 모드는 쓰지 않는 것을 숨겨 주고, 설정은 언제든 다시 하거나 프리셋을 바꿀 수 있습니다.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**데스크톱 단독 실행과 동기화:**
|
||||
데스크톱 앱은 자체 백엔드와 데이터베이스로 서버 없이 혼자 돌아갑니다. Termix 서버에 연결하면 호스트와 자격 증명, 스니펫 등을 양방향으로 동기화할 수 있고, 연결을 로컬에서 시작할지 서버를 거칠지도 고를 수 있습니다.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**명령줄 도구:**
|
||||
셸과 스크립트에서 쓰는 `termix` CLI입니다. 터미널을 열고, 호스트 하나나 플릿 전체에서 명령을 실행하고, SFTP로 파일을 옮기고, 호스트와 스니펫, 자격 증명을 관리할 수 있습니다. `npm install -g @termix-cli/cli`로 설치하거나 단독 실행 파일을 받으면 됩니다. [CLI 문서](https://docs.termix.site/cli)를 참고하세요.
|
||||
셸과 스크립트에서 쓰는 `termix` CLI입니다. 터미널을 열고, 호스트 하나나 플릿 전체에서 명령을 실행하고, SFTP로 파일을 옮기고, 호스트와 스니펫, 자격 증명을 관리할 수 있습니다. `npm install -g @termix-ssh/cli`로 설치하거나 단독 실행 파일을 받으면 됩니다. [CLI 문서](https://docs.termix.site/cli)를 참고하세요.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Proxmox 인스턴스에서 호스트를 바로 가져오고, 노드와 게스트
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**보안:**
|
||||
비밀번호와 키를 비롯한 비밀 정보는 사용자별로 암호화되고, 데이터베이스 파일 자체도 디스크에서 암호화할 수 있습니다. 어떻게 동작하는지는 [문서](https://docs.termix.site/security)에서 볼 수 있습니다.
|
||||
비밀번호와 키를 비롯한 비밀 정보는 사용자별로 암호화되고, 데이터베이스 파일 자체도 디스크에서 암호화할 수 있습니다. 어떻게 동작하는지는 [문서](https://docs.termix.site/features/authentication/security/)에서 볼 수 있습니다.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Proxmox 인스턴스에서 호스트를 바로 가져오고, 노드와 게스트
|
||||
- **키보드 단축키** - 탭 이동과 닫기 등, 모두 다시 지정할 수 있습니다
|
||||
- **Wake-on-LAN** - Termix에서도, 자동화 단계에서도 컴퓨터를 켜기
|
||||
- **신뢰할 수 있는 프록시 인증** - 리버스 프록시가 로그인을 처리하고 사용자 정보를 넘겨주기
|
||||
- **풍부한 SSH 기능** - 점프 호스트, Warpgate, TOTP 입력, SOCKS5, 호스트 키 확인, 비밀번호 자동 입력, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, 포트 노킹, 터미널 로그, 에이전트 포워딩, Bitwarden SSH 에이전트, HashiCorp Vault SSH 서명 등
|
||||
- **화이트 라벨** - 관리자가 인스턴스를 자기 이름과 로고, 색으로 다시 꾸밀 수 있습니다
|
||||
- **웹 엔드포인트** - 라우터 관리 페이지 같은 호스트의 웹 UI를 별도 탭이 아니라 Termix 안에 그대로 띄우기
|
||||
- **협업 룸** - 발표자 화면과 초대 기능을 갖춘, 여러 명이 함께 세션을 오가는 상시 룸
|
||||
- **풍부한 SSH 기능** - 점프 호스트, Warpgate, TOTP 입력, SOCKS5, 호스트 키 확인, 비밀번호 자동 입력, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, 포트 노킹, 터미널 로그, 에이전트 포워딩, Bitwarden SSH 에이전트, HashiCorp Vault SSH 서명, Step CA, 1Password Connect 등
|
||||
- **Termix ID** - sshid.io 같은 기능을 내장했습니다. 핸들을 등록하고 리졸버 URL에 공개 키를 올리고 내장 CA에서 SSH 인증서를 발급할 수 있습니다
|
||||
- **명령 기록 자동 완성** - 입력하는 동안 명령 기록을 바탕으로 터미널에 인라인 제안을 보여줍니다
|
||||
- **데스크톱 단독 실행과 동기화** - 데스크톱 앱은 자체 백엔드와 데이터베이스로 서버 없이 혼자 돌아가며, Termix 서버와 선택적으로 동기화할 수 있습니다
|
||||
|
||||
</details>
|
||||
|
||||
@@ -313,6 +304,8 @@ Proxmox 인스턴스에서 호스트를 바로 가져오고, 노드와 게스트
|
||||
|
||||
모든 플랫폼의 자세한 설치 방법은 [Termix 문서](https://docs.termix.site/install)를 참고하세요.
|
||||
|
||||
쿠버네티스에 배포하시나요? Helm 차트는 `charts/termix`에 있고, Ingress와 Traefik, Argo CD, GitHub Actions, GitLab CI를 다루는 설정 안내는 [docs.termix.site/install/server/kubernetes](https://docs.termix.site/install/server/kubernetes)에 있습니다.
|
||||
|
||||
Docker Compose 예시입니다(원격 데스크톱 기능을 쓰지 않는다면 `guacd`와 네트워크 부분은 빼도 됩니다):
|
||||
|
||||
```yaml
|
||||
@@ -355,7 +348,7 @@ networks:
|
||||
Termix에는 CLI도 있어서 터미널에서 서버를 관리하거나 Termix를 자기 스크립트에 넣어 쓸 수 있습니다.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +365,9 @@ Termix 서버는 집 안 네트워크가 아니라 VPS에서 돌릴 수도 있
|
||||
|
||||
## 텔레메트리
|
||||
|
||||
Termix는 하루에 한 번 익명의 작은 데이터를 보냅니다. 인스턴스가 얼마나 돌아가는지, 어떤 기능이 쓰이는지 파악하기 위한 것입니다. 여기에는 무작위 인스턴스 ID, 사용자와 호스트 수, 앱 버전, 최근 24시간 동안 쓴 기능(터미널, 파일 관리자, 터널, Docker 등)만 들어갑니다. 사용자 이름과 호스트 이름, IP 주소, 자격 증명처럼 나나 내 서버를 알아볼 수 있는 것은 전혀 담기지 않습니다.
|
||||
Termix는 하루에 한 번 작은 익명 보고서를 보내서 몇 개의 인스턴스가 실행 중이고 어떤 기능이 쓰이는지 알 수 있게 합니다. 보고서에는 무작위 인스턴스 ID, 앱 버전, 사용자 수와 호스트 수가 들어 있습니다. 또한 플랫폼 정보(OS, 아키텍처, Node.js 버전, 데이터베이스 종류, Docker·데스크톱 앱·일반 서버 중 무엇으로 실행하는지), 탭 종류별로 열린 횟수와 SSH 로그인 수, 실행 중인 내장 기능도 포함될 수 있습니다. 사용자 이름, 호스트 이름, IP 주소, 자격 증명 등 당신이나 서버를 식별할 수 있는 정보는 절대 포함되지 않습니다.
|
||||
|
||||
기본으로 켜져 있습니다. 관리 설정의 일반에서 끄거나, Termix를 시작하기 전에 `ENABLE_TELEMETRY=false`를 지정하면 됩니다.
|
||||
기본으로 켜져 있습니다. 관리 설정의 Usage Statistics에서 끄거나 포함할 내용을 고를 수 있고, 보낼 보고서를 미리 그대로 볼 수도 있습니다. 각 사용자는 자신의 프로필에서 본인의 기능 사용 기록을 뺄 수 있습니다. `ENABLE_TELEMETRY=false`를 지정하면 꺼지고 스위치가 잠깁니다.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +383,52 @@ Termix는 무료 오픈 소스이고 구독이나 유료 요금제가 없습니
|
||||
|
||||
유료 게재로 개발을 지원하고 싶으신가요? [mail@termix.site](mailto:mail@termix.site)로 메일을 보내 주세요.
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## 지원
|
||||
|
||||
+28
-28
@@ -214,22 +214,8 @@ Salva um conjunto de abas com a divisão da tela e reabre tudo com um clique. O
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Configuração guiada:**
|
||||
Uma configuração curta te leva por escolher uma predefinição de interface, o tema, as funcionalidades que queres e o teu primeiro host. O modo simples esconde o que não usas, e dá para refazer a configuração ou trocar de predefinição quando quiseres.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Desktop independente e sincronização:**
|
||||
O aplicativo de desktop roda sozinho, com backend e banco de dados locais, sem servidor. Também dá para ligar num servidor Termix e sincronizar nos dois sentidos hosts, credenciais, trechos e mais, e escolher se as conexões saem da tua máquina ou passam pelo servidor.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Linha de comando:**
|
||||
Um CLI `termix` para o teu shell e os teus scripts. Abre terminais, roda um comando num host ou numa frota inteira, move arquivos por SFTP e gerencia hosts, trechos e credenciais. Instala com `npm install -g @termix-cli/cli` ou pega um binário independente. Vê a [documentação do CLI](https://docs.termix.site/cli).
|
||||
Um CLI `termix` para o teu shell e os teus scripts. Abre terminais, roda um comando num host ou numa frota inteira, move arquivos por SFTP e gerencia hosts, trechos e credenciais. Instala com `npm install -g @termix-ssh/cli` ou pega um binário independente. Vê a [documentação do CLI](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Um CLI `termix` para o teu shell e os teus scripts. Abre terminais, roda um coma
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Segurança:**
|
||||
Senhas, chaves e outros segredos são criptografados por usuário, e os próprios arquivos do banco de dados podem ser criptografados em disco. Vê a [documentação](https://docs.termix.site/security) para entender como funciona.
|
||||
Senhas, chaves e outros segredos são criptografados por usuário, e os próprios arquivos do banco de dados podem ser criptografados em disco. Vê a [documentação](https://docs.termix.site/features/authentication/security/) para entender como funciona.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Cerca de 30 idiomas incluídos, gerenciados pelo [Crowdin](https://docs.termix.s
|
||||
- **Atalhos de teclado** - Trocar de aba, fechar abas e mais, tudo remapeável
|
||||
- **Wake-on-LAN** - Liga uma máquina pelo Termix ou por um passo de automação
|
||||
- **Autenticação por proxy confiável** - Deixa um proxy reverso cuidar do login e repassar o usuário
|
||||
- **SSH bem completo** - Hosts de salto, Warpgate, pedidos de TOTP, SOCKS5, verificação de chave de host, preenchimento automático de senha, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, registro do terminal, encaminhamento de agente, agente SSH do Bitwarden, assinatura SSH com HashiCorp Vault e mais
|
||||
- **Marca própria** - Os administradores podem rebatizar a instância com nome, logo e cores próprios
|
||||
- **Endpoints web** - Abre a interface web do próprio host, como a página de administração de um roteador, embutida no Termix em vez de numa aba separada
|
||||
- **Salas de colaboração** - Salas persistentes onde um grupo pode passar de uma sessão para outra junto, com um palco de apresentação e convites
|
||||
- **SSH bem completo** - Hosts de salto, Warpgate, pedidos de TOTP, SOCKS5, verificação de chave de host, preenchimento automático de senha, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, registro do terminal, encaminhamento de agente, agente SSH do Bitwarden, assinatura SSH com HashiCorp Vault, Step CA, 1Password Connect e mais
|
||||
- **Termix ID** - Uma versão embutida do sshid.io. Registra um identificador, publica as tuas chaves públicas numa URL de resolução e emite certificados SSH pela CA embutida
|
||||
- **Sugestões automáticas de histórico de comandos** - Sugestões dentro do terminal enquanto tu digitas, baseadas no teu histórico de comandos
|
||||
- **Desktop independente e sincronização** - O aplicativo de desktop roda sozinho, com backend e banco de dados locais, e pode opcionalmente sincronizar com um servidor Termix
|
||||
|
||||
</details>
|
||||
|
||||
@@ -355,7 +346,7 @@ networks:
|
||||
O Termix também tem um CLI, para gerenciares os teus servidores pelo terminal e usares o Termix nos teus próprios scripts.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +363,9 @@ A [GINERNET](https://docs.termix.site/install/ginernet) patrocina o Termix, e a
|
||||
|
||||
## Telemetria
|
||||
|
||||
O Termix manda uma vez por dia um pequeno sinal anônimo, para eu saber quantas instâncias estão rodando e quais funcionalidades são usadas. Ele contém um ID de instância aleatório, quantos usuários e hosts tu tens, a versão do aplicativo e quais funcionalidades (terminal, gerenciador de arquivos, túneis, docker, etc.) foram usadas nas últimas 24 horas. Nunca contém nomes de usuário, nomes de host, endereços IP, credenciais ou qualquer coisa que identifique ti ou os teus servidores.
|
||||
O Termix envia uma vez por dia um pequeno relatório anónimo, para eu ver quantas instâncias estão a correr e que funcionalidades são usadas. Contém um ID de instância aleatório, a versão da app e quantos utilizadores e hosts tens. Também pode incluir a tua plataforma (sistema operativo, arquitetura, versão do Node.js, tipo de base de dados e se usas Docker, a app de desktop ou um servidor normal), quantas vezes cada tipo de separador foi aberto e quantos logins SSH houve, e que funcionalidades integradas estão ativas. Nunca contém nomes de utilizador, nomes de host, endereços IP, credenciais ou qualquer outra coisa que te identifique a ti ou aos teus servidores.
|
||||
|
||||
Vem ligado por padrão. Podes desligar nas configurações de administração, em Geral, ou definir `ENABLE_TELEMETRY=false` antes mesmo de iniciar o Termix.
|
||||
Vem ligado por padrão. Podes desligar ou escolher o que inclui nas configurações de administração, em Usage Statistics, onde também podes ver o relatório exato antes de ser enviado. Cada utilizador pode excluir o seu próprio uso de funcionalidades no perfil. Definir `ENABLE_TELEMETRY=false` desliga-o e bloqueia o interruptor.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +381,52 @@ O Termix é gratuito e de código aberto, sem assinaturas nem planos pagos. Se e
|
||||
|
||||
Tens interesse num espaço pago para apoiar o desenvolvimento? Escreve para [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Suporte
|
||||
|
||||
+28
-28
@@ -214,22 +214,8 @@ RDP, VNC и Telnet прямо в браузере, во вкладках и с
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Пошаговая настройка:**
|
||||
Короткая настройка поможет выбрать шаблон интерфейса, тему, нужные возможности и первый хост. Простой режим скрывает то, чем вы не пользуетесь, а настройку можно пройти заново или сменить шаблон в любой момент.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Автономный клиент и синхронизация:**
|
||||
Настольное приложение работает само по себе, со своим бэкендом и базой данных, без сервера. Его можно подключить к серверу Termix, чтобы в обе стороны синхронизировать хосты, учётные данные, сниппеты и остальное, и выбрать, откуда идут подключения: с вашего компьютера или через сервер.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Командная строка:**
|
||||
CLI `termix` для вашей оболочки и ваших скриптов. Открывайте терминалы, выполняйте команду на одном хосте или на целом флоте, перемещайте файлы по SFTP и управляйте хостами, сниппетами и учётными данными. Установите через `npm install -g @termix-cli/cli` или возьмите отдельный исполняемый файл. Смотрите [документацию CLI](https://docs.termix.site/cli).
|
||||
CLI `termix` для вашей оболочки и ваших скриптов. Открывайте терминалы, выполняйте команду на одном хосте или на целом флоте, перемещайте файлы по SFTP и управляйте хостами, сниппетами и учётными данными. Установите через `npm install -g @termix-ssh/cli` или возьмите отдельный исполняемый файл. Смотрите [документацию CLI](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ CLI `termix` для вашей оболочки и ваших скриптов.
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Безопасность:**
|
||||
Пароли, ключи и другие секреты шифруются для каждого пользователя, а сами файлы базы данных можно зашифровать на диске. Как это устроено, описано в [документации](https://docs.termix.site/security).
|
||||
Пароли, ключи и другие секреты шифруются для каждого пользователя, а сами файлы базы данных можно зашифровать на диске. Как это устроено, описано в [документации](https://docs.termix.site/features/authentication/security/).
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ CLI `termix` для вашей оболочки и ваших скриптов.
|
||||
- **Сочетания клавиш** - Переход между вкладками, их закрытие и другое, всё можно переназначить
|
||||
- **Wake-on-LAN** - Разбудите машину из Termix или из шага автоматизации
|
||||
- **Доверенный прокси** - Пусть обратный прокси возьмёт вход на себя и передаст пользователя
|
||||
- **Богатые возможности SSH** - Промежуточные хосты, Warpgate, запросы TOTP, SOCKS5, проверка ключей хоста, автозаполнение паролей, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, журналы терминала, проброс агента, SSH-агент Bitwarden, подпись SSH через HashiCorp Vault и другое
|
||||
- **Собственный бренд** - Администраторы могут переоформить установку под своё имя, логотип и цвета
|
||||
- **Веб-эндпоинты** - Открывайте собственный веб-интерфейс хоста, например админку роутера, прямо внутри Termix вместо отдельной вкладки
|
||||
- **Комнаты для совместной работы** - Постоянные комнаты, где группа может вместе переключаться между сессиями, с режимом докладчика и приглашениями
|
||||
- **Богатые возможности SSH** - Промежуточные хосты, Warpgate, запросы TOTP, SOCKS5, проверка ключей хоста, автозаполнение паролей, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, журналы терминала, проброс агента, SSH-агент Bitwarden, подпись SSH через HashiCorp Vault, Step CA, 1Password Connect и другое
|
||||
- **Termix ID** - Встроенный аналог sshid.io. Займите имя, опубликуйте открытые ключи по адресу распознавателя и выпускайте SSH-сертификаты через встроенный центр сертификации
|
||||
- **Автоподсказки истории команд** - Подсказки прямо в терминале по мере ввода, на основе истории ваших команд
|
||||
- **Автономный клиент и синхронизация** - Настольное приложение работает само по себе, со своим бэкендом и локальной базой данных, и может по желанию синхронизироваться с сервером Termix
|
||||
|
||||
</details>
|
||||
|
||||
@@ -355,7 +346,7 @@ networks:
|
||||
У Termix есть и CLI, так что серверами можно управлять из терминала и использовать Termix в своих скриптах.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +363,9 @@ termix ssh 1
|
||||
|
||||
## Телеметрия
|
||||
|
||||
Termix раз в сутки отправляет небольшой анонимный сигнал, чтобы я понимал, сколько установок работает и какими возможностями действительно пользуются. В нём есть случайный идентификатор установки, число пользователей и хостов, версия приложения и то, какие возможности (терминал, файловый менеджер, туннели, docker и прочее) использовались за последние 24 часа. В нём никогда нет имён пользователей, имён хостов, IP-адресов, учётных данных и ничего другого, что указывало бы на вас или ваши серверы.
|
||||
Раз в день Termix отправляет небольшой анонимный отчёт, чтобы я видел, сколько установок работает и какими функциями пользуются. В нём есть случайный ID установки, версия приложения и количество пользователей и хостов. Он также может включать вашу платформу (ОС, архитектуру, версию Node.js, тип базы данных и то, как запущен Termix: в Docker, как настольное приложение или как обычный сервер), сколько раз открывались вкладки каждого типа и сколько было входов по SSH, а также какие встроенные функции работают. В нём никогда нет имён пользователей, имён хостов, IP-адресов, учётных данных или чего-либо ещё, что может указать на вас или ваши серверы.
|
||||
|
||||
По умолчанию он включён. Выключить можно в настройках администратора в разделе «Общие» или задать `ENABLE_TELEMETRY=false` ещё до первого запуска Termix.
|
||||
По умолчанию он включён. Выключить его или выбрать, что в него входит, можно в настройках администратора в разделе Usage Statistics, там же можно заранее посмотреть точный отчёт. Каждый пользователь может исключить своё использование функций в своём профиле. `ENABLE_TELEMETRY=false` выключает его и блокирует переключатель.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +381,52 @@ Termix бесплатен и открыт, без подписок и платн
|
||||
|
||||
Интересует платное размещение в поддержку разработки? Напишите на [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Поддержка
|
||||
|
||||
+29
-29
@@ -214,22 +214,8 @@ Bir sekme grubunu bölünmüş düzeniyle birlikte kaydedin ve hepsini tek tıkl
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Rehberli kurulum:**
|
||||
Kısa bir kurulum, arayüz ön ayarını, temanızı, istediğiniz özellikleri ve ilk sunucunuzu seçmenizde size yol gösterir. Basit kip kullanmadığınız şeyleri gizler; kurulumu istediğiniz zaman yeniden çalıştırabilir veya ön ayarı değiştirebilirsiniz.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Bağımsız masaüstü ve eşitleme:**
|
||||
Masaüstü uygulaması kendi arka ucu ve veritabanıyla tek başına, sunucusuz çalışır. İsterseniz bir Termix sunucusuna bağlayıp sunucuları, kimlik bilgilerini, parçacıkları ve fazlasını iki yönlü eşitleyebilir, bağlantıların kendi makinenizden mi yoksa sunucu üzerinden mi kurulacağını seçebilirsiniz.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Komut satırı:**
|
||||
Kabuğunuz ve betikleriniz için bir `termix` CLI'ı. Terminal açın, tek bir sunucuda veya tüm filoda komut çalıştırın, SFTP ile dosya taşıyın ve sunucuları, parçacıkları ve kimlik bilgilerini yönetin. `npm install -g @termix-cli/cli` ile kurun ya da bağımsız bir çalıştırılabilir dosya edinin. [CLI belgelerine](https://docs.termix.site/cli) bakın.
|
||||
**Komut satırı arayüzü:**
|
||||
Kabuğunuz ve betikleriniz için bir `termix` CLI'ı. Terminal açın, tek bir sunucuda veya tüm filoda komut çalıştırın, SFTP ile dosya taşıyın ve sunucuları, parçacıkları ve kimlik bilgilerini yönetin. `npm install -g @termix-ssh/cli` ile kurun ya da bağımsız bir çalıştırılabilir dosya edinin. [CLI belgelerine](https://docs.termix.site/cli) bakın.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Kabuğunuz ve betikleriniz için bir `termix` CLI'ı. Terminal açın, tek bir s
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Güvenlik:**
|
||||
Parolalar, anahtarlar ve diğer gizli bilgiler kullanıcı bazında şifrelenir, veritabanı dosyalarının kendisi de diskte şifrelenebilir. Nasıl çalıştığı için [belgelere](https://docs.termix.site/security) bakın.
|
||||
Parolalar, anahtarlar ve diğer gizli bilgiler kullanıcı bazında şifrelenir, veritabanı dosyalarının kendisi de diskte şifrelenebilir. Nasıl çalıştığı için [belgelere](https://docs.termix.site/features/authentication/security/) bakın.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Yaklaşık 30 dil yerleşik olarak gelir, [Crowdin](https://docs.termix.site/tra
|
||||
- **Klavye kısayolları** - Sekmeler arasında geçiş, sekme kapatma ve dahası, hepsi yeniden atanabilir
|
||||
- **Wake-on-LAN** - Bir makineyi Termix'ten ya da bir otomasyon adımından uyandırın
|
||||
- **Güvenilir vekil doğrulaması** - Girişi ters vekil sunucu halletsin ve kullanıcıyı aktarsın
|
||||
- **Zengin SSH desteği** - Atlama sunucuları, Warpgate, TOTP istekleri, SOCKS5, sunucu anahtarı doğrulama, parola otomatik doldurma, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, terminal günlüğü, aracı yönlendirme, Bitwarden SSH aracısı, HashiCorp Vault ile SSH imzalama ve dahası
|
||||
- **Beyaz etiket** - Yöneticiler kurulumu kendi adı, logosu ve renkleriyle yeniden markalayabilir
|
||||
- **Web uç noktaları** - Bir sunucunun kendi web arayüzünü, örneğin bir yönlendirici yönetim sayfasını, ayrı bir sekme yerine Termix içine gömülü açın
|
||||
- **İşbirliği odaları** - Bir grubun oturumlar arasında birlikte geçiş yapabildiği kalıcı odalar; sunum kürsüsü ve davetlerle
|
||||
- **Zengin SSH desteği** - Atlama sunucuları, Warpgate, TOTP istekleri, SOCKS5, sunucu anahtarı doğrulama, parola otomatik doldurma, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, terminal günlüğü, aracı yönlendirme, Bitwarden SSH aracısı, HashiCorp Vault ile SSH imzalama, Step CA, 1Password Connect ve dahası
|
||||
- **Termix ID** - sshid.io'nun yerleşik hali. Bir kullanıcı adı alın, açık anahtarlarınızı bir çözümleyici adresinde yayımlayın ve yerleşik CA ile SSH sertifikaları çıkarın
|
||||
- **Komut geçmişi önerileri** - Yazarken komut geçmişinize dayalı satır içi öneriler
|
||||
- **Bağımsız masaüstü ve eşitleme** - Masaüstü uygulaması kendi arka ucu ve veritabanıyla tek başına çalışır, isteğe bağlı olarak bir Termix sunucusuyla eşitlenebilir
|
||||
|
||||
</details>
|
||||
|
||||
@@ -355,7 +346,7 @@ networks:
|
||||
Termix'in bir CLI'ı da var; sunucularınızı terminalden yönetebilir ve Termix'i kendi betiklerinizde kullanabilirsiniz.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +363,9 @@ Termix sunucusunu kendi ağınız yerine bir VPS üzerinde de çalıştırabilir
|
||||
|
||||
## Telemetri
|
||||
|
||||
Termix günde bir kez küçük ve anonim bir sinyal gönderir; böylece kaç kurulumun çalıştığını ve hangi özelliklerin kullanıldığını görebiliyorum. İçinde rastgele bir kurulum kimliği, kaç kullanıcı ve sunucunuz olduğu, uygulama sürümü ve son 24 saatte hangi özelliklerin (terminal, dosya yöneticisi, tüneller, docker vb.) kullanıldığı yer alır. İçinde asla kullanıcı adları, sunucu adları, IP adresleri, kimlik bilgileri ya da sizi veya sunucularınızı tanımlayan başka bir şey bulunmaz.
|
||||
Termix, kaç kurulumun çalıştığını ve hangi özelliklerin kullanıldığını görebilmem için günde bir kez küçük ve anonim bir rapor gönderir. Raporda rastgele bir kurulum kimliği, uygulama sürümü ve kaç kullanıcı ile sunucunuz olduğu bulunur. Ayrıca platformunuzu (işletim sistemi, mimari, Node.js sürümü, veritabanı türü ve Docker, masaüstü uygulaması ya da normal bir sunucu kullanıp kullanmadığınız), her sekme türünün kaç kez açıldığını ve kaç SSH girişi yapıldığını, hangi yerleşik özelliklerin çalıştığını da içerebilir. Kullanıcı adları, sunucu adları, IP adresleri, kimlik bilgileri ya da sizi veya sunucularınızı tanıtacak hiçbir şey asla gönderilmez.
|
||||
|
||||
Varsayılan olarak açıktır. Yönetici ayarlarında Genel bölümünden kapatabilir ya da Termix'i hiç başlatmadan önce `ENABLE_TELEMETRY=false` tanımlayabilirsiniz.
|
||||
Varsayılan olarak açıktır. Yönetici ayarlarında Usage Statistics bölümünden kapatabilir veya neleri içereceğini seçebilir, gönderilecek raporu olduğu gibi önizleyebilirsiniz. Her kullanıcı kendi özellik kullanımını profilinden hariç tutabilir. `ENABLE_TELEMETRY=false` tanımlamak onu kapatır ve anahtarı kilitler.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +381,52 @@ Termix ücretsiz ve açık kaynaklıdır; abonelik ya da ücretli plan yoktur.
|
||||
|
||||
Geliştirmeyi desteklemek için ücretli bir yerleşim ilginizi çeker mi? [mail@termix.site](mailto:mail@termix.site) adresine yazın.
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Destek
|
||||
|
||||
+28
-28
@@ -214,22 +214,8 @@ Lưu một bộ thẻ cùng cách chia màn hình rồi mở lại toàn bộ ch
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Cài đặt có hướng dẫn:**
|
||||
Một phần cài đặt ngắn sẽ hướng bạn chọn kiểu giao diện, chủ đề, những tính năng bạn muốn và máy chủ đầu tiên. Chế độ đơn giản ẩn bớt những gì bạn không dùng, và bạn có thể chạy lại phần cài đặt hoặc đổi kiểu bất cứ lúc nào.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Ứng dụng máy tính độc lập và đồng bộ:**
|
||||
Ứng dụng máy tính chạy độc lập với backend và cơ sở dữ liệu riêng, không cần máy chủ. Bạn cũng có thể nối nó với một máy chủ Termix để đồng bộ hai chiều máy chủ, thông tin đăng nhập, đoạn lệnh và nhiều thứ khác, và chọn kết nối xuất phát từ máy của bạn hay đi qua máy chủ.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Dòng lệnh:**
|
||||
Công cụ `termix` cho shell và các script của bạn. Mở terminal, chạy một lệnh trên một máy chủ hoặc cả một nhóm, chuyển tệp qua SFTP, và quản lý máy chủ, đoạn lệnh và thông tin đăng nhập. Cài bằng `npm install -g @termix-cli/cli` hoặc tải bản chạy độc lập. Xem [tài liệu CLI](https://docs.termix.site/cli).
|
||||
Công cụ `termix` cho shell và các script của bạn. Mở terminal, chạy một lệnh trên một máy chủ hoặc cả một nhóm, chuyển tệp qua SFTP, và quản lý máy chủ, đoạn lệnh và thông tin đăng nhập. Cài bằng `npm install -g @termix-ssh/cli` hoặc tải bản chạy độc lập. Xem [tài liệu CLI](https://docs.termix.site/cli).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -237,7 +223,7 @@ Công cụ `termix` cho shell và các script của bạn. Mở terminal, chạy
|
||||
<td width="50%" valign="top">
|
||||
|
||||
**Bảo mật:**
|
||||
Mật khẩu, khoá và các thông tin bí mật khác được mã hoá theo từng người dùng, và bản thân các tệp cơ sở dữ liệu cũng có thể mã hoá trên ổ đĩa. Xem [tài liệu](https://docs.termix.site/security) để biết cách hoạt động.
|
||||
Mật khẩu, khoá và các thông tin bí mật khác được mã hoá theo từng người dùng, và bản thân các tệp cơ sở dữ liệu cũng có thể mã hoá trên ổ đĩa. Xem [tài liệu](https://docs.termix.site/features/authentication/security/) để biết cách hoạt động.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
@@ -267,8 +253,13 @@ Có sẵn khoảng 30 ngôn ngữ, quản lý qua [Crowdin](https://docs.termix.
|
||||
- **Phím tắt** - Chuyển giữa các thẻ, đóng thẻ và nhiều thao tác khác, đều gán lại được
|
||||
- **Wake-on-LAN** - Đánh thức một máy từ Termix hoặc từ một bước tự động hoá
|
||||
- **Xác thực qua proxy tin cậy** - Để reverse proxy lo phần đăng nhập rồi chuyển thông tin người dùng vào
|
||||
- **SSH nhiều tính năng** - Máy chủ trung gian, Warpgate, hỏi mã TOTP, SOCKS5, kiểm tra khoá máy chủ, tự điền mật khẩu, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, ghi nhật ký terminal, chuyển tiếp agent, SSH agent của Bitwarden, ký SSH bằng HashiCorp Vault và nhiều thứ khác
|
||||
- **Nhãn trắng** - Quản trị viên có thể đổi thương hiệu hệ thống với tên, logo và màu sắc riêng
|
||||
- **Điểm cuối web** - Mở giao diện web riêng của một máy chủ, chẳng hạn trang quản trị router, ngay trong Termix thay vì mở một thẻ riêng
|
||||
- **Phòng cộng tác** - Phòng lâu dài để cả nhóm cùng chuyển qua lại giữa các phiên, có sân khấu người trình bày và lời mời
|
||||
- **SSH nhiều tính năng** - Máy chủ trung gian, Warpgate, hỏi mã TOTP, SOCKS5, kiểm tra khoá máy chủ, tự điền mật khẩu, [OPKSSH](https://github.com/openpubkey/opkssh), tmux, port knocking, ghi nhật ký terminal, chuyển tiếp agent, SSH agent của Bitwarden, ký SSH bằng HashiCorp Vault, Step CA, 1Password Connect và nhiều thứ khác
|
||||
- **Termix ID** - Bản dựng sẵn theo kiểu sshid.io. Đăng ký một tên, công bố khoá công khai của bạn tại một địa chỉ phân giải, và cấp chứng chỉ SSH từ CA tích hợp
|
||||
- **Gợi ý lịch sử lệnh** - Gợi ý ngay trong terminal khi bạn gõ, dựa trên lịch sử lệnh của bạn
|
||||
- **Ứng dụng máy tính độc lập và đồng bộ** - Ứng dụng máy tính chạy độc lập với backend và cơ sở dữ liệu riêng, có thể đồng bộ tuỳ chọn với một máy chủ Termix
|
||||
|
||||
</details>
|
||||
|
||||
@@ -355,7 +346,7 @@ networks:
|
||||
Termix cũng có CLI, để bạn quản lý máy chủ từ terminal và dùng Termix trong script của mình.
|
||||
|
||||
```bash
|
||||
npm install -g @termix-cli/cli
|
||||
npm install -g @termix-ssh/cli
|
||||
termix login --url https://termix.example.com
|
||||
termix ssh 1
|
||||
```
|
||||
@@ -372,9 +363,9 @@ Bạn có thể chạy máy chủ Termix trên VPS thay vì trong mạng của m
|
||||
|
||||
## Dữ liệu sử dụng
|
||||
|
||||
Termix gửi một tín hiệu nhỏ ẩn danh mỗi ngày một lần, để tôi biết có bao nhiêu bản đang chạy và tính năng nào thực sự được dùng. Nó gồm một mã bản cài ngẫu nhiên, số người dùng và máy chủ bạn có, phiên bản ứng dụng, và những tính năng (terminal, trình quản lý tệp, tunnel, docker, v.v.) đã dùng trong 24 giờ qua. Nó không bao giờ chứa tên người dùng, tên máy chủ, địa chỉ IP, thông tin đăng nhập hay bất cứ thứ gì nhận dạng bạn hoặc máy chủ của bạn.
|
||||
Mỗi ngày một lần, Termix gửi một báo cáo ẩn danh nhỏ để tôi biết có bao nhiêu bản cài đặt đang chạy và tính năng nào được dùng. Báo cáo gồm một ID ngẫu nhiên của bản cài đặt, phiên bản ứng dụng, và số người dùng cùng số máy chủ của bạn. Nó cũng có thể gồm nền tảng của bạn (hệ điều hành, kiến trúc, phiên bản Node.js, loại cơ sở dữ liệu, và bạn chạy bằng Docker, ứng dụng máy tính hay máy chủ thường), số lần mỗi loại tab được mở và số lần đăng nhập SSH, cùng các tính năng tích hợp đang chạy. Nó không bao giờ chứa tên người dùng, tên máy chủ, địa chỉ IP, thông tin đăng nhập hay bất cứ thứ gì có thể nhận ra bạn hoặc máy chủ của bạn.
|
||||
|
||||
Mặc định là bật. Bạn tắt nó trong phần Cài đặt quản trị, mục Chung, hoặc đặt `ENABLE_TELEMETRY=false` trước cả khi khởi động Termix.
|
||||
Mặc định là bật. Bạn có thể tắt hoặc chọn nội dung gửi đi trong phần Cài đặt quản trị, mục Usage Statistics, và xem trước chính xác báo cáo sẽ được gửi. Mỗi người dùng có thể loại phần sử dụng tính năng của riêng mình trong hồ sơ. Đặt `ENABLE_TELEMETRY=false` sẽ tắt nó và khóa công tắc.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -390,43 +381,52 @@ Termix miễn phí và mã nguồn mở, không có gói thuê bao hay bản tr
|
||||
|
||||
Bạn muốn đặt quảng cáo trả phí để ủng hộ việc phát triển? Gửi thư tới [mail@termix.site](mailto:mail@termix.site).
|
||||
|
||||
<!-- SPONSORS:START -->
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="40" alt="DigitalOcean" />
|
||||
<img src="https://termix.site/img/sponsors/digitalocean.svg" height="40" alt="DigitalOcean" />
|
||||
</a>
|
||||
|
||||
<a href="https://crowdin.com/">
|
||||
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="40" alt="Crowdin" />
|
||||
<img src="https://termix.site/img/sponsors/crowdin.svg" height="40" alt="Crowdin" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.blacksmith.sh/">
|
||||
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="40" alt="Blacksmith" />
|
||||
<img src="https://termix.site/img/sponsors/blacksmith.svg" height="40" alt="Blacksmith" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.cloudflare.com/">
|
||||
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="40" alt="Cloudflare" />
|
||||
<img src="https://termix.site/img/sponsors/cloudflare.png" height="40" alt="Cloudflare" />
|
||||
</a>
|
||||
|
||||
<a href="https://akamai.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/8/8b/Akamai_logo.svg" height="40" alt="Akamai" />
|
||||
<img src="https://termix.site/img/sponsors/akamai.svg" height="40" alt="Akamai" />
|
||||
</a>
|
||||
|
||||
<a href="https://aws.amazon.com/">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
|
||||
<img src="https://termix.site/img/sponsors/aws.png" height="40" alt="AWS" />
|
||||
</a>
|
||||
|
||||
<a href="https://rackgenius.com/">
|
||||
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="Rack Genius" />
|
||||
<img src="https://termix.site/img/sponsors/rackgenius.png" height="40" alt="Rack Genius" />
|
||||
</a>
|
||||
|
||||
<a href="https://ginernet.com/">
|
||||
<img src="https://ginernet.com/img/logo-web.png" height="40" alt="Ginernet" />
|
||||
<img src="https://termix.site/img/sponsors/ginernet.png" height="40" alt="Ginernet" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.hetzner.com/?mtm_campaign=termix&mtm_medium=referral&mtm_content=sponsoring_link">
|
||||
<img src="https://termix.site/img/sponsors/hetzner.png" height="40" alt="Hetzner" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SPONSORS:END -->
|
||||
|
||||
<br />
|
||||
|
||||
## Hỗ trợ
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
CREATE TABLE `collab_room_members` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`room_id` varchar(255) NOT NULL,
|
||||
`user_id` varchar(255) NOT NULL,
|
||||
`room_role` text NOT NULL DEFAULT ('member'),
|
||||
`added_by` varchar(255),
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `collab_room_members_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_collab_room_members_room_user` UNIQUE(`room_id`,`user_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `collab_rooms` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`owner_user_id` varchar(255) NOT NULL,
|
||||
`persistent` boolean NOT NULL DEFAULT false,
|
||||
`presenter_user_id` varchar(255),
|
||||
`stage_protocol` text,
|
||||
`stage_host_id` int,
|
||||
`stage_share_id` varchar(255),
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`ended_at` text,
|
||||
CONSTRAINT `collab_rooms_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `collab_room_members` ADD CONSTRAINT `collab_room_members_room_id_collab_rooms_id_fk` FOREIGN KEY (`room_id`) REFERENCES `collab_rooms`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `collab_room_members` ADD CONSTRAINT `collab_room_members_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `collab_room_members` ADD CONSTRAINT `collab_room_members_added_by_users_id_fk` FOREIGN KEY (`added_by`) REFERENCES `users`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `collab_rooms` ADD CONSTRAINT `collab_rooms_owner_user_id_users_id_fk` FOREIGN KEY (`owner_user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `collab_rooms` ADD CONSTRAINT `collab_rooms_presenter_user_id_users_id_fk` FOREIGN KEY (`presenter_user_id`) REFERENCES `users`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `collab_rooms` ADD CONSTRAINT `collab_rooms_stage_host_id_ssh_data_id_fk` FOREIGN KEY (`stage_host_id`) REFERENCES `ssh_data`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `collab_rooms` ADD CONSTRAINT `collab_rooms_stage_share_id_session_shares_id_fk` FOREIGN KEY (`stage_share_id`) REFERENCES `session_shares`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_collab_room_members_user` ON `collab_room_members` (`user_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_collab_rooms_owner` ON `collab_rooms` (`owner_user_id`);
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `collab_rooms` ADD `guest_link_token` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `collab_rooms` ADD CONSTRAINT `idx_collab_rooms_guest_token` UNIQUE(`guest_link_token`);
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE `secret_sources` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`user_id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`kind` text NOT NULL DEFAULT ('onepassword-connect'),
|
||||
`base_url` text NOT NULL,
|
||||
`token` text NOT NULL,
|
||||
`shared` boolean NOT NULL DEFAULT false,
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `secret_sources_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `secret_sources` ADD CONSTRAINT `secret_sources_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_secret_sources_user` ON `secret_sources` (`user_id`);
|
||||
@@ -0,0 +1,42 @@
|
||||
CREATE TABLE `credential_access` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`credential_id` int NOT NULL,
|
||||
`user_id` varchar(255),
|
||||
`role_id` int,
|
||||
`granted_by` varchar(255) NOT NULL,
|
||||
`permission_level` text NOT NULL DEFAULT ('use'),
|
||||
`expires_at` varchar(255),
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `credential_access_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `shared_credential_secrets` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`credential_access_id` int NOT NULL,
|
||||
`target_user_id` varchar(255) NOT NULL,
|
||||
`credential_id` int NOT NULL,
|
||||
`encrypted_username` text,
|
||||
`auth_type` text NOT NULL DEFAULT ('password'),
|
||||
`encrypted_password` text,
|
||||
`encrypted_key` text,
|
||||
`encrypted_key_password` text,
|
||||
`key_type` text,
|
||||
`public_key` text,
|
||||
`cert_public_key` text,
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `shared_credential_secrets_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_shared_credential_secrets_scope` UNIQUE(`credential_access_id`,`target_user_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_credential_id_ssh_credentials_id_fk` FOREIGN KEY (`credential_id`) REFERENCES `ssh_credentials`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_role_id_roles_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_granted_by_users_id_fk` FOREIGN KEY (`granted_by`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` ADD CONSTRAINT `shared_cred_secrets_access_id_fk` FOREIGN KEY (`credential_access_id`) REFERENCES `credential_access`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` ADD CONSTRAINT `shared_credential_secrets_target_user_id_users_id_fk` FOREIGN KEY (`target_user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` ADD CONSTRAINT `shared_credential_secrets_credential_id_ssh_credentials_id_fk` FOREIGN KEY (`credential_id`) REFERENCES `ssh_credentials`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_user_id` ON `credential_access` (`user_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_role_id` ON `credential_access` (`role_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_credential_id` ON `credential_access` (`credential_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_shared_credential_secrets_target` ON `shared_credential_secrets` (`target_user_id`,`credential_id`);
|
||||
@@ -0,0 +1,22 @@
|
||||
CREATE TABLE `folder_access` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`owner_user_id` varchar(255) NOT NULL,
|
||||
`folder` varchar(255) NOT NULL,
|
||||
`user_id` varchar(255),
|
||||
`role_id` int,
|
||||
`granted_by` varchar(255) NOT NULL,
|
||||
`permission_level` text NOT NULL DEFAULT ('connect'),
|
||||
`expires_at` varchar(255),
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `folder_access_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` MODIFY COLUMN `folder` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `snippets` MODIFY COLUMN `folder` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_credentials` MODIFY COLUMN `folder` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `vault_profiles` MODIFY COLUMN `folder` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `folder_access` ADD CONSTRAINT `folder_access_owner_user_id_users_id_fk` FOREIGN KEY (`owner_user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `folder_access` ADD CONSTRAINT `folder_access_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `folder_access` ADD CONSTRAINT `folder_access_role_id_roles_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `folder_access` ADD CONSTRAINT `folder_access_granted_by_users_id_fk` FOREIGN KEY (`granted_by`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_folder_access_owner_folder` ON `folder_access` (`owner_user_id`,`folder`);
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `ssh_data` ADD `enable_web_ui` boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` ADD `web_ui_config` text;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `ssh_data` ADD `enable_ai_assistant` boolean DEFAULT false NOT NULL;
|
||||
@@ -0,0 +1,51 @@
|
||||
CREATE TABLE `plugin_install_counts` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`plugin_id` varchar(255) NOT NULL,
|
||||
`registry_id` varchar(255) NOT NULL,
|
||||
`count` int NOT NULL DEFAULT 0,
|
||||
`source` text NOT NULL DEFAULT ('aggregate-telemetry'),
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `plugin_install_counts_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_plugin_install_counts_plugin_registry` UNIQUE(`plugin_id`,`registry_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `plugin_permission_grants` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`plugin_id` varchar(255) NOT NULL,
|
||||
`capability` varchar(255) NOT NULL,
|
||||
`granted_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`granted_by` varchar(255) NOT NULL,
|
||||
CONSTRAINT `plugin_permission_grants_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_plugin_permission_grants_plugin_capability` UNIQUE(`plugin_id`,`capability`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `plugin_registries` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`url` text NOT NULL,
|
||||
`kind` text NOT NULL DEFAULT ('community'),
|
||||
`enabled` boolean NOT NULL DEFAULT true,
|
||||
`signing_key` text,
|
||||
`last_checked_at` text,
|
||||
`last_index_hash` text,
|
||||
CONSTRAINT `plugin_registries_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `plugins` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`version` text NOT NULL,
|
||||
`tier` text NOT NULL DEFAULT ('available'),
|
||||
`source` text NOT NULL DEFAULT ('community'),
|
||||
`registry_id` varchar(255),
|
||||
`state` text NOT NULL DEFAULT ('disabled'),
|
||||
`installed_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`auto_update` boolean NOT NULL DEFAULT false,
|
||||
`manifest_json` text NOT NULL,
|
||||
CONSTRAINT `plugins_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `plugin_permission_grants` ADD CONSTRAINT `plugin_permission_grants_plugin_id_plugins_id_fk` FOREIGN KEY (`plugin_id`) REFERENCES `plugins`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `plugin_permission_grants` ADD CONSTRAINT `plugin_permission_grants_granted_by_users_id_fk` FOREIGN KEY (`granted_by`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_plugins_registry_id` ON `plugins` (`registry_id`);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `user_preferences` ADD `show_pin_app_rail_button` boolean;
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE `plugin_storage` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`plugin_id` varchar(255) NOT NULL,
|
||||
`key` varchar(255) NOT NULL,
|
||||
`value` text NOT NULL,
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `plugin_storage_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_plugin_storage_plugin_key` UNIQUE(`plugin_id`,`key`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `plugin_storage` ADD CONSTRAINT `plugin_storage_plugin_id_plugins_id_fk` FOREIGN KEY (`plugin_id`) REFERENCES `plugins`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,3 @@
|
||||
DROP TABLE `alert_firings`;--> statement-breakpoint
|
||||
DROP TABLE `alert_rule_channels`;--> statement-breakpoint
|
||||
DROP TABLE `alert_rules`;
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `plugin_permission_grants` MODIFY COLUMN `granted_by` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `plugin_permission_grants` ADD `source` text DEFAULT ('admin') NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `plugins` ADD `last_error` text;
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE `plugin_migrations` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`plugin_id` varchar(255) NOT NULL,
|
||||
`migration_id` varchar(255) NOT NULL,
|
||||
`checksum` text NOT NULL,
|
||||
`applied_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `plugin_migrations_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_plugin_migrations_plugin_migration` UNIQUE(`plugin_id`,`migration_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `plugin_migrations` ADD CONSTRAINT `plugin_migrations_plugin_id_plugins_id_fk` FOREIGN KEY (`plugin_id`) REFERENCES `plugins`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,17 @@
|
||||
CREATE TABLE `rbac_applied_defaults` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`role_name` varchar(255) NOT NULL,
|
||||
`permission` varchar(255) NOT NULL,
|
||||
`applied_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `rbac_applied_defaults_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_rbac_applied_defaults_role_permission` UNIQUE(`role_name`,`permission`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `rbac_known_permissions` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`permission` varchar(255) NOT NULL,
|
||||
`plugin_id` varchar(255),
|
||||
`first_seen_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `rbac_known_permissions_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_rbac_known_permissions_permission` UNIQUE(`permission`)
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE `plugin_settings` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`plugin_id` varchar(255) NOT NULL,
|
||||
`scope` enum('admin','user','host','secret') NOT NULL,
|
||||
`scope_id` varchar(255),
|
||||
`key` varchar(255) NOT NULL,
|
||||
`value` text,
|
||||
`encrypted` boolean NOT NULL DEFAULT false,
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `plugin_settings_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_plugin_settings_scope_key` UNIQUE(`plugin_id`,`scope`,`scope_id`,`key`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `plugin_settings` ADD CONSTRAINT `plugin_settings_plugin_id_plugins_id_fk` FOREIGN KEY (`plugin_id`) REFERENCES `plugins`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_plugin_settings_plugin_scope` ON `plugin_settings` (`plugin_id`,`scope`);
|
||||
@@ -0,0 +1,24 @@
|
||||
CREATE TABLE `user_external_identities` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`user_id` varchar(255) NOT NULL,
|
||||
`provider_id` varchar(255) NOT NULL,
|
||||
`subject` varchar(255) NOT NULL,
|
||||
`email` text,
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `user_external_identities_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_user_external_identities_provider_subject` UNIQUE(`provider_id`,`subject`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `user_second_factors` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`user_id` varchar(255) NOT NULL,
|
||||
`plugin_id` varchar(255) NOT NULL,
|
||||
`factor_id` varchar(255) NOT NULL,
|
||||
`enrolled_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `user_second_factors_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_user_second_factors_user_factor` UNIQUE(`user_id`,`plugin_id`,`factor_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `user_external_identities` ADD CONSTRAINT `user_external_identities_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `user_second_factors` ADD CONSTRAINT `user_second_factors_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_user_external_identities_user` ON `user_external_identities` (`user_id`);
|
||||
@@ -0,0 +1,5 @@
|
||||
-- user_workspaces moved to the workspaces plugin, whose first migration renames it
|
||||
-- to p_workspaces_workspaces. Dropping it here would lose every saved workspace,
|
||||
-- so this only stops drizzle tracking it. SELECT 1 because MySQL rejects an
|
||||
-- empty query.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- network_topology moved to the network-topology plugin, which adopts (renames)
|
||||
-- this table in its own migration before this drizzle migration would run.
|
||||
-- No DROP here: it would delete every row before the plugin's rename applies.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- snippets, snippet_folders and snippet_access moved to the snippets plugin
|
||||
-- (p_snippets_*), adopted by rename rather than dropped. A real DROP TABLE
|
||||
-- here would run before the plugin's adoption migration and delete every row.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- dropped, see plugin adoption (fleets plugin, migrations/mysql/0001_adopt_fleets.sql)
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- proxmox_node_history and proxmox_stats_preferences moved to the proxmox
|
||||
-- plugin (p_proxmox_*), adopted by rename rather than dropped. The four
|
||||
-- ssh_data proxmox columns are copied into the plugin's host settings after
|
||||
-- plugins load, which is after this migration, so a real DROP COLUMN here
|
||||
-- would delete the data first. The columns stay in place, unused, until 3.0.0.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- file_manager_pinned, file_manager_recent, file_manager_shortcuts and
|
||||
-- transfer_recent are adopted (renamed, not dropped) by the file-manager
|
||||
-- plugin's own migration, which runs at plugin activation, after core's
|
||||
-- drizzle migrations. A DROP TABLE here would run first and delete the data.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- c2s_tunnel_presets moved to the tunnels plugin, whose first migration renames
|
||||
-- it to p_tunnels_presets. Dropping it here would lose every saved preset, so
|
||||
-- this only stops drizzle tracking it. SELECT 1 because MySQL rejects an
|
||||
-- empty query.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- command_history moved to the ssh-terminal plugin, whose first migration
|
||||
-- renames it to p_ssh_terminal_command_history. Dropping it here would lose
|
||||
-- every saved command, so this only stops drizzle tracking it. SELECT 1
|
||||
-- because MySQL rejects an empty query.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- tmux_session_tags moved to the tmux-monitor plugin, whose first migration
|
||||
-- renames it to p_tmux_monitor_session_tags. Dropping it here would lose
|
||||
-- every saved tag, so this only stops drizzle tracking it. SELECT 1 because
|
||||
-- MySQL rejects an empty query.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- session_shares, session_share_participants, collab_rooms and
|
||||
-- collab_room_members moved to the session-sharing plugin, whose first
|
||||
-- migration renames them. Dropping them here would lose every share and
|
||||
-- room, so this only stops drizzle tracking them. SELECT 1 because MySQL
|
||||
-- rejects an empty query.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- session_recordings moved to the session-recording plugin, whose first
|
||||
-- migration renames it. Dropping it here would lose every recording, so
|
||||
-- this only stops drizzle tracking it. SELECT 1 because MySQL rejects an
|
||||
-- empty query.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,7 @@
|
||||
-- The remote desktop host options (enable_rdp, enable_vnc, enable_telnet,
|
||||
-- the three ports, rdp_security, rdp_ignore_cert, security, ignore_cert,
|
||||
-- guacamole_config) and user_preferences.rdp_defaults moved to the
|
||||
-- remote-desktop plugin's settings. The copy runs after plugins load, which
|
||||
-- is after this migration, so a real DROP COLUMN here would delete the data
|
||||
-- first. The columns stay in place, unused, until 3.0.0.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,9 @@
|
||||
-- host_metrics_preferences, host_health_checks, host_health_history and
|
||||
-- host_metrics_history moved to the host-metrics plugin, which adopts them by
|
||||
-- rename in its own first migration. That runs after this one, so a real
|
||||
-- DROP TABLE here would delete every row first.
|
||||
SELECT 1;--> statement-breakpoint
|
||||
-- Status checks are core: the per-host switch and interval, copied out of
|
||||
-- stats_config at boot by host-status-config-migration.ts.
|
||||
ALTER TABLE `ssh_data` ADD `status_check_enabled` boolean DEFAULT true NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` ADD `status_check_interval` int;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- ssh_data.stats_config split: its status half moved to status_check_enabled
|
||||
-- and status_check_interval, its metrics half to the host-metrics plugin's
|
||||
-- host settings. Both copies run at boot, after this migration, so a real
|
||||
-- DROP COLUMN here would delete the data first. The column stays in place,
|
||||
-- unused, until 3.0.0.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- ssh_data.enable_docker and docker_config moved to the docker plugin's host
|
||||
-- settings. The copy runs at boot, after this migration, so a real DROP
|
||||
-- COLUMN here would delete the data first. The columns stay in place,
|
||||
-- unused, until 3.0.0.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- The automation tables moved to the automations plugin, which renames them
|
||||
-- into its own namespace at activation. That runs after this migration, so a
|
||||
-- real DROP TABLE here would delete every automation first.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,8 @@
|
||||
-- The ai tables moved to the ai plugin, which renames them into its own
|
||||
-- namespace at activation, and ssh_data.enable_ai_assistant and the two
|
||||
-- user_preferences ai columns moved to its settings. Both run after this
|
||||
-- migration, so a real DROP here would delete the data first. The columns
|
||||
-- stay in place, unused, until 3.0.0. The timestamp and label type changes
|
||||
-- drizzle-kit also wrote are generator drift (see FINISH-LIST.md), not a
|
||||
-- change to the database, and are left out on purpose.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- dashboard_service_links, homepage_items and homepage_layouts moved to the
|
||||
-- homepage plugin, which adopts them by rename at activation (see
|
||||
-- plugins/homepage/migrations/mysql/0001_adopt_homepage_tables.sql).
|
||||
-- Dropping them here would delete every row before the plugin's migration
|
||||
-- ever runs, since this runs at boot before the plugins table exists.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- mac_address and wol_broadcast_address move to the wake-on-lan plugin's
|
||||
-- host settings at boot, after this migration runs. Dropping them here would
|
||||
-- delete the data before the copy has a chance to run.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- secret_sources moves to the secret-sources plugin's adopted table at
|
||||
-- activation, after this migration runs. Dropping it here would delete the
|
||||
-- data before the plugin has a chance to rename it.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- webauthn_credentials moves to the webauthn plugin's adopted table at
|
||||
-- activation, and the users TOTP columns are read by the TOTP boot migration
|
||||
-- after this runs. Dropping either here would lose the data first.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- sso_providers moves to the sso plugin's adopted table at activation, and
|
||||
-- its LDAP rows are copied into the ldap plugin by a boot migration after
|
||||
-- this runs. Dropping it here would lose the data first.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- opkssh_tokens moves to the opkssh plugin's adopted table at activation,
|
||||
-- and ssh_data.use_warpgate is copied into the warpgate plugin's host
|
||||
-- settings by a boot migration after this runs. Dropping either here would
|
||||
-- lose the data first.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- vault_profiles and vault_tokens move to the vault plugin's adopted tables
|
||||
-- at activation, and ssh_data.vault_profile_id is copied into the vault
|
||||
-- plugin's host settings by a boot migration after this runs. Dropping any
|
||||
-- of them here would lose the data first.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- termix_identities, termix_identity_keys and termix_identity_ca move to the
|
||||
-- termix-identity plugin's adopted tables at activation. Dropping them here
|
||||
-- would lose the data first.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,52 @@
|
||||
-- The dialect generator now decides varchar or text per table. Columns that
|
||||
-- were varchar(255) only because the same name was a key in another table
|
||||
-- become text, and the timestamps and labels B18's regeneration left as
|
||||
-- varchar(255) on real databases follow. varchar to text keeps every value.
|
||||
ALTER TABLE `api_keys` MODIFY COLUMN `name` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `api_keys` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `api_keys` MODIFY COLUMN `expires_at` text;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` MODIFY COLUMN `expires_at` text;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `credential_sidebar_preferences` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `folder_access` MODIFY COLUMN `expires_at` text;--> statement-breakpoint
|
||||
ALTER TABLE `folder_access` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `host_access` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `host_sidebar_preferences` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` MODIFY COLUMN `name` text;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` MODIFY COLUMN `folder` text;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_data` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `notification_channels` MODIFY COLUMN `name` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `notification_channels` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `plugin_install_counts` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `plugin_registries` MODIFY COLUMN `name` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `plugin_settings` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `plugin_storage` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `plugins` MODIFY COLUMN `name` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `plugins` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `rbac_known_permissions` MODIFY COLUMN `plugin_id` text;--> statement-breakpoint
|
||||
ALTER TABLE `roles` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `roles` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `sessions` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `shared_host_auth_overrides` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `shared_host_auth_overrides` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `shared_host_secrets` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `shared_host_secrets` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_credentials` MODIFY COLUMN `name` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_credentials` MODIFY COLUMN `folder` text;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_credentials` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_credentials` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_folders` MODIFY COLUMN `name` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `ssh_folders` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `ssh_folders` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `sync_tombstones` MODIFY COLUMN `sync_id` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `trusted_devices` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `trusted_devices` MODIFY COLUMN `expires_at` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `ui_preferences` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `user_external_identities` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `user_open_tabs` MODIFY COLUMN `label` text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `user_open_tabs` MODIFY COLUMN `created_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `user_open_tabs` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);--> statement-breakpoint
|
||||
ALTER TABLE `user_preferences` MODIFY COLUMN `updated_at` text NOT NULL DEFAULT (CURRENT_TIMESTAMP);
|
||||
@@ -0,0 +1,6 @@
|
||||
-- The file manager, tunnels, web endpoint, terminal, tmux monitor, session
|
||||
-- sharing and session recording host columns, and the dead show_*_in_sidebar
|
||||
-- columns, moved to their plugins' host settings. The copies run after
|
||||
-- plugins load, which is after this migration, so a real DROP COLUMN here
|
||||
-- would delete the data first. The columns stay in place, unused, until 3.0.0.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- dismissed_alerts and notification_channels moved to the alerts plugin. It
|
||||
-- renames the first into its own namespace and copies the second at
|
||||
-- activation, both after this migration, so a real DROP TABLE here would
|
||||
-- delete them first. notification_channels stays in place, unused, until
|
||||
-- 3.0.0.
|
||||
SELECT 1;
|
||||
Loaded 100 of 4568 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user