Sync from Heretek-AI/ProxmoxVE - 2026-03-15

This commit is contained in:
github-actions[bot]
2026-03-15 11:40:42 +00:00
parent 5ff3c5714d
commit 9b120bada2
485 changed files with 131660 additions and 794 deletions
+60 -33
View File
@@ -1,38 +1,65 @@
# ---------------------------------------
# Treat Shell files as first-class code
# ---------------------------------------
*.sh linguist-detectable=true
*.bash linguist-language=Shell
*.func linguist-language=Shell
*.install linguist-language=Shell
# Git Attributes for Heretek-AI/ProxmoxVE Fork
# These attributes configure how git handles merges from upstream
# Files with 'merge=ours' will always keep the fork version during merges
# ---------------------------------------
# Treat Golang files as Go (for /api/)
api/**/*.go linguist-language=Go
# =============================================================================
# CUSTOM SCRIPT DIRECTORIES - Always preserve fork versions
# =============================================================================
# ---------------------------------------
# Treat frontend as JavaScript/TypeScript (optional)
frontend/**/*.ts linguist-language=TypeScript
frontend/**/*.js linguist-language=JavaScript
# Custom install scripts
install/ merge=ours
install/*.sh merge=ours
# ---------------------------------------
# Exclude documentation from stats
*.md linguist-documentation
docs/** linguist-documentation
README.md linguist-documentation
CONTRIBUTING.md linguist-documentation
SECURITY.md linguist-documentation
# Custom container scripts
ct/ merge=ours
ct/*.sh merge=ours
ct/headers/ merge=ours
ct/headers/* merge=ours
# ---------------------------------------
# Exclude generated/config files
*.json linguist-generated
frontend/public/json/*.json linguist-generated=false
*.lock linguist-generated
*.yml linguist-generated
*.yaml linguist-generated
.github/** linguist-generated
.vscode/** linguist-generated
# Custom frontend (entire directory)
frontend/ merge=ours
frontend/** merge=ours
# ---------------------------------------
# Standard text handling
* text=auto eol=lf
# Custom images
misc/images/ merge=ours
misc/images/* merge=ours
# Custom addon tools
tools/addon/ merge=ours
tools/addon/* merge=ours
# =============================================================================
# WORKFLOW CONFIGURATION - Preserve fork-specific CI/CD
# =============================================================================
# Custom GitHub Actions workflows
.github/workflows/ merge=ours
.github/workflows/* merge=ours
# Custom runner configurations
.github/runner/ merge=ours
.github/runner/** merge=ours
# =============================================================================
# DOCUMENTATION - Preserve fork-specific branding
# =============================================================================
# Custom README with fork branding
README.md merge=ours
# Custom CHANGELOG
CHANGELOG.md merge=ours
# =============================================================================
# DEFAULT ATTRIBUTES
# =============================================================================
# Auto-detect text files and perform LF normalization
* text=auto
# Shell scripts should always have LF line endings
*.sh text eol=lf
# GitHub Actions workflows should have LF line endings
*.yml text eol=lf
*.yaml text eol=lf
+259 -123
View File
@@ -1,155 +1,291 @@
name: Sync Upstream (Create Pull Request)
name: Sync Upstream (Git Merge Strategy)
on:
schedule:
# Runs automatically every day at 2:00 AM UTC. Adjust as needed.
# Runs automatically every day at 2:00 AM UTC
- cron: '0 2 * * *'
workflow_dispatch: # Allows you to run this manually from the Actions tab
workflow_dispatch:
# Allows manual trigger from the Actions tab
inputs:
force_sync:
description: 'Force sync even if no new commits detected'
required: false
default: 'false'
type: boolean
permissions:
contents: write # Required to allow the GitHub Actions bot to push commits
pull-requests: write # Required to create pull requests
contents: write
pull-requests: write
env:
UPSTREAM_REPO: community-scripts/ProxmoxVE
UPSTREAM_BRANCH: main
FORK_BRANCH: main
jobs:
check-and-sync:
runs-on: ubuntu-latest
outputs:
has_changes: ${{ steps.check.outputs.has_changes }}
commit_count: ${{ steps.check.outputs.commit_count }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ env.FORK_BRANCH }}
token: ${{ secrets.PAT_WORKFLOW || secrets.GITHUB_TOKEN }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Configure the 'ours' merge driver for fork-specific files
# This tells git to use our version for files marked with merge=ours in .gitattributes
git config merge.ours.name "ours merge driver"
git config merge.ours.driver "true"
- name: Add upstream remote
run: |
git remote add upstream https://github.com/${{ env.UPSTREAM_REPO }}.git || true
git fetch upstream ${{ env.UPSTREAM_BRANCH }}
- name: Check for new upstream commits
id: check
run: |
# Get the merge base between fork and upstream
MERGE_BASE=$(git merge-base HEAD upstream/${{ env.UPSTREAM_BRANCH }} 2>/dev/null || echo "")
if [ -z "$MERGE_BASE" ]; then
echo "No common ancestor found - this may be a fresh sync"
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "commit_count=unknown" >> $GITHUB_OUTPUT
exit 0
fi
# Count commits in upstream that are not in fork
UPSTREAM_COMMITS=$(git rev-list $MERGE_BASE..upstream/${{ env.UPSTREAM_BRANCH }} --count 2>/dev/null || echo "0")
if [ "$UPSTREAM_COMMITS" -eq 0 ] && [ "${{ github.event.inputs.force_sync }}" != "true" ]; then
echo "No new commits from upstream. Nothing to sync."
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "commit_count=0" >> $GITHUB_OUTPUT
else
echo "Found $UPSTREAM_COMMITS new commits from upstream."
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "commit_count=$UPSTREAM_COMMITS" >> $GITHUB_OUTPUT
fi
sync-and-create-pr:
needs: check-and-sync
if: needs.check-and-sync.outputs.has_changes == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetches all history for all branches and tags
# If your default branch is not 'main', change it here:
ref: main
fetch-depth: 0
ref: ${{ env.FORK_BRANCH }}
token: ${{ secrets.PAT_WORKFLOW || secrets.GITHUB_TOKEN }}
- name: Sync upstream and create pull request
- name: Configure Git with merge driver
run: |
# 1. Configure Git for the Actions bot
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# 2. Add the upstream repository
git remote add upstream https://github.com/community-scripts/ProxmoxVE.git
git fetch upstream main
# 3. Check if there are any new commits from upstream
UPSTREAM_COMMITS=$(git log HEAD..upstream/main --oneline 2>/dev/null | wc -l)
if [ "$UPSTREAM_COMMITS" -eq 0 ]; then
echo "No new commits from upstream. Nothing to sync."
exit 0
fi
echo "Found $UPSTREAM_COMMITS new commits from upstream."
# 4. Backup ignored directories and files BEFORE creating sync branch
echo "Backing up fork-specific directories and files..."
mkdir -p /tmp/backup
cp -r install /tmp/backup/
cp -r ct /tmp/backup/
cp -r frontend /tmp/backup/
cp -r misc/images /tmp/backup/images
cp -r .github/workflows /tmp/backup/workflows
cp -r .github/runner /tmp/backup/runner
cp -r tools/addon /tmp/backup/addon
cp CHANGELOG.md /tmp/backup/
cp README.md /tmp/backup/
# 5. Create a new branch from upstream/main for the PR
# Configure the 'ours' merge driver
# Files with merge=ours in .gitattributes will automatically keep fork version
git config merge.ours.name "ours merge driver"
git config merge.ours.driver "true"
- name: Add upstream remote
run: |
git remote add upstream https://github.com/${{ env.UPSTREAM_REPO }}.git || true
git fetch upstream ${{ env.UPSTREAM_BRANCH }}
- name: Create sync branch
id: branch
run: |
BRANCH_NAME="upstream-sync-$(date +%Y%m%d-%H%M%S)"
echo "Creating sync branch: $BRANCH_NAME"
git checkout -b "$BRANCH_NAME" upstream/main
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
git checkout -b "$BRANCH_NAME"
- name: Merge upstream with fork preservation
id: merge
run: |
echo "Starting merge from upstream/${{ env.UPSTREAM_BRANCH }}..."
# 6. Restore fork-specific files on this branch
echo "Restoring fork-specific directories and files..."
rm -rf install ct frontend misc/images
cp -r /tmp/backup/install .
cp -r /tmp/backup/ct .
cp -r /tmp/backup/frontend .
mkdir -p misc
cp -r /tmp/backup/images misc/images
rm -rf .github/workflows
mkdir -p .github
cp -r /tmp/backup/workflows .github/workflows
rm -rf .github/runner
cp -r /tmp/backup/runner .github/runner
rm -rf tools/addon
mkdir -p tools
cp -r /tmp/backup/addon tools/addon
cp /tmp/backup/CHANGELOG.md .
cp /tmp/backup/README.md .
# Attempt merge with the 'ours' strategy for conflicts
# The .gitattributes file configures which files use merge=ours
git merge upstream/${{ env.UPSTREAM_BRANCH }} \
--no-edit \
-m "Merge upstream ${{ env.UPSTREAM_REPO }} into ${{ env.FORK_BRANCH }}" \
2>&1 || MERGE_STATUS=$?
# 7. Stage all restored files
git add install ct frontend misc/images .github/workflows .github/runner tools/addon CHANGELOG.md README.md
# 8. Check for any merge conflicts in other files
# Since we're creating from upstream/main, we need to check against main
git fetch origin main
CONFLICT_FILES=$(git diff --name-only origin/main HEAD | head -50)
# 9. Commit the sync with preserved files
if ! git diff --staged --quiet; then
git commit -m "Sync from upstream - preserving fork-specific customizations"
if [ "${MERGE_STATUS:-0}" -eq 0 ]; then
echo "Merge completed successfully with no conflicts."
echo "merge_status=success" >> $GITHUB_OUTPUT
echo "has_conflicts=false" >> $GITHUB_OUTPUT
elif [ "${MERGE_STATUS:-0}" -eq 1 ]; then
echo "Merge has conflicts that need resolution."
echo "merge_status=conflicts" >> $GITHUB_OUTPUT
echo "has_conflicts=true" >> $GITHUB_OUTPUT
# List conflicted files
CONFLICTS=$(git diff --name-only --diff-filter=U 2>/dev/null || echo "")
echo "conflicted_files<<EOF" >> $GITHUB_OUTPUT
echo "$CONFLICTS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Check if conflicts are only in fork-specific files
# These should have been handled by merge=ours, but check anyway
FORK_FILES=$(git diff --name-only --diff-filter=U \
-- 'install/' 'ct/' 'frontend/' 'misc/images/' '.github/workflows/' '.github/runner/' 'tools/addon/' 'README.md' 'CHANGELOG.md' 2>/dev/null || echo "")
if [ -n "$FORK_FILES" ]; then
echo "Warning: Fork-specific files have unexpected conflicts:"
echo "$FORK_FILES"
# For fork files, always take our version
for file in $FORK_FILES; do
git checkout --ours "$file" 2>/dev/null || true
git add "$file" 2>/dev/null || true
done
fi
# For other conflicts, we leave them for manual resolution in the PR
# This allows reviewers to see what needs attention
else
echo "Merge failed with status: ${MERGE_STATUS}"
echo "merge_status=failed" >> $GITHUB_OUTPUT
exit 1
fi
- name: Get upstream changes summary
id: summary
run: |
# Get list of upstream commits being merged
echo "upstream_commits<<EOF" >> $GITHUB_OUTPUT
git log HEAD..upstream/${{ env.UPSTREAM_BRANCH }} --oneline --no-merges | head -30 >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Get list of changed files for PR description
CHANGED_FILES=$(git diff --name-only origin/main HEAD | head -100)
UPSTREAM_LOG=$(git log origin/main..HEAD --oneline | head -20)
# Get changed files summary
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
git diff --name-only HEAD upstream/${{ env.UPSTREAM_BRANCH }} | head -50 >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# 10. Push the branch
git push origin HEAD --force
# 11. Create PR using GitHub CLI
echo "Creating pull request for upstream sync..."
gh pr create \
--title "🔄 Upstream Sync - $(date +%Y-%m-%d)" \
--body "This PR syncs the latest changes from upstream [\`community-scripts/ProxmoxVE\`](https://github.com/community-scripts/ProxmoxVE) while preserving fork-specific customizations.
# Count files by category
TOTAL_CHANGED=$(git diff --name-only HEAD upstream/${{ env.UPSTREAM_BRANCH }} | wc -l)
echo "total_changed=$TOTAL_CHANGED" >> $GITHUB_OUTPUT
## 📋 Upstream Commits Included
\`\`\`
$UPSTREAM_LOG
\`\`\`
- name: Commit merge result
if: steps.merge.outputs.merge_status == 'conflicts'
run: |
# Commit the merge with resolved fork-specific conflicts
# Remaining conflicts will be visible in the PR for review
git commit -m "Merge upstream with partial conflict resolution
## 📁 Changed Files
<details>
<summary>Click to expand</summary>
Fork-specific files (install/, ct/, frontend/, etc.) have been preserved.
Other conflicts may require manual review before merging." || true
\`\`\`
$CHANGED_FILES
\`\`\`
</details>
- name: Push sync branch
run: |
git push origin ${{ steps.branch.outputs.branch_name }} --force
## ⚠️ Important
Before merging, ensure all fork-specific references are preserved:
- \`Heretek-AI\` repository references
- Fork-specific workflow files
- Custom workflow configurations
## 🔒 Fork-Specific Files Preserved
The following files/directories are preserved from the fork and NOT overwritten by upstream:
- \`install/\` directory
- \`ct/\` directory
- \`frontend/\` directory
- \`misc/images/\` directory
- \`.github/workflows/\` directory
- \`.github/runner/\` directory
- \`tools/addon/\` directory
- \`CHANGELOG.md\`
- \`README.md\`
## ✅ Checklist Before Merge
- [ ] Review all changed files for unexpected modifications
- [ ] Verify fork-specific files are intact
- [ ] Check for any new upstream files that might conflict with fork customizations
- [ ] Test any new scripts or features from upstream
---
*This PR was automatically created by the [upstream-sync workflow](https://github.com/Heretek-AI/ProxmoxVE/blob/main/.github/workflows/upstream-sync.yml).*" \
--base main \
--head "$BRANCH_NAME" || echo "PR may already exist or no changes to PR"
echo "✅ Pull request created successfully for upstream sync."
# Switch back to main
git checkout main
- name: Create Pull Request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH="${{ steps.branch.outputs.branch_name }}"
HAS_CONFLICTS="${{ steps.merge.outputs.has_conflicts }}"
CONFLICTED_FILES="${{ steps.merge.outputs.conflicted_files }}"
# Build PR body
PR_BODY="## 🔄 Upstream Sync Summary
This PR syncs the latest changes from upstream [\`${{ env.UPSTREAM_REPO }}\`](https://github.com/${{ env.UPSTREAM_REPO }}) while preserving fork-specific customizations.
### 📊 Sync Statistics
- **Upstream commits:** ${{ needs.check-and-sync.outputs.commit_count }}
- **Files changed:** ${{ steps.summary.outputs.total_changed }}
- **Merge conflicts:** ${HAS_CONFLICTS:-none}
### 📋 Upstream Commits (last 30)
\`\`\`
${{ steps.summary.outputs.upstream_commits }}
\`\`\`
### 📁 Changed Files
<details>
<summary>Click to view changed files</summary>
\`\`\`
${{ steps.summary.outputs.changed_files }}
\`\`\`
</details>
"
# Add conflict warning if needed
if [ "$HAS_CONFLICTS" = "true" ]; then
PR_BODY="$PR_BODY
### ⚠️ Merge Conflicts Detected
The following files have conflicts that need manual review:
\`\`\`
$CONFLICTED_FILES
\`\`\`
**Note:** Fork-specific files have been automatically preserved using the \`merge=ours\` strategy configured in \`.gitattributes\`.
"
else
PR_BODY="$PR_BODY
### ✅ Clean Merge
No conflicts detected. Fork-specific files were automatically preserved using the \`merge=ours\` strategy.
"
fi
# Add preserved files section
PR_BODY="$PR_BODY
### 🔒 Fork-Specific Files Preserved
The following files/directories are configured in \`.gitattributes\` to always keep the fork version:
- \`install/\` - Custom install scripts
- \`ct/\` - Custom container scripts
- \`frontend/\` - Custom frontend
- \`misc/images/\` - Custom images
- \`.github/workflows/\` - Custom CI/CD workflows
- \`.github/runner/\` - Custom runner configurations
- \`tools/addon/\` - Custom addon tools
- \`README.md\` - Fork-specific documentation
- \`CHANGELOG.md\` - Fork-specific changelog
### ✅ Pre-Merge Checklist
- [ ] Review all changed files for unexpected modifications
- [ ] Verify fork-specific files are intact
- [ ] Resolve any remaining merge conflicts
- [ ] Test any new scripts or features from upstream
---
*This PR was automatically created by the [upstream-sync workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/upstream-sync.yml).*
"
# Create PR title with conflict indicator
if [ "$HAS_CONFLICTS" = "true" ]; then
TITLE="🔄 Upstream Sync - $(date +%Y-%m-%d) ⚠️ CONFLICTS"
else
TITLE="🔄 Upstream Sync - $(date +%Y-%m-%d)"
fi
# Create the PR
gh pr create \
--title "$TITLE" \
--body "$PR_BODY" \
--base "${{ env.FORK_BRANCH }}" \
--head "$BRANCH" \
--label "upstream-sync,automated" || echo "PR may already exist"
- name: Cleanup
run: |
git checkout ${{ env.FORK_BRANCH }}
git branch -D ${{ steps.branch.outputs.branch_name }} 2>/dev/null || true
+2
View File
@@ -420,6 +420,8 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-03-15
## 2026-03-14
## 2026-03-13
@@ -1,5 +1,5 @@
{
"generated": "2026-03-13T12:28:01Z",
"generated": "2026-03-14T06:30:27Z",
"versions": [
{
"slug": "agregarr",
@@ -18,9 +18,23 @@
{
"slug": "llamacpp",
"repo": "ggml-org/llama.cpp",
"version": "b8308",
"version": "b8329",
"pinned": false,
"date": "2026-03-13T10:57:46Z"
"date": "2026-03-14T04:58:36Z"
},
{
"slug": "localai",
"repo": "mudler/LocalAI",
"version": "v3.12.1",
"pinned": false,
"date": "2026-02-21T13:49:24Z"
},
{
"slug": "localrecall",
"repo": "mudler/LocalRecall",
"version": "v0.5.5",
"pinned": false,
"date": "2026-02-16T22:38:06Z"
},
{
"slug": "maintainerr",
@@ -1,7 +1,9 @@
{
"name": "LocalRecall (In Testing - Borked)",
"name": "LocalRecall",
"slug": "localrecall",
"categories": [20],
"categories": [
20
],
"date_created": "2026-03-14",
"type": "ct",
"updateable": true,
@@ -1,7 +1,9 @@
{
"name": "RAGFlow (In Testing - Borked)",
"name": "RAGFlow",
"slug": "ragflow",
"categories": [20],
"categories": [
20
],
"date_created": "2026-03-12",
"type": "ct",
"updateable": true,
@@ -9,7 +11,7 @@
"interface_port": 80,
"documentation": "https://ragflow.io/docs/dev/",
"website": "https://ragflow.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ragflow.webp",
"logo": "https://raw.githubusercontent.com/infiniflow/ragflow/refs/heads/main/web/public/logo.svg",
"config_path": "/opt/ragflow/conf/service_conf.yaml",
"description": "RAGFlow is an open-source RAG (Retrieval-Augmented Generation) engine with deep document understanding. It provides a streamlined RAG workflow for businesses of any scale, combining LLM capabilities to provide truthful question-answering with well-founded citations from various complex formatted data.",
"install_methods": [
@@ -95,6 +95,9 @@ msg_ok "Installed Dependencies"
# DATABASE SETUP (MariaDB)
# ==============================================================================
# Install MariaDB server first
setup_mariadb
MARIADB_DB_NAME="rag_flow"
MARIADB_DB_USER="rag_flow"
setup_mariadb_db
@@ -121,6 +124,10 @@ REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
$STD apt-get install -y redis-server
# Stop Redis if running to apply new configuration
systemctl stop redis-server 2>/dev/null || true
# Write Redis configuration with password
cat <<EOF >/etc/redis/redis.conf
bind 127.0.0.1
port 6379
@@ -136,7 +143,17 @@ EOF
mkdir -p /var/log/redis
chown -R redis:redis /var/log/redis /var/lib/redis
systemctl enable -q --now redis-server
# Enable and start Redis with new configuration
systemctl enable -q redis-server
systemctl start redis-server
# Wait for Redis to be ready and verify password works
for i in {1..30}; do
if redis-cli -a "${REDIS_PASS}" ping 2>/dev/null | grep -q "PONG"; then
break
fi
sleep 1
done
msg_ok "Redis Installed"
# ==============================================================================
@@ -29,111 +29,48 @@ function update_script() {
exit
fi
cd /opt/ragflow || exit
LOCAL_VERSION=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
REMOTE_VERSION=$(git ls-remote origin HEAD 2>/dev/null | awk '{print $1}' || echo "unknown")
if check_for_gh_release "ragflow" "infiniflow/ragflow"; then
msg_info "Stopping Services"
systemctl stop ragflow-task-executor || true
systemctl stop ragflow-server || true
msg_ok "Stopped Services"
if [[ "$LOCAL_VERSION" == "$REMOTE_VERSION" ]] || [[ "$REMOTE_VERSION" == "unknown" ]]; then
if [[ "$REMOTE_VERSION" == "unknown" ]]; then
msg_info "Unable to check for updates. Checking local version..."
CURRENT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "unknown")
msg_info "Current version: ${CURRENT_TAG}"
fi
msg_info "No update required. ${APP} is already up to date."
exit 0
msg_info "Backing up Data"
cp -r /opt/ragflow/conf /opt/ragflow_conf_backup
cp -r /opt/ragflow/data /opt/ragflow_data_backup 2>/dev/null || true
cp /opt/ragflow/.env /opt/ragflow_env_backup 2>/dev/null || true
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ragflow" "infiniflow/ragflow" "tarball" "latest" "/opt/ragflow"
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /usr/local/bin/uv sync --python 3.12 --frozen --index-strategy unsafe-best-match
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
msg_info "Rebuilding Frontend"
cd /opt/ragflow/web || exit
$STD npm install
$STD npm run build
cp -r /opt/ragflow/web/dist/* /var/www/ragflow/
msg_ok "Rebuilt Frontend"
msg_info "Restoring Configuration"
cp -r /opt/ragflow_conf_backup/. /opt/ragflow/conf/
cp -r /opt/ragflow_data_backup/. /opt/ragflow/data/ 2>/dev/null || true
cp /opt/ragflow_env_backup /opt/ragflow/.env 2>/dev/null || true
rm -rf /opt/ragflow_conf_backup /opt/ragflow_data_backup /opt/ragflow_env_backup
msg_ok "Restored Configuration"
msg_info "Starting Services"
systemctl start ragflow-server
sleep 5
systemctl start ragflow-task-executor
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
msg_info "Stopping Services"
systemctl stop ragflow-task-executor || true
systemctl stop ragflow-server || true
msg_ok "Stopped Services"
msg_info "Backing up Data"
cp -r /opt/ragflow/conf /opt/ragflow_conf_backup
cp -r /opt/ragflow/data /opt/ragflow_data_backup 2>/dev/null || true
msg_ok "Backed up Data"
msg_info "Updating ${APP}"
$STD git fetch origin
$STD git reset --hard origin/main
$STD git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || true
msg_ok "Updated ${APP}"
# Fix: Replace gitee.com URLs with GitHub URLs
# RAGFlow's pyproject.toml and uv.lock may reference gitee.com which requires authentication
# We replace with GitHub mirror which is publicly accessible
if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_info "Replacing gitee.com URLs in pyproject.toml with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' pyproject.toml
msg_ok "Fixed graspologic URLs in pyproject.toml"
fi
if grep -q "gitee.com/infiniflow/graspologic" uv.lock 2>/dev/null; then
msg_info "Replacing gitee.com URLs in uv.lock with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' uv.lock
msg_ok "Fixed graspologic URLs in lock file"
fi
# Fix: Replace Chinese PyPI mirror with standard PyPI
# https://github.com/astral-sh/uv/issues/10462
# uv records index url into uv.lock but doesn't failover among multiple indexes
# RAGFlow uses pypi.tuna.tsinghua.edu.cn which may not have all packages
if grep -q "pypi.tuna.tsinghua.edu.cn" pyproject.toml 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' pyproject.toml
msg_ok "Fixed PyPI index URL in pyproject.toml"
fi
if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror in uv.lock with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' uv.lock
msg_ok "Fixed PyPI index URL in lock file"
fi
# Remove the ragflow_sdk package from pyproject.toml since we only need the
# server components. The SDK is a client library for connecting to RAGFlow
# from external applications, which is not needed for server-only installations.
if grep -q "sdk.python.ragflow_sdk" pyproject.toml 2>/dev/null; then
msg_info "Excluding SDK Package from Installation"
sed -i '/sdk.python.ragflow_sdk/d' pyproject.toml
msg_ok "Excluded ragflow_sdk from installation"
fi
# Fix: Pin MCP version to avoid pyjwt conflict with zhipuai
# zhipuai requires pyjwt>=2.8.0,<2.9.0 but mcp>=1.23.0 requires pyjwt>=2.10.1
# These constraints are incompatible. However, mcp==1.19.0 doesn't require pyjwt>=2.10.1
# By pinning MCP to 1.19.0 (matching upstream's uv.lock), we preserve ZhipuAI functionality
# See: https://github.com/MetaGLM/zhipuai-sdk-python-v4/issues/103
if grep -q 'mcp>=' pyproject.toml 2>/dev/null; then
msg_info "Pinning MCP version to 1.19.0 to preserve ZhipuAI compatibility"
sed -i 's/mcp>=1.23.0/mcp==1.19.0/' pyproject.toml
msg_ok "Pinned MCP to version 1.19.0"
fi
# Note: We do NOT remove agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
# Install Python dependencies using the upstream lock file
# The --frozen flag tells uv to use the lock file as-is without re-resolution
# This is the official RAGFlow installation method from their documentation
# Reference: https://ragflow.io/docs/launch_ragflow_from_source
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /root/.local/bin/uv sync --python 3.12 --frozen --index-strategy unsafe-best-match
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
msg_info "Restoring Configuration"
cp -r /opt/ragflow_conf_backup/. /opt/ragflow/conf/
rm -rf /opt/ragflow_conf_backup /opt/ragflow_data_backup
msg_ok "Restored Configuration"
msg_info "Starting Services"
systemctl start ragflow-server
systemctl start ragflow-task-executor
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
}
@@ -88,20 +88,6 @@ function update_script() {
msg_ok "Fixed PyPI index URL in lock file"
fi
# Fix: Ensure Python version constraint matches upstream
# RAGFlow upstream uses requires-python = ">=3.12,<3.15"
# infinity-sdk requires Python >=3.11,<3.14
# The intersection is >=3.12,<3.14, but we keep upstream's constraint
# and rely on the lock file for correct resolution
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
# Only update if it doesn't match upstream
if ! grep -q 'requires-python = ">=3.12,<3.15"' pyproject.toml 2>/dev/null; then
msg_info "Updating Python version constraint to match upstream"
sed -i 's/requires-python\s*=.*/requires-python = ">=3.12,<3.15"/' pyproject.toml
msg_ok "Updated Python version constraint"
fi
fi
# Remove the ragflow_sdk package from pyproject.toml since we only need the
# server components. The SDK is a client library for connecting to RAGFlow
# from external applications, which is not needed for server-only installations.
@@ -111,7 +97,18 @@ function update_script() {
msg_ok "Excluded ragflow_sdk from installation"
fi
# Note: We do NOT remove zhipuai or agentrun-sdk from pyproject.toml
# Fix: Pin MCP version to avoid pyjwt conflict with zhipuai
# zhipuai requires pyjwt>=2.8.0,<2.9.0 but mcp>=1.23.0 requires pyjwt>=2.10.1
# These constraints are incompatible. However, mcp==1.19.0 doesn't require pyjwt>=2.10.1
# By pinning MCP to 1.19.0 (matching upstream's uv.lock), we preserve ZhipuAI functionality
# See: https://github.com/MetaGLM/zhipuai-sdk-python-v4/issues/103
if grep -q 'mcp>=' pyproject.toml 2>/dev/null; then
msg_info "Pinning MCP version to 1.19.0 to preserve ZhipuAI compatibility"
sed -i 's/mcp>=1.23.0/mcp==1.19.0/' pyproject.toml
msg_ok "Pinned MCP to version 1.19.0"
fi
# Note: We do NOT remove agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
@@ -122,7 +119,7 @@ function update_script() {
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /root/.local/bin/uv sync --python 3.12 --frozen
$STD /root/.local/bin/uv sync --python 3.12 --frozen --index-strategy unsafe-best-match
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -18,9 +18,10 @@ update_os
# This script installs RAGFlow with all dependencies directly on the LXC container:
# - MariaDB (MySQL-compatible, metadata storage)
# - Elasticsearch 8.11 (document/vector search)
# - Redis/Valkey (caching)
# - Redis (caching)
# - MinIO (object storage)
# - Python 3.12 (backend)
# - Node.js 22 (frontend build)
# - Nginx (frontend reverse proxy)
# ==============================================================================
@@ -91,56 +92,35 @@ $STD apt-get install -y \
msg_ok "Installed Dependencies"
# ==============================================================================
# MARIADB INSTALLATION (MySQL-compatible)
# DATABASE SETUP (MariaDB)
# ==============================================================================
# Using MariaDB instead of MySQL to avoid expired GPG key issues on Debian 13+
# MariaDB is fully MySQL-compatible and works with RAGFlow
msg_info "Installing MariaDB (MySQL-compatible)"
$STD apt-get install -y mariadb-server mariadb-client
MARIADB_DB_NAME="rag_flow"
MARIADB_DB_USER="rag_flow"
setup_mariadb_db
# Wait for MariaDB to be ready
for i in {1..30}; do
if mysqladmin ping -h localhost --silent 2>/dev/null; then
break
fi
sleep 1
done
# Generate MariaDB credentials
MYSQL_RAGFLOW_USER="rag_flow"
MYSQL_RAGFLOW_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
MYSQL_RAGFLOW_DB="rag_flow"
msg_info "Creating MariaDB Database and User"
$STD mysql -u root -e "CREATE DATABASE \`${MYSQL_RAGFLOW_DB}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mysql -u root -e "CREATE USER '${MYSQL_RAGFLOW_USER}'@'localhost' IDENTIFIED BY '${MYSQL_RAGFLOW_PASS}';"
$STD mysql -u root -e "GRANT ALL PRIVILEGES ON \`${MYSQL_RAGFLOW_DB}\`.* TO '${MYSQL_RAGFLOW_USER}'@'localhost';"
$STD mysql -u root -e "FLUSH PRIVILEGES;"
# Increase max_allowed_packet for large documents
# Configure MariaDB for RAGFlow
msg_info "Configuring MariaDB for RAGFlow"
$STD mysql -u root -e "SET GLOBAL max_allowed_packet=1073741824;"
cat <<EOF >/etc/mysql/mariadb.conf.d/ragflow.cnf
[mysqld]
[mariadb]
max_allowed_packet=1073741824
max_connections=900
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
EOF
systemctl restart mariadb
msg_ok "MariaDB Configured"
msg_ok "Configured MariaDB"
# ==============================================================================
# REDIS INSTALLATION
# ==============================================================================
# Using Redis from Debian repos instead of Valkey to avoid external repo issues
msg_info "Installing Redis"
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
$STD apt-get install -y redis-server
# Configure Redis
cat <<EOF >/etc/redis/redis.conf
bind 127.0.0.1
port 6379
@@ -229,19 +209,16 @@ msg_ok "Elasticsearch Installed"
# ==============================================================================
msg_info "Installing MinIO"
MINIO_USER="rag_flow"
MINIO_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
# Download MinIO binary
curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio -o /usr/local/bin/minio
chmod +x /usr/local/bin/minio
# Create MinIO user and directories
useradd -r -s /bin/false minio-user 2>/dev/null || true
# Create MinIO directories
mkdir -p /var/lib/minio/data
chown -R minio-user:minio-user /var/lib/minio
# Create MinIO service
# Create MinIO service (run as root in LXC)
cat <<EOF >/etc/systemd/system/minio.service
[Unit]
Description=MinIO Object Storage
@@ -250,9 +227,7 @@ Wants=network-online.target
[Service]
Type=notify
User=minio-user
Group=minio-user
Environment="MINIO_ROOT_USER=${MINIO_USER}"
Environment="MINIO_ROOT_USER=rag_flow"
Environment="MINIO_ROOT_PASSWORD=${MINIO_PASS}"
Environment="MINIO_BROWSER=on"
ExecStart=/usr/local/bin/minio server /var/lib/minio/data --console-address ":9001"
@@ -264,7 +239,6 @@ LimitNOFILE=65535
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now minio
# Wait for MinIO to be ready
@@ -274,98 +248,26 @@ for i in {1..30}; do
fi
sleep 1
done
# Create bucket for RAGFlow
$STD curl -s -X PUT "http://localhost:9000/minio/health/live" || true
msg_ok "MinIO Installed"
# ==============================================================================
# RAGFLOW INSTALLATION
# ==============================================================================
msg_info "Downloading RAGFlow"
fetch_and_deploy_gh_release "ragflow" "infiniflow/ragflow" "tarball" "v0.24.0" "/opt/ragflow"
msg_ok "Downloaded RAGFlow"
# ==============================================================================
# PYTHON ENVIRONMENT
# ==============================================================================
PYTHON_VERSION="3.12" setup_uv
# Install jemalloc for memory management
$STD apt-get install -y libjemalloc-dev
# Clone RAGFlow repository
msg_info "Cloning RAGFlow Repository"
cd /opt || exit
$STD git clone --depth 1 https://github.com/infiniflow/ragflow.git ragflow
cd /opt/ragflow || exit
git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || echo "v0.24.0" > /opt/ragflow/version.txt
msg_ok "Cloned RAGFlow Repository"
# Fix: Replace gitee.com URLs with GitHub URLs
# RAGFlow's pyproject.toml and uv.lock may reference gitee.com which requires authentication
# We replace with GitHub mirror which is publicly accessible
if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_info "Replacing gitee.com URLs in pyproject.toml with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' pyproject.toml
msg_ok "Fixed graspologic URLs in pyproject.toml"
fi
if grep -q "gitee.com/infiniflow/graspologic" uv.lock 2>/dev/null; then
msg_info "Replacing gitee.com URLs in uv.lock with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' uv.lock
msg_ok "Fixed graspologic URLs in lock file"
fi
# Fix: Replace Chinese PyPI mirror with standard PyPI
# https://github.com/astral-sh/uv/issues/10462
# uv records index url into uv.lock but doesn't failover among multiple indexes
# RAGFlow uses pypi.tuna.tsinghua.edu.cn which may not have all packages
if grep -q "pypi.tuna.tsinghua.edu.cn" pyproject.toml 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' pyproject.toml
msg_ok "Fixed PyPI index URL in pyproject.toml"
fi
if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror in uv.lock with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' uv.lock
msg_ok "Fixed PyPI index URL in lock file"
fi
# Fix: Ensure Python version constraint matches upstream
# RAGFlow upstream uses requires-python = ">=3.12,<3.15"
# infinity-sdk requires Python >=3.11,<3.14
# The intersection is >=3.12,<3.14, but we keep upstream's constraint
# and rely on the lock file for correct resolution
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
# Only update if it doesn't match upstream
if ! grep -q 'requires-python = ">=3.12,<3.15"' pyproject.toml 2>/dev/null; then
msg_info "Updating Python version constraint to match upstream"
sed -i 's/requires-python\s*=.*/requires-python = ">=3.12,<3.15"/' pyproject.toml
msg_ok "Updated Python version constraint"
fi
fi
# ==============================================================================
# SDK EXCLUSION
# ==============================================================================
# Remove the ragflow_sdk package from pyproject.toml since we only need the
# server components. The SDK is a client library for connecting to RAGFlow
# from external applications, which is not needed for server-only installations.
msg_info "Excluding SDK Package from Installation"
if grep -q "sdk.python.ragflow_sdk" pyproject.toml 2>/dev/null; then
sed -i '/sdk.python.ragflow_sdk/d' pyproject.toml
msg_ok "Excluded ragflow_sdk from installation"
else
msg_ok "SDK package not found in pyproject.toml (already excluded or not present)"
fi
# Note: We do NOT remove zhipuai or agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
# Install Python dependencies using the upstream lock file
# The --frozen flag tells uv to use the lock file as-is without re-resolution
# This is the official RAGFlow installation method from their documentation
# Reference: https://ragflow.io/docs/launch_ragflow_from_source
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /usr/local/bin/uv sync --python 3.12 --frozen
$STD /usr/local/bin/uv sync --python 3.12 --frozen --index-strategy unsafe-best-match
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
@@ -375,10 +277,8 @@ msg_ok "Installed Python Dependencies"
msg_info "Creating RAGFlow Configuration"
# Create configuration directory
mkdir -p /opt/ragflow/conf /opt/ragflow/data /opt/ragflow/logs
# Create service configuration
cat <<EOF >/opt/ragflow/conf/service_conf.yaml
ragflow:
host: 0.0.0.0
@@ -387,16 +287,16 @@ admin:
host: 0.0.0.0
http_port: 9381
mysql:
name: '${MYSQL_RAGFLOW_DB}'
user: '${MYSQL_RAGFLOW_USER}'
password: '${MYSQL_RAGFLOW_PASS}'
name: 'rag_flow'
user: 'rag_flow'
password: '${MARIADB_DB_PASS}'
host: 'localhost'
port: 3306
max_connections: 900
stale_timeout: 300
max_allowed_packet: 1073741824
minio:
user: '${MINIO_USER}'
user: 'rag_flow'
password: '${MINIO_PASS}'
host: 'localhost:9000'
bucket: 'ragflow'
@@ -417,7 +317,6 @@ user_default_llm:
base_url: 'http://localhost:6380'
EOF
# Create environment file
cat <<EOF >/opt/ragflow/.env
DOC_ENGINE=elasticsearch
DEVICE=cpu
@@ -426,13 +325,13 @@ STACK_VERSION=8.11.3
ES_HOST=localhost
ES_PORT=9200
ELASTIC_PASSWORD=${ES_PASS}
MYSQL_PASSWORD=${MYSQL_RAGFLOW_PASS}
MYSQL_PASSWORD=${MARIADB_DB_PASS}
MYSQL_HOST=localhost
MYSQL_DBNAME=${MYSQL_RAGFLOW_DB}
MYSQL_DBNAME=rag_flow
MYSQL_PORT=3306
MINIO_HOST=localhost
MINIO_PORT=9000
MINIO_USER=${MINIO_USER}
MINIO_USER=rag_flow
MINIO_PASSWORD=${MINIO_PASS}
REDIS_HOST=localhost
REDIS_PORT=6379
@@ -456,7 +355,6 @@ msg_ok "Created RAGFlow Configuration"
msg_info "Creating Systemd Services"
# RAGFlow Backend Server
cat <<EOF >/etc/systemd/system/ragflow-server.service
[Unit]
Description=RAGFlow Backend Server
@@ -465,7 +363,6 @@ Requires=mariadb.service elasticsearch.service redis-server.service minio.servic
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ragflow
Environment=PYTHONPATH=/opt/ragflow
Environment=LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
@@ -481,7 +378,6 @@ LimitNOFILE=65535
WantedBy=multi-user.target
EOF
# RAGFlow Task Executor
cat <<EOF >/etc/systemd/system/ragflow-task-executor.service
[Unit]
Description=RAGFlow Task Executor
@@ -490,7 +386,6 @@ Requires=mariadb.service elasticsearch.service redis-server.service minio.servic
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ragflow
Environment=PYTHONPATH=/opt/ragflow
Environment=LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
@@ -505,7 +400,6 @@ LimitNOFILE=65535
WantedBy=multi-user.target
EOF
systemctl daemon-reload
msg_ok "Created Systemd Services"
# ==============================================================================
@@ -515,17 +409,16 @@ msg_ok "Created Systemd Services"
msg_info "Setting up Nginx Frontend"
$STD apt-get install -y nginx
# Build RAGFlow frontend from source (no Docker)
NODE_VERSION="22" setup_nodejs
msg_info "Building RAGFlow Frontend"
mkdir -p /var/www/ragflow
NODE_VERSION="22" setup_nodejs
cd /opt/ragflow/web || exit
$STD npm install
$STD npm run build
cp -r /opt/ragflow/web/dist/* /var/www/ragflow/
msg_ok "Built RAGFlow Frontend"
# Configure Nginx
cat <<EOF >/etc/nginx/sites-available/ragflow.conf
server {
listen 80 default_server;
@@ -585,36 +478,6 @@ $STD ln -sf /etc/nginx/sites-available/ragflow.conf /etc/nginx/sites-enabled/
$STD systemctl enable -q --now nginx
msg_ok "Nginx Frontend Configured"
# ==============================================================================
# SAVE CREDENTIALS
# ==============================================================================
msg_info "Saving Credentials"
cat <<EOF >~/ragflow.creds
RAGFlow Credentials
===================
MariaDB Database: ${MYSQL_RAGFLOW_DB}
MariaDB User: ${MYSQL_RAGFLOW_USER}
MariaDB Password: ${MYSQL_RAGFLOW_PASS}
Elasticsearch User: elastic
Elasticsearch Password: ${ES_PASS}
Redis Password: ${REDIS_PASS}
MinIO User: ${MINIO_USER}
MinIO Password: ${MINIO_PASS}
Web Interface: http://<IP>:80
API Endpoint: http://<IP>:9380
MinIO Console: http://<IP>:9001
Configuration: /opt/ragflow/conf/service_conf.yaml
Environment: /opt/ragflow/.env
EOF
chmod 600 ~/ragflow.creds
msg_ok "Saved Credentials"
# ==============================================================================
# START SERVICES
# ==============================================================================
@@ -634,12 +497,24 @@ customize
cleanup_lxc
msg_ok "Completed Successfully!\n"
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo -e "${CREATING}${GN}RAGFlow has been successfully installed!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:80${CL}"
echo -e "${INFO}${YW} API endpoint: http://${IP}:9380${CL}"
echo -e "${INFO}${YW} MinIO Console: http://${IP}:9001${CL}"
echo -e "${INFO}${YW} Credentials saved to: ~/ragflow.creds${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${LOCAL_IP}:80${CL}"
echo -e "${INFO}${YW} API endpoint: http://${LOCAL_IP}:9380${CL}"
echo -e "${INFO}${YW} MinIO Console: http://${LOCAL_IP}:9001${CL}"
echo -e ""
echo -e "${INFO}${YW} Credentials:${CL}"
echo -e "${TAB}- MariaDB User: rag_flow"
echo -e "${TAB}- MariaDB Password: ${MARIADB_DB_PASS}"
echo -e "${TAB}- Elasticsearch Password: ${ES_PASS}"
echo -e "${TAB}- Redis Password: ${REDIS_PASS}"
echo -e "${TAB}- MinIO User: rag_flow"
echo -e "${TAB}- MinIO Password: ${MINIO_PASS}"
echo -e ""
echo -e "${INFO}${YW} Configuration files:${CL}"
echo -e "${TAB}- /opt/ragflow/conf/service_conf.yaml"
echo -e "${TAB}- /opt/ragflow/.env"
echo -e ""
echo -e "${INFO}${YW} Important Notes:${CL}"
echo -e "${TAB}- Configure your LLM API key in the web interface"
@@ -16,7 +16,7 @@ msg_info "Installing Dependencies"
$STD apt-get install -y curl ca-certificates
msg_ok "Installed Dependencies"
GO_VERSION="1.24" setup_go
setup_go
fetch_and_deploy_gh_release "localrecall" "mudler/LocalRecall" "tarball" "latest" "/opt/localrecall"
@@ -311,15 +311,17 @@ if grep -q "gitee.com/infiniflow/graspologic" uv.lock 2>/dev/null; then
fi
# Fix: Replace Chinese PyPI mirror with standard PyPI
# https://github.com/astral-sh/uv/issues/10462
# uv records index url into uv.lock but doesn't failover among multiple indexes
# RAGFlow uses pypi.tuna.tsinghua.edu.cn which may not have all packages
if grep -q "pypi.tuna.tsinghua.edu.cn" pyproject.toml 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' pyproject.toml
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' pyproject.toml
msg_ok "Fixed PyPI index URL in pyproject.toml"
fi
if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror in uv.lock with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' uv.lock
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' uv.lock
msg_ok "Fixed PyPI index URL in lock file"
fi
@@ -337,6 +339,21 @@ if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
fi
fi
# ==============================================================================
# SDK EXCLUSION
# ==============================================================================
# Remove the ragflow_sdk package from pyproject.toml since we only need the
# server components. The SDK is a client library for connecting to RAGFlow
# from external applications, which is not needed for server-only installations.
msg_info "Excluding SDK Package from Installation"
if grep -q "sdk.python.ragflow_sdk" pyproject.toml 2>/dev/null; then
sed -i '/sdk.python.ragflow_sdk/d' pyproject.toml
msg_ok "Excluded ragflow_sdk from installation"
else
msg_ok "SDK package not found in pyproject.toml (already excluded or not present)"
fi
# Note: We do NOT remove zhipuai or agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
@@ -39,7 +39,7 @@ function update_script() {
msg_ok "Backed up Data"
msg_info "Updating LocalRecall"
GO_VERSION="1.24" setup_go
setup_go
fetch_and_deploy_gh_release "localrecall" "mudler/LocalRecall" "tarball" "latest" "/opt/localrecall"
cd /opt/localrecall || exit
$STD go build -o localrecall .
@@ -74,15 +74,17 @@ function update_script() {
fi
# Fix: Replace Chinese PyPI mirror with standard PyPI
# https://github.com/astral-sh/uv/issues/10462
# uv records index url into uv.lock but doesn't failover among multiple indexes
# RAGFlow uses pypi.tuna.tsinghua.edu.cn which may not have all packages
if grep -q "pypi.tuna.tsinghua.edu.cn" pyproject.toml 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' pyproject.toml
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' pyproject.toml
msg_ok "Fixed PyPI index URL in pyproject.toml"
fi
if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror in uv.lock with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' uv.lock
sed -i 's|pypi.tuna.tsinghua.edu.cn|pypi.org|g' uv.lock
msg_ok "Fixed PyPI index URL in lock file"
fi
@@ -100,6 +102,15 @@ function update_script() {
fi
fi
# Remove the ragflow_sdk package from pyproject.toml since we only need the
# server components. The SDK is a client library for connecting to RAGFlow
# from external applications, which is not needed for server-only installations.
if grep -q "sdk.python.ragflow_sdk" pyproject.toml 2>/dev/null; then
msg_info "Excluding SDK Package from Installation"
sed -i '/sdk.python.ragflow_sdk/d' pyproject.toml
msg_ok "Excluded ragflow_sdk from installation"
fi
# Note: We do NOT remove zhipuai or agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
@@ -1,5 +1,5 @@
{
"name": "LocalRecall (In Testing)",
"name": "LocalRecall (In Testing - Borked)",
"slug": "localrecall",
"categories": [20],
"date_created": "2026-03-14",
@@ -1,5 +1,5 @@
{
"name": "RAGFlow (In Testing)",
"name": "RAGFlow (In Testing - Borked)",
"slug": "ragflow",
"categories": [20],
"date_created": "2026-03-12",
@@ -0,0 +1,6 @@
__ __ ____
/ /___ _________ _/ /_______ _________ _/ / /
/ / __ \/ ___/ __ `/ / ___/ _ \/ ___/ __ `/ / /
/ / /_/ / /__/ /_/ / / / / __/ /__/ /_/ / / /
/_/\____/\___/\__,_/_/_/ \___/\___/\__,_/_/_/
@@ -86,57 +86,32 @@ function update_script() {
msg_ok "Fixed PyPI index URL in lock file"
fi
# Fix: Limit Python version to avoid dependency resolution issues
# zhipuai==2.0.1 has pyjwt<2.9.dev0 but mcp>=1.23.0 needs pyjwt>=2.10.1
# These are incompatible for Python 3.14+ on macOS, but we're on Linux with Python 3.12
# Limit requires-python to exclude Python 3.14+ to avoid this conflict
msg_info "Fixing Python version constraints"
# Read current requires-python and update it
# Fix: Ensure Python version constraint matches upstream
# RAGFlow upstream uses requires-python = ">=3.12,<3.15"
# infinity-sdk requires Python >=3.11,<3.14
# The intersection is >=3.12,<3.14, but we keep upstream's constraint
# and rely on the lock file for correct resolution
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
# Replace any requires-python with our constrained version
sed -i 's/requires-python\s*=.*/requires-python = ">=3.10,<3.14"/' pyproject.toml
msg_ok "Limited Python version range in pyproject.toml"
else
# Add requires-python if not present
sed -i '/^\[project\]/a requires-python = ">=3.10,<3.14"' pyproject.toml
msg_ok "Added Python version constraint to pyproject.toml"
# Only update if it doesn't match upstream
if ! grep -q 'requires-python = ">=3.12,<3.15"' pyproject.toml 2>/dev/null; then
msg_info "Updating Python version constraint to match upstream"
sed -i 's/requires-python\s*=.*/requires-python = ">=3.12,<3.15"/' pyproject.toml
msg_ok "Updated Python version constraint"
fi
fi
# Fix: Remove zhipuai dependency - it's incompatible with mcp>=1.23.0
# zhipuai has pyjwt<2.9.dev0 constraint which conflicts with mcp's pyjwt>=2.10.1
# zhipuai is only needed for ZhipuAI LLM provider, which is optional
if grep -q 'zhipuai' pyproject.toml 2>/dev/null; then
msg_info "Removing incompatible zhipuai dependency"
# Remove zhipuai from dependencies - it's an optional LLM provider
sed -i '/zhipuai/d' pyproject.toml
msg_ok "Removed zhipuai dependency"
fi
# Fix: Remove agentrun-sdk dependency - it's incompatible with crawl4ai
# agentrun-sdk requires alibabacloud-tea-openapi which needs cryptography<45.0.0
# but crawl4ai requires pyopenssl>=25.3.0 which needs cryptography>=45.0.7
# agentrun-sdk is only needed for Alibaba Cloud AgentRun, which is optional
if grep -q 'agentrun-sdk' pyproject.toml 2>/dev/null; then
msg_info "Removing incompatible agentrun-sdk dependency"
sed -i '/agentrun-sdk/d' pyproject.toml
msg_ok "Removed agentrun-sdk dependency"
fi
# Remove the lock file to force fresh dependency resolution
# This avoids issues with platform-specific markers in the existing lock
if [ -f "uv.lock" ]; then
msg_info "Removing existing lock file for fresh resolution"
rm -f uv.lock
msg_ok "Removed lock file"
fi
# Note: We do NOT remove zhipuai or agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
# Install Python dependencies using the upstream lock file
# The --frozen flag tells uv to use the lock file as-is without re-resolution
# This is the official RAGFlow installation method from their documentation
# Reference: https://ragflow.io/docs/launch_ragflow_from_source
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
# Use --prerelease=allow to allow pre-release versions if needed
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --prerelease=allow
$STD /root/.local/bin/uv sync --python 3.12 --frozen
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -1,9 +1,7 @@
{
"name": "RAGFlow",
"name": "RAGFlow (In Testing)",
"slug": "ragflow",
"categories": [
20
],
"categories": [20],
"date_created": "2026-03-12",
"type": "ct",
"updateable": true,
@@ -323,48 +323,32 @@ if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_ok "Fixed PyPI index URL in lock file"
fi
# Fix: Limit Python version to avoid dependency resolution issues
# zhipuai==2.0.1 has pyjwt<2.9.dev0 but mcp>=1.23.0 needs pyjwt>=2.10.1
# These are incompatible for Python 3.14+ on macOS, but we're on Linux with Python 3.12
# Limit requires-python to exclude Python 3.14+ to avoid this conflict
msg_info "Fixing Python version constraints"
# Read current requires-python and update it
# Fix: Ensure Python version constraint matches upstream
# RAGFlow upstream uses requires-python = ">=3.12,<3.15"
# infinity-sdk requires Python >=3.11,<3.14
# The intersection is >=3.12,<3.14, but we keep upstream's constraint
# and rely on the lock file for correct resolution
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
# Replace any requires-python with our constrained version
sed -i 's/requires-python\s*=.*/requires-python = ">=3.10,<3.14"/' pyproject.toml
msg_ok "Limited Python version range in pyproject.toml"
else
# Add requires-python if not present
sed -i '/^\[project\]/a requires-python = ">=3.10,<3.14"' pyproject.toml
msg_ok "Added Python version constraint to pyproject.toml"
# Only update if it doesn't match upstream
if ! grep -q 'requires-python = ">=3.12,<3.15"' pyproject.toml 2>/dev/null; then
msg_info "Updating Python version constraint to match upstream"
sed -i 's/requires-python\s*=.*/requires-python = ">=3.12,<3.15"/' pyproject.toml
msg_ok "Updated Python version constraint"
fi
fi
# Fix: Remove zhipuai dependency - it's incompatible with mcp>=1.23.0
# zhipuai has pyjwt<2.9.dev0 constraint which conflicts with mcp's pyjwt>=2.10.1
# zhipuai is only needed for ZhipuAI LLM provider, which is optional
if grep -q 'zhipuai' pyproject.toml 2>/dev/null; then
msg_info "Removing incompatible zhipuai dependency"
# Remove zhipuai from dependencies - it's an optional LLM provider
sed -i '/zhipuai/d' pyproject.toml
msg_ok "Removed zhipuai dependency"
fi
# Note: We do NOT remove zhipuai or agentrun-sdk from pyproject.toml
# These are resolved correctly in the upstream uv.lock file
# Removing them would require regenerating the lock file, which causes issues
# Remove the lock file to force fresh dependency resolution
# This avoids issues with platform-specific markers in the existing lock
if [ -f "uv.lock" ]; then
msg_info "Removing existing lock file for fresh resolution"
rm -f uv.lock
msg_ok "Removed lock file"
fi
# Install Python dependencies
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
# Use --prerelease=allow to allow pre-release versions if needed
# Install Python dependencies using the upstream lock file
# The --frozen flag tells uv to use the lock file as-is without re-resolution
# This is the official RAGFlow installation method from their documentation
# Reference: https://ragflow.io/docs/launch_ragflow_from_source
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --prerelease=allow
$STD /usr/local/bin/uv sync --python 3.12 --frozen
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/refs/heads/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL}"/misc/build.func)
# Author: BillyOutlast
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mudler/LocalRecall
APP="localrecall"
var_tags="${var_tags:-ai;rag;knowledge-base;vector-db}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/localrecall ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "localrecall" "mudler/LocalRecall"; then
msg_info "Stopping Service"
systemctl stop localrecall
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp -r /opt/localrecall/data /opt/localrecall_data_backup 2>/dev/null || true
msg_ok "Backed up Data"
msg_info "Updating LocalRecall"
GO_VERSION="1.24" setup_go
fetch_and_deploy_gh_release "localrecall" "mudler/LocalRecall" "tarball" "latest" "/opt/localrecall"
cd /opt/localrecall || exit
$STD go build -o localrecall .
mv localrecall /usr/local/bin/localrecall
cd / || exit
rm -rf /opt/localrecall
msg_ok "Updated LocalRecall"
msg_info "Restoring Data"
mkdir -p /opt/localrecall/data
mkdir -p /opt/localrecall/assets
cp -r /opt/localrecall_data_backup/. /opt/localrecall/data 2>/dev/null || true
rm -rf /opt/localrecall_data_backup
msg_ok "Restored Data"
msg_info "Starting Service"
systemctl start localrecall
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
@@ -0,0 +1,42 @@
{
"name": "LocalRecall",
"slug": "localrecall",
"categories": [20],
"date_created": "2026-03-14",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://github.com/mudler/LocalRecall#readme",
"website": "https://github.com/mudler/LocalRecall",
"logo": "https://raw.githubusercontent.com/mudler/LocalRecall/main/static/logo.png",
"config_path": "/opt/localrecall/.env",
"description": "A lightweight RESTful API for managing knowledge bases and files stored in vector databases. No GPU, internet, or cloud services required. Integrates with LocalAI for embeddings.",
"install_methods": [
{
"type": "default",
"script": "ct/localrecall.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Requires an embedding service (like LocalAI) for full functionality. Set OPENAI_BASE_URL environment variable to point to your embedding service.",
"type": "info"
},
{
"text": "Default configuration uses Chromem as the vector database engine. For PostgreSQL support, set VECTOR_ENGINE=postgres and DATABASE_URL environment variables.",
"type": "info"
}
]
}
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# Author: BillyOutlast
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mudler/LocalRecall
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y curl ca-certificates
msg_ok "Installed Dependencies"
GO_VERSION="1.24" setup_go
fetch_and_deploy_gh_release "localrecall" "mudler/LocalRecall" "tarball" "latest" "/opt/localrecall"
msg_info "Building LocalRecall"
cd /opt/localrecall || exit
$STD go build -o localrecall .
mv localrecall /usr/local/bin/localrecall
cd / || exit
rm -rf /opt/localrecall
msg_ok "Built LocalRecall"
msg_info "Setting Up Application"
mkdir -p /opt/localrecall/data
mkdir -p /opt/localrecall/assets
msg_ok "Set Up Application"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/localrecall.service
[Unit]
Description=LocalRecall - Knowledge Base Management API
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/localrecall
ExecStart=/usr/local/bin/localrecall
Restart=on-failure
RestartSec=5
Environment=COLLECTION_DB_PATH=/opt/localrecall/data
Environment=FILE_ASSETS=/opt/localrecall/assets
Environment=LISTENING_ADDRESS=:8080
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now localrecall
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
@@ -102,12 +102,24 @@ function update_script() {
msg_ok "Added Python version constraint to pyproject.toml"
fi
# Fix: Update zhipuai to a version compatible with newer pyjwt
# zhipuai>=2.0.2 supports pyjwt>=2.10.1 which is compatible with mcp>=1.23.0
# Fix: Remove zhipuai dependency - it's incompatible with mcp>=1.23.0
# zhipuai has pyjwt<2.9.dev0 constraint which conflicts with mcp's pyjwt>=2.10.1
# zhipuai is only needed for ZhipuAI LLM provider, which is optional
if grep -q 'zhipuai' pyproject.toml 2>/dev/null; then
msg_info "Updating zhipuai version constraint for pyjwt compatibility"
sed -i 's/zhipuai\s*=\s*"[^"]*"/zhipuai = ">=2.0.2"/' pyproject.toml
msg_ok "Updated zhipuai version constraint"
msg_info "Removing incompatible zhipuai dependency"
# Remove zhipuai from dependencies - it's an optional LLM provider
sed -i '/zhipuai/d' pyproject.toml
msg_ok "Removed zhipuai dependency"
fi
# Fix: Remove agentrun-sdk dependency - it's incompatible with crawl4ai
# agentrun-sdk requires alibabacloud-tea-openapi which needs cryptography<45.0.0
# but crawl4ai requires pyopenssl>=25.3.0 which needs cryptography>=45.0.7
# agentrun-sdk is only needed for Alibaba Cloud AgentRun, which is optional
if grep -q 'agentrun-sdk' pyproject.toml 2>/dev/null; then
msg_info "Removing incompatible agentrun-sdk dependency"
sed -i '/agentrun-sdk/d' pyproject.toml
msg_ok "Removed agentrun-sdk dependency"
fi
# Remove the lock file to force fresh dependency resolution
@@ -123,7 +135,8 @@ function update_script() {
export UV_SYSTEM_PYTHON=1
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux
# Use --prerelease=allow to allow pre-release versions if needed
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --prerelease=allow
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -339,15 +339,14 @@ else
msg_ok "Added Python version constraint to pyproject.toml"
fi
# Fix: Update zhipuai to a version compatible with newer pyjwt
# zhipuai 2.0.1 has pyjwt<2.9.dev0 which conflicts with mcp>=1.23.0 (needs pyjwt>=2.10.1)
# zhipuai>=2.1.0 has relaxed pyjwt requirements compatible with mcp
# Fix: Remove zhipuai dependency - it's incompatible with mcp>=1.23.0
# zhipuai has pyjwt<2.9.dev0 constraint which conflicts with mcp's pyjwt>=2.10.1
# zhipuai is only needed for ZhipuAI LLM provider, which is optional
if grep -q 'zhipuai' pyproject.toml 2>/dev/null; then
msg_info "Updating zhipuai version constraint for pyjwt compatibility"
# Match both "zhipuai==2.0.1" and "zhipuai = "2.0.1"" formats
sed -i 's/"zhipuai==[^"]*"/"zhipuai>=2.1.0"/g' pyproject.toml
sed -i 's/zhipuai\s*=\s*"[^"]*"/zhipuai = ">=2.1.0"/g' pyproject.toml
msg_ok "Updated zhipuai version constraint"
msg_info "Removing incompatible zhipuai dependency"
# Remove zhipuai from dependencies - it's an optional LLM provider
sed -i '/zhipuai/d' pyproject.toml
msg_ok "Removed zhipuai dependency"
fi
# Remove the lock file to force fresh dependency resolution
@@ -361,10 +360,11 @@ fi
# Install Python dependencies
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
# Use --prerelease=allow to allow pre-release versions if needed
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --prerelease=allow
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/refs/heads/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL}"/misc/build.func)
# Author: BillyOutlast
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mudler/LocalAI
APP="localai"
@@ -35,7 +35,7 @@ function update_script() {
systemctl stop localai
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "localai" "mudler/LocalAI" "prebuild" "local-ai"
fetch_and_deploy_gh_release "local-ai" "mudler/LocalAI" "singlefile" "latest" "/usr/local/bin" "local-ai-v*-linux-*"
msg_info "Starting Service"
systemctl start localai
@@ -102,13 +102,28 @@ function update_script() {
msg_ok "Added Python version constraint to pyproject.toml"
fi
# Fix: Update zhipuai to a version compatible with newer pyjwt
# zhipuai>=2.0.2 supports pyjwt>=2.10.1 which is compatible with mcp>=1.23.0
if grep -q 'zhipuai' pyproject.toml 2>/dev/null; then
msg_info "Updating zhipuai version constraint for pyjwt compatibility"
sed -i 's/zhipuai\s*=\s*"[^"]*"/zhipuai = ">=2.0.2"/' pyproject.toml
msg_ok "Updated zhipuai version constraint"
fi
# Remove the lock file to force fresh dependency resolution
# This avoids issues with platform-specific markers in the existing lock
if [ -f "uv.lock" ]; then
msg_info "Removing existing lock file for fresh resolution"
rm -f uv.lock
msg_ok "Removed lock file"
fi
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
# Use --resolution lowest-direct to avoid resolving optional dependency conflicts
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --resolution lowest-direct
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
$STD apt-get install -y curl
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "localai" "mudler/LocalAI" "prebuild" "local-ai"
fetch_and_deploy_gh_release "local-ai" "mudler/LocalAI" "singlefile" "latest" "/usr/local/bin" "local-ai-v*-linux-*"
msg_info "Setting Up Service"
mkdir -p /opt/localai/models
@@ -339,14 +339,32 @@ else
msg_ok "Added Python version constraint to pyproject.toml"
fi
# Fix: Update zhipuai to a version compatible with newer pyjwt
# zhipuai 2.0.1 has pyjwt<2.9.dev0 which conflicts with mcp>=1.23.0 (needs pyjwt>=2.10.1)
# zhipuai>=2.1.0 has relaxed pyjwt requirements compatible with mcp
if grep -q 'zhipuai' pyproject.toml 2>/dev/null; then
msg_info "Updating zhipuai version constraint for pyjwt compatibility"
# Match both "zhipuai==2.0.1" and "zhipuai = "2.0.1"" formats
sed -i 's/"zhipuai==[^"]*"/"zhipuai>=2.1.0"/g' pyproject.toml
sed -i 's/zhipuai\s*=\s*"[^"]*"/zhipuai = ">=2.1.0"/g' pyproject.toml
msg_ok "Updated zhipuai version constraint"
fi
# Remove the lock file to force fresh dependency resolution
# This avoids issues with platform-specific markers in the existing lock
if [ -f "uv.lock" ]; then
msg_info "Removing existing lock file for fresh resolution"
rm -f uv.lock
msg_ok "Removed lock file"
fi
# Install Python dependencies
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# Use --resolution lowest-direct to avoid resolving optional dependency conflicts
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --resolution lowest-direct
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: BillyOutlast
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mudler/LocalAI
APP="localai"
var_tags="${var_tags:-ai;llm;inference;openai-compatible}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-20}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/local-ai ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "localai" "mudler/LocalAI"; then
msg_info "Stopping Service"
systemctl stop localai
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "localai" "mudler/LocalAI" "prebuild" "local-ai"
msg_info "Starting Service"
systemctl start localai
msg_ok "Started Service"
msg_ok "Updated Successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
@@ -0,0 +1,50 @@
{
"name": "LocalAI",
"slug": "localai",
"categories": [20],
"date_created": "2026-03-14",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://localai.io/basics/getting_started/",
"website": "https://localai.io",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/localai.webp",
"config_path": "",
"description": "Free, Open Source OpenAI alternative for local AI inferencing. Self-hosted and local-first. Drop-in replacement, running on consumer-grade hardware. No GPU required. Runs gguf, transformers, diffusers and many more.",
"install_methods": [
{
"type": "default",
"script": "ct/localai.sh",
"resources": {
"cpu": 4,
"ram": 8192,
"hdd": 20,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Access the WebUI at http://SERVER_IP:8080",
"type": "info"
},
{
"text": "Models are stored in /opt/localai/models",
"type": "info"
},
{
"text": "OpenAI-compatible API endpoint available at http://SERVER_IP:8080/v1",
"type": "info"
},
{
"text": "GPU support is auto-detected at runtime (NVIDIA, AMD, Intel)",
"type": "info"
}
]
}
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: BillyOutlast
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mudler/LocalAI
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y curl
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "localai" "mudler/LocalAI" "prebuild" "local-ai"
msg_info "Setting Up Service"
mkdir -p /opt/localai/models
cat <<EOF >/etc/systemd/system/localai.service
[Unit]
Description=LocalAI - OpenAI-compatible local inference server
After=network.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/local-ai
Restart=on-failure
RestartSec=5
Environment=LOCALAI_MODELS_PATH=/opt/localai/models
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now localai
msg_ok "Set Up Service"
motd_ssh
customize
cleanup_lxc
@@ -86,11 +86,29 @@ function update_script() {
msg_ok "Fixed PyPI index URL in lock file"
fi
# Fix: Limit Python version to avoid dependency resolution issues
# zhipuai==2.0.1 has pyjwt<2.9.dev0 but mcp>=1.23.0 needs pyjwt>=2.10.1
# These are incompatible for Python 3.14+ on macOS, but we're on Linux with Python 3.12
# Limit requires-python to exclude Python 3.14+ to avoid this conflict
msg_info "Fixing Python version constraints"
# Read current requires-python and update it
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
# Replace any requires-python with our constrained version
sed -i 's/requires-python\s*=.*/requires-python = ">=3.10,<3.14"/' pyproject.toml
msg_ok "Limited Python version range in pyproject.toml"
else
# Add requires-python if not present
sed -i '/^\[project\]/a requires-python = ">=3.10,<3.14"' pyproject.toml
msg_ok "Added Python version constraint to pyproject.toml"
fi
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
# Use --resolution lowest-direct to avoid resolving optional dependency conflicts
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --resolution lowest-direct
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -325,26 +325,28 @@ fi
# Fix: Limit Python version to avoid dependency resolution issues
# zhipuai==2.0.1 has pyjwt<2.9.dev0 but mcp>=1.23.0 needs pyjwt>=2.10.1
# These are incompatible, but only for Python 3.14+ on macOS
# These are incompatible for Python 3.14+ on macOS, but we're on Linux with Python 3.12
# Limit requires-python to exclude Python 3.14+ to avoid this conflict
if grep -q 'requires-python.*3.14' pyproject.toml 2>/dev/null || grep -q 'requires-python.*>=3.10' pyproject.toml 2>/dev/null; then
msg_info "Limiting Python version range to avoid dependency conflicts"
# Replace broad Python version with specific range that excludes 3.14+
sed -i 's/requires-python\s*=\s*">=3\.10"/requires-python = ">=3.10,<3.14"/g' pyproject.toml
sed -i 's/requires-python\s*=\s*">=3\.11"/requires-python = ">=3.11,<3.14"/g' pyproject.toml
sed -i 's/requires-python\s*=\s*">=3\.12"/requires-python = ">=3.12,<3.14"/g' pyproject.toml
msg_info "Fixing Python version constraints"
# Read current requires-python and update it
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
# Replace any requires-python with our constrained version
sed -i 's/requires-python\s*=.*/requires-python = ">=3.10,<3.14"/' pyproject.toml
msg_ok "Limited Python version range in pyproject.toml"
else
# Add requires-python if not present
sed -i '/^\[project\]/a requires-python = ">=3.10,<3.14"' pyproject.toml
msg_ok "Added Python version constraint to pyproject.toml"
fi
# Install Python dependencies
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# This allows uv to find packages across different PyPI mirrors
# Use --resolution lowest-direct to avoid resolving optional dependency conflicts
# Use --python-platform linux to only resolve for Linux (skip macOS/Windows markers)
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match --python-platform linux --resolution lowest-direct
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
@@ -73,12 +73,24 @@ function update_script() {
msg_ok "Fixed graspologic URLs in lock file"
fi
# Fix: Replace Chinese PyPI mirror with standard PyPI
# RAGFlow uses pypi.tuna.tsinghua.edu.cn which may not have all packages
if grep -q "pypi.tuna.tsinghua.edu.cn" pyproject.toml 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' pyproject.toml
msg_ok "Fixed PyPI index URL in pyproject.toml"
fi
if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror in uv.lock with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' uv.lock
msg_ok "Fixed PyPI index URL in lock file"
fi
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
# Use --frozen to use pre-resolved versions from uv.lock
# This is how the official Dockerfile handles dependencies
$STD /root/.local/bin/uv sync --python 3.12 --frozen
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
$STD /root/.local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -296,25 +296,55 @@ cd /opt/ragflow || exit
git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || echo "v0.24.0" > /opt/ragflow/version.txt
msg_ok "Cloned RAGFlow Repository"
# Fix: Replace gitee.com URLs in uv.lock with GitHub URLs
# RAGFlow's uv.lock may reference gitee.com which requires authentication
# Fix: Replace gitee.com URLs with GitHub URLs
# RAGFlow's pyproject.toml and uv.lock may reference gitee.com which requires authentication
# We replace with GitHub mirror which is publicly accessible
# Note: We modify uv.lock, not pyproject.toml, to preserve the lock file integrity
if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_info "Replacing gitee.com URLs in pyproject.toml with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' pyproject.toml
msg_ok "Fixed graspologic URLs in pyproject.toml"
fi
if grep -q "gitee.com/infiniflow/graspologic" uv.lock 2>/dev/null; then
msg_info "Replacing gitee.com URLs in uv.lock with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' uv.lock
msg_ok "Fixed graspologic URLs in lock file"
fi
# Install Python dependencies using the lock file
# The --frozen flag tells uv to use exact versions from uv.lock without re-resolving
# This avoids dependency conflicts that occur during fresh resolution
# Fix: Replace Chinese PyPI mirror with standard PyPI
# RAGFlow uses pypi.tuna.tsinghua.edu.cn which may not have all packages
if grep -q "pypi.tuna.tsinghua.edu.cn" pyproject.toml 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' pyproject.toml
msg_ok "Fixed PyPI index URL in pyproject.toml"
fi
if grep -q "pypi.tuna.tsinghua.edu.cn" uv.lock 2>/dev/null; then
msg_info "Replacing Chinese PyPI mirror in uv.lock with standard PyPI"
sed -i 's|pypi.tuna.tsinghua.edu.cn/simple|pypi.org/simple|g' uv.lock
msg_ok "Fixed PyPI index URL in lock file"
fi
# Fix: Limit Python version to avoid dependency resolution issues
# zhipuai==2.0.1 has pyjwt<2.9.dev0 but mcp>=1.23.0 needs pyjwt>=2.10.1
# These are incompatible, but only for Python 3.14+ on macOS
# Limit requires-python to exclude Python 3.14+ to avoid this conflict
if grep -q 'requires-python.*3.14' pyproject.toml 2>/dev/null || grep -q 'requires-python.*>=3.10' pyproject.toml 2>/dev/null; then
msg_info "Limiting Python version range to avoid dependency conflicts"
# Replace broad Python version with specific range that excludes 3.14+
sed -i 's/requires-python\s*=\s*">=3\.10"/requires-python = ">=3.10,<3.14"/g' pyproject.toml
sed -i 's/requires-python\s*=\s*">=3\.11"/requires-python = ">=3.11,<3.14"/g' pyproject.toml
sed -i 's/requires-python\s*=\s*">=3\.12"/requires-python = ">=3.12,<3.14"/g' pyproject.toml
msg_ok "Limited Python version range in pyproject.toml"
fi
# Install Python dependencies
# Use --index-strategy unsafe-best-match to handle multi-index package resolution
# This allows uv to find packages across different PyPI mirrors
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
# Use --frozen to use pre-resolved versions from uv.lock
# This is how the official Dockerfile handles dependencies
$STD /usr/local/bin/uv sync --python 3.12 --frozen
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
@@ -464,25 +494,15 @@ msg_ok "Created Systemd Services"
msg_info "Setting up Nginx Frontend"
$STD apt-get install -y nginx
# Download RAGFlow frontend from Docker image
msg_info "Extracting RAGFlow Frontend"
# Build RAGFlow frontend from source (no Docker)
msg_info "Building RAGFlow Frontend"
mkdir -p /var/www/ragflow
cd /tmp || exit
# Pull and extract frontend from Docker image
if command -v docker &>/dev/null; then
$STD docker pull infiniflow/ragflow:v0.24.0
$STD docker create --name ragflow-temp infiniflow/ragflow:v0.24.0
$STD docker cp ragflow-temp:/ragflow/web /var/www/ragflow/
$STD docker rm ragflow-temp
else
# Fallback: clone and build frontend
NODE_VERSION="22" setup_nodejs
cd /opt/ragflow/web || exit
$STD npm install || exit
$STD npm run build
cp -r /opt/ragflow/web/dist/* /var/www/ragflow/
fi
NODE_VERSION="22" setup_nodejs
cd /opt/ragflow/web || exit
$STD npm install
$STD npm run build
cp -r /opt/ragflow/web/dist/* /var/www/ragflow/
msg_ok "Built RAGFlow Frontend"
# Configure Nginx
cat <<EOF >/etc/nginx/sites-available/ragflow.conf
@@ -296,58 +296,26 @@ cd /opt/ragflow || exit
git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || echo "v0.24.0" > /opt/ragflow/version.txt
msg_ok "Cloned RAGFlow Repository"
# Fix: Replace gitee.com graspologic dependency with GitHub version
# RAGFlow's pyproject.toml references a gitee.com fork that requires authentication
# We replace it with the GitHub mirror which is publicly accessible
if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_info "Replacing gitee.com graspologic dependency with GitHub version"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' pyproject.toml
msg_ok "Fixed graspologic dependency"
# Fix: Replace gitee.com URLs in uv.lock with GitHub URLs
# RAGFlow's uv.lock may reference gitee.com which requires authentication
# We replace with GitHub mirror which is publicly accessible
# Note: We modify uv.lock, not pyproject.toml, to preserve the lock file integrity
if grep -q "gitee.com/infiniflow/graspologic" uv.lock 2>/dev/null; then
msg_info "Replacing gitee.com URLs in uv.lock with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' uv.lock
msg_ok "Fixed graspologic URLs in lock file"
fi
# Fix: Limit Python version to avoid dependency resolution for future Python versions
# RAGFlow's dependencies have conflicts when resolving for Python 3.14+
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
sed -i 's/requires-python.*/requires-python = ">=3.10,<3.13"/' pyproject.toml
else
sed -i '/^\[project\]/a requires-python = ">=3.10,<3.13"' pyproject.toml
fi
# Add uv environments configuration to limit to Linux x86_64 only
# This avoids dependency resolution conflicts on macOS/Darwin and ARM64
if ! grep -q 'tool.uv.environments' pyproject.toml 2>/dev/null; then
cat >> pyproject.toml << 'UVENV'
[tool.uv]
environments = ["sys_platform == 'linux' and platform_machine == 'x86_64'"]
UVENV
fi
# Fix: Resolve PyJWT dependency conflict between zhipuai and mcp
# zhipuai==2.0.1 requires pyjwt>=2.8.0,<2.9.dev0
# mcp>=1.23.0 requires pyjwt[crypto]>=2.10.1
# These constraints are mutually exclusive, so we override PyJWT to satisfy mcp
# Reference: https://github.com/infiniflow/ragflow/issues/4499
if ! grep -q 'tool.uv.override-dependencies' pyproject.toml 2>/dev/null; then
msg_info "Adding dependency overrides for PyJWT conflict resolution"
cat >> pyproject.toml << 'OVERRIDE'
[tool.uv.override-dependencies]
# Force PyJWT version that satisfies mcp's requirement (>=2.10.1)
# zhipuai's constraint (<2.9.dev0) is overly restrictive and works with newer PyJWT
pyjwt = ">=2.10.1"
OVERRIDE
msg_ok "Added dependency overrides"
fi
# Install Python dependencies
# Install Python dependencies using the lock file
# The --frozen flag tells uv to use exact versions from uv.lock without re-resolving
# This avoids dependency conflicts that occur during fresh resolution
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
# Use --index-strategy unsafe-best-match to handle multiple PyPI indexes
# and avoid dependency resolution issues with mirrors
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match
$STD /usr/local/bin/uv run --index-strategy unsafe-best-match download_deps.py
# Use --frozen to use pre-resolved versions from uv.lock
# This is how the official Dockerfile handles dependencies
$STD /usr/local/bin/uv sync --python 3.12 --frozen
$STD /usr/local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
# ==============================================================================
@@ -29,7 +29,7 @@ function update_script() {
exit
fi
cd /opt/ragflow
cd /opt/ragflow || exit
LOCAL_VERSION=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
REMOTE_VERSION=$(git ls-remote origin HEAD 2>/dev/null | awk '{print $1}' || echo "unknown")
@@ -59,10 +59,26 @@ function update_script() {
$STD git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || true
msg_ok "Updated ${APP}"
# Fix: Replace gitee.com URLs with GitHub URLs
# RAGFlow's pyproject.toml and uv.lock may reference gitee.com which requires authentication
# We replace with GitHub mirror which is publicly accessible
if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_info "Replacing gitee.com URLs in pyproject.toml with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' pyproject.toml
msg_ok "Fixed graspologic URLs in pyproject.toml"
fi
if grep -q "gitee.com/infiniflow/graspologic" uv.lock 2>/dev/null; then
msg_info "Replacing gitee.com URLs in uv.lock with GitHub"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' uv.lock
msg_ok "Fixed graspologic URLs in lock file"
fi
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow
cd /opt/ragflow || exit
export UV_SYSTEM_PYTHON=1
$STD /root/.local/bin/uv sync --python 3.12
# Use --frozen to use pre-resolved versions from uv.lock
# This is how the official Dockerfile handles dependencies
$STD /root/.local/bin/uv sync --python 3.12 --frozen
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
@@ -305,6 +305,41 @@ if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_ok "Fixed graspologic dependency"
fi
# Fix: Limit Python version to avoid dependency resolution for future Python versions
# RAGFlow's dependencies have conflicts when resolving for Python 3.14+
if grep -q 'requires-python' pyproject.toml 2>/dev/null; then
sed -i 's/requires-python.*/requires-python = ">=3.10,<3.13"/' pyproject.toml
else
sed -i '/^\[project\]/a requires-python = ">=3.10,<3.13"' pyproject.toml
fi
# Add uv environments configuration to limit to Linux x86_64 only
# This avoids dependency resolution conflicts on macOS/Darwin and ARM64
if ! grep -q 'tool.uv.environments' pyproject.toml 2>/dev/null; then
cat >> pyproject.toml << 'UVENV'
[tool.uv]
environments = ["sys_platform == 'linux' and platform_machine == 'x86_64'"]
UVENV
fi
# Fix: Resolve PyJWT dependency conflict between zhipuai and mcp
# zhipuai==2.0.1 requires pyjwt>=2.8.0,<2.9.dev0
# mcp>=1.23.0 requires pyjwt[crypto]>=2.10.1
# These constraints are mutually exclusive, so we override PyJWT to satisfy mcp
# Reference: https://github.com/infiniflow/ragflow/issues/4499
if ! grep -q 'tool.uv.override-dependencies' pyproject.toml 2>/dev/null; then
msg_info "Adding dependency overrides for PyJWT conflict resolution"
cat >> pyproject.toml << 'OVERRIDE'
[tool.uv.override-dependencies]
# Force PyJWT version that satisfies mcp's requirement (>=2.10.1)
# zhipuai's constraint (<2.9.dev0) is overly restrictive and works with newer PyJWT
pyjwt = ">=2.10.1"
OVERRIDE
msg_ok "Added dependency overrides"
fi
# Install Python dependencies
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
@@ -16,7 +16,7 @@ update_os
# RAGFlow Bare-Metal Installation Script
# ==============================================================================
# This script installs RAGFlow with all dependencies directly on the LXC container:
# - MySQL 8.0 (metadata storage)
# - MariaDB (MySQL-compatible, metadata storage)
# - Elasticsearch 8.11 (document/vector search)
# - Redis/Valkey (caching)
# - MinIO (object storage)
@@ -91,12 +91,15 @@ $STD apt-get install -y \
msg_ok "Installed Dependencies"
# ==============================================================================
# MYSQL INSTALLATION
# MARIADB INSTALLATION (MySQL-compatible)
# ==============================================================================
# Using MariaDB instead of MySQL to avoid expired GPG key issues on Debian 13+
# MariaDB is fully MySQL-compatible and works with RAGFlow
MYSQL_VERSION="8.0" setup_mysql
msg_info "Installing MariaDB (MySQL-compatible)"
$STD apt-get install -y mariadb-server mariadb-client
# Wait for MySQL to be ready
# Wait for MariaDB to be ready
for i in {1..30}; do
if mysqladmin ping -h localhost --silent 2>/dev/null; then
break
@@ -104,12 +107,12 @@ for i in {1..30}; do
sleep 1
done
# Generate MySQL credentials
# Generate MariaDB credentials
MYSQL_RAGFLOW_USER="rag_flow"
MYSQL_RAGFLOW_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
MYSQL_RAGFLOW_DB="rag_flow"
msg_info "Creating MySQL Database and User"
msg_info "Creating MariaDB Database and User"
$STD mysql -u root -e "CREATE DATABASE \`${MYSQL_RAGFLOW_DB}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mysql -u root -e "CREATE USER '${MYSQL_RAGFLOW_USER}'@'localhost' IDENTIFIED BY '${MYSQL_RAGFLOW_PASS}';"
$STD mysql -u root -e "GRANT ALL PRIVILEGES ON \`${MYSQL_RAGFLOW_DB}\`.* TO '${MYSQL_RAGFLOW_USER}'@'localhost';"
@@ -117,31 +120,28 @@ $STD mysql -u root -e "FLUSH PRIVILEGES;"
# Increase max_allowed_packet for large documents
$STD mysql -u root -e "SET GLOBAL max_allowed_packet=1073741824;"
cat <<EOF >/etc/mysql/mysql.conf.d/ragflow.cnf
cat <<EOF >/etc/mysql/mariadb.conf.d/ragflow.cnf
[mysqld]
max_allowed_packet=1073741824
max_connections=900
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
EOF
systemctl restart mysql
msg_ok "MySQL Configured"
systemctl restart mariadb
msg_ok "MariaDB Configured"
# ==============================================================================
# REDIS/VALKEY INSTALLATION
# REDIS INSTALLATION
# ==============================================================================
# Using Redis from Debian repos instead of Valkey to avoid external repo issues
msg_info "Installing Valkey (Redis-compatible)"
msg_info "Installing Redis"
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
# Add Valkey repository
curl -fsSL https://packages.valkey.io/pubkey.gpg | gpg --dearmor -o /usr/share/keyrings/valkey.gpg
echo "deb [signed-by=/usr/share/keyrings/valkey.gpg] https://packages.valkey.io/valkey/debian $(lsb_release -cs) main" >/etc/apt/sources.list.d/valkey.list
$STD apt-get update
$STD apt-get install -y valkey
$STD apt-get install -y redis-server
# Configure Valkey
cat <<EOF >/etc/valkey/valkey.conf
# Configure Redis
cat <<EOF >/etc/redis/redis.conf
bind 127.0.0.1
port 6379
requirepass ${REDIS_PASS}
@@ -149,15 +149,15 @@ maxmemory 2gb
maxmemory-policy allkeys-lru
daemonize no
supervised systemd
logfile /var/log/valkey/valkey.log
dir /var/lib/valkey
logfile /var/log/redis/redis-server.log
dir /var/lib/redis
EOF
mkdir -p /var/log/valkey /var/lib/valkey
chown -R valkey:valkey /var/log/valkey /var/lib/valkey
mkdir -p /var/log/redis
chown -R redis:redis /var/log/redis /var/lib/redis
systemctl enable -q --now valkey
msg_ok "Valkey Installed"
systemctl enable -q --now redis-server
msg_ok "Redis Installed"
# ==============================================================================
# ELASTICSEARCH INSTALLATION
@@ -291,17 +291,28 @@ $STD apt-get install -y libjemalloc-dev
# Clone RAGFlow repository
msg_info "Cloning RAGFlow Repository"
cd /opt || exit
$STD gi || exitt clone --depth 1 https://github.com/infiniflow/ragflow.git ragflow
$STD git clone --depth 1 https://github.com/infiniflow/ragflow.git ragflow
cd /opt/ragflow || exit
git describe -- || exittags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || echo "v0.24.0" > /opt/ragflow/version.txt
git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || echo "v0.24.0" > /opt/ragflow/version.txt
msg_ok "Cloned RAGFlow Repository"
# Fix: Replace gitee.com graspologic dependency with GitHub version
# RAGFlow's pyproject.toml references a gitee.com fork that requires authentication
# We replace it with the GitHub mirror which is publicly accessible
if grep -q "gitee.com/infiniflow/graspologic" pyproject.toml 2>/dev/null; then
msg_info "Replacing gitee.com graspologic dependency with GitHub version"
sed -i 's|gitee.com/infiniflow/graspologic|github.com/infiniflow/graspologic|g' pyproject.toml
msg_ok "Fixed graspologic dependency"
fi
# Install Python dependencies
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTE || exitM_PYTHON=1
$STD /root/.local/bin/uv sync --python 3.12
$STD /root/.local/bin/uv run download_deps.py
export UV_SYSTEM_PYTHON=1
# Use --index-strategy unsafe-best-match to handle multiple PyPI indexes
# and avoid dependency resolution issues with mirrors
$STD /usr/local/bin/uv sync --python 3.12 --index-strategy unsafe-best-match
$STD /usr/local/bin/uv run --index-strategy unsafe-best-match download_deps.py
msg_ok "Installed Python Dependencies"
# ==============================================================================
@@ -395,8 +406,8 @@ msg_info "Creating Systemd Services"
cat <<EOF >/etc/systemd/system/ragflow-server.service
[Unit]
Description=RAGFlow Backend Server
After=network.target mysql.service elasticsearch.service valkey.service minio.service
Requires=mysql.service elasticsearch.service valkey.service minio.service
After=network.target mariadb.service elasticsearch.service redis-server.service minio.service
Requires=mariadb.service elasticsearch.service redis-server.service minio.service
[Service]
Type=simple
@@ -406,7 +417,7 @@ Environment=PYTHONPATH=/opt/ragflow
Environment=LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
Environment=NLTK_DATA=/opt/ragflow/nltk_data
ExecStartPre=/bin/sleep 10
ExecStart=/root/.local/bin/uv run python api/ragflow_server.py
ExecStart=/usr/local/bin/uv run --index-strategy unsafe-best-match python api/ragflow_server.py
Restart=on-failure
RestartSec=10
TimeoutStartSec=300
@@ -420,8 +431,8 @@ EOF
cat <<EOF >/etc/systemd/system/ragflow-task-executor.service
[Unit]
Description=RAGFlow Task Executor
After=network.target mysql.service elasticsearch.service valkey.service minio.service ragflow-server.service
Requires=mysql.service elasticsearch.service valkey.service minio.service
After=network.target mariadb.service elasticsearch.service redis-server.service minio.service ragflow-server.service
Requires=mariadb.service elasticsearch.service redis-server.service minio.service
[Service]
Type=simple
@@ -430,7 +441,7 @@ WorkingDirectory=/opt/ragflow
Environment=PYTHONPATH=/opt/ragflow
Environment=LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
Environment=NLTK_DATA=/opt/ragflow/nltk_data
ExecStart=/root/.local/bin/uv run python rag/svr/task_executor.py 0
ExecStart=/usr/local/bin/uv run --index-strategy unsafe-best-match python rag/svr/task_executor.py 0
Restart=on-failure
RestartSec=10
TimeoutStartSec=300
@@ -464,7 +475,7 @@ if command -v docker &>/dev/null; then
else
# Fallback: clone and build frontend
NODE_VERSION="22" setup_nodejs
cd /opt/ragflow/web
cd /opt/ragflow/web || exit
$STD npm install || exit
$STD npm run build
cp -r /opt/ragflow/web/dist/* /var/www/ragflow/
@@ -538,9 +549,9 @@ msg_info "Saving Credentials"
cat <<EOF >~/ragflow.creds
RAGFlow Credentials
===================
MySQL Database: ${MYSQL_RAGFLOW_DB}
MySQL User: ${MYSQL_RAGFLOW_USER}
MySQL Password: ${MYSQL_RAGFLOW_PASS}
MariaDB Database: ${MYSQL_RAGFLOW_DB}
MariaDB User: ${MYSQL_RAGFLOW_USER}
MariaDB Password: ${MYSQL_RAGFLOW_PASS}
Elasticsearch User: elastic
Elasticsearch Password: ${ES_PASS}
@@ -0,0 +1,91 @@
#!/usr/bin/env bash
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/refs/heads/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL}"/misc/build.func)
# Author: BillyOutlast
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/infiniflow/ragflow
APP="RAGFlow"
var_tags="${var_tags:-ai;rag;llm;knowledge-base}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-16384}"
var_disk="${var_disk:-50}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/ragflow ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
cd /opt/ragflow
LOCAL_VERSION=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
REMOTE_VERSION=$(git ls-remote origin HEAD 2>/dev/null | awk '{print $1}' || echo "unknown")
if [[ "$LOCAL_VERSION" == "$REMOTE_VERSION" ]] || [[ "$REMOTE_VERSION" == "unknown" ]]; then
if [[ "$REMOTE_VERSION" == "unknown" ]]; then
msg_info "Unable to check for updates. Checking local version..."
CURRENT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "unknown")
msg_info "Current version: ${CURRENT_TAG}"
fi
msg_info "No update required. ${APP} is already up to date."
exit 0
fi
msg_info "Stopping Services"
systemctl stop ragflow-task-executor || true
systemctl stop ragflow-server || true
msg_ok "Stopped Services"
msg_info "Backing up Data"
cp -r /opt/ragflow/conf /opt/ragflow_conf_backup
cp -r /opt/ragflow/data /opt/ragflow_data_backup 2>/dev/null || true
msg_ok "Backed up Data"
msg_info "Updating ${APP}"
$STD git fetch origin
$STD git reset --hard origin/main
$STD git describe --tags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || true
msg_ok "Updated ${APP}"
msg_info "Reinstalling Python Dependencies"
cd /opt/ragflow
export UV_SYSTEM_PYTHON=1
$STD /root/.local/bin/uv sync --python 3.12
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Reinstalled Python Dependencies"
msg_info "Restoring Configuration"
cp -r /opt/ragflow_conf_backup/. /opt/ragflow/conf/
rm -rf /opt/ragflow_conf_backup /opt/ragflow_data_backup
msg_ok "Restored Configuration"
msg_info "Starting Services"
systemctl start ragflow-server
systemctl start ragflow-task-executor
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:80${CL}"
echo -e "${INFO}${YW} API endpoint: http://${IP}:9380${CL}"
@@ -0,0 +1,80 @@
{
"name": "RAGFlow",
"slug": "ragflow",
"categories": [
20
],
"date_created": "2026-03-12",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://ragflow.io/docs/dev/",
"website": "https://ragflow.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ragflow.webp",
"config_path": "/opt/ragflow/conf/service_conf.yaml",
"description": "RAGFlow is an open-source RAG (Retrieval-Augmented Generation) engine with deep document understanding. It provides a streamlined RAG workflow for businesses of any scale, combining LLM capabilities to provide truthful question-answering with well-founded citations from various complex formatted data.",
"install_methods": [
{
"type": "default",
"script": "ct/ragflow.sh",
"resources": {
"cpu": 4,
"ram": 16384,
"hdd": 50,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Access the Web UI at http://<IP>:80",
"type": "info"
},
{
"text": "API endpoint: http://<IP>:9380",
"type": "info"
},
{
"text": "MinIO Console: http://<IP>:9001",
"type": "info"
},
{
"text": "Credentials saved to ~/ragflow.creds after installation",
"type": "info"
},
{
"text": "Configure your LLM API key in Settings after first login",
"type": "warning"
},
{
"text": "Requires vm.max_map_count >= 262144 (configured automatically)",
"type": "warning"
},
{
"text": "Elasticsearch may take 1-2 minutes to fully initialize on first start",
"type": "info"
},
{
"text": "Default installation uses CPU for document processing",
"type": "info"
},
{
"text": "For GPU acceleration, additional configuration is required",
"type": "info"
},
{
"text": "Services: MySQL, Elasticsearch, Redis/Valkey, MinIO, RAGFlow Backend",
"type": "info"
},
{
"text": "Minimum 16GB RAM recommended for production workloads",
"type": "warning"
}
]
}
@@ -0,0 +1,593 @@
#!/usr/bin/env bash
# Author: BillyOutlast
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/infiniflow/ragflow
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
# ==============================================================================
# RAGFlow Bare-Metal Installation Script
# ==============================================================================
# This script installs RAGFlow with all dependencies directly on the LXC container:
# - MySQL 8.0 (metadata storage)
# - Elasticsearch 8.11 (document/vector search)
# - Redis/Valkey (caching)
# - MinIO (object storage)
# - Python 3.12 (backend)
# - Nginx (frontend reverse proxy)
# ==============================================================================
# ==============================================================================
# SYSTEM PREPARATION
# ==============================================================================
msg_info "Configuring System Parameters for Elasticsearch"
# Elasticsearch requires vm.max_map_count >= 262144
if [[ $(sysctl -n vm.max_map_count) -lt 262144 ]]; then
sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" >>/etc/sysctl.conf
fi
msg_ok "Configured System Parameters"
# ==============================================================================
# DEPENDENCIES INSTALLATION
# ==============================================================================
msg_info "Installing Dependencies"
$STD apt-get install -y \
curl \
wget \
git \
gnupg \
apt-transport-https \
ca-certificates \
lsb-release \
build-essential \
libjemalloc-dev \
pkg-config \
libmariadb-dev \
libmariadb-dev-compat \
default-libmysqlclient-dev \
libpq-dev \
libssl-dev \
libffi-dev \
libxml2-dev \
libxslt1-dev \
libjpeg-dev \
libpng-dev \
zlib1g-dev \
libtiff-dev \
libfreetype6-dev \
liblcms2-dev \
libwebp-dev \
libharfbuzz-dev \
libfribidi-dev \
libxcb1-dev \
libgl1 \
libglib2.0-dev \
libopenblas-dev \
liblapack-dev \
gfortran \
ffmpeg \
poppler-utils \
tesseract-ocr \
tesseract-ocr-eng \
tesseract-ocr-chi-sim \
libreoffice-writer \
libreoffice-calc \
libreoffice-impress \
antiword \
catdoc \
html2text \
unrtf \
pandoc
msg_ok "Installed Dependencies"
# ==============================================================================
# MYSQL INSTALLATION
# ==============================================================================
MYSQL_VERSION="8.0" setup_mysql
# Wait for MySQL to be ready
for i in {1..30}; do
if mysqladmin ping -h localhost --silent 2>/dev/null; then
break
fi
sleep 1
done
# Generate MySQL credentials
MYSQL_RAGFLOW_USER="rag_flow"
MYSQL_RAGFLOW_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
MYSQL_RAGFLOW_DB="rag_flow"
msg_info "Creating MySQL Database and User"
$STD mysql -u root -e "CREATE DATABASE \`${MYSQL_RAGFLOW_DB}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mysql -u root -e "CREATE USER '${MYSQL_RAGFLOW_USER}'@'localhost' IDENTIFIED BY '${MYSQL_RAGFLOW_PASS}';"
$STD mysql -u root -e "GRANT ALL PRIVILEGES ON \`${MYSQL_RAGFLOW_DB}\`.* TO '${MYSQL_RAGFLOW_USER}'@'localhost';"
$STD mysql -u root -e "FLUSH PRIVILEGES;"
# Increase max_allowed_packet for large documents
$STD mysql -u root -e "SET GLOBAL max_allowed_packet=1073741824;"
cat <<EOF >/etc/mysql/mysql.conf.d/ragflow.cnf
[mysqld]
max_allowed_packet=1073741824
max_connections=900
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
EOF
systemctl restart mysql
msg_ok "MySQL Configured"
# ==============================================================================
# REDIS/VALKEY INSTALLATION
# ==============================================================================
msg_info "Installing Valkey (Redis-compatible)"
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
# Add Valkey repository
curl -fsSL https://packages.valkey.io/pubkey.gpg | gpg --dearmor -o /usr/share/keyrings/valkey.gpg
echo "deb [signed-by=/usr/share/keyrings/valkey.gpg] https://packages.valkey.io/valkey/debian $(lsb_release -cs) main" >/etc/apt/sources.list.d/valkey.list
$STD apt-get update
$STD apt-get install -y valkey
# Configure Valkey
cat <<EOF >/etc/valkey/valkey.conf
bind 127.0.0.1
port 6379
requirepass ${REDIS_PASS}
maxmemory 2gb
maxmemory-policy allkeys-lru
daemonize no
supervised systemd
logfile /var/log/valkey/valkey.log
dir /var/lib/valkey
EOF
mkdir -p /var/log/valkey /var/lib/valkey
chown -R valkey:valkey /var/log/valkey /var/lib/valkey
systemctl enable -q --now valkey
msg_ok "Valkey Installed"
# ==============================================================================
# ELASTICSEARCH INSTALLATION
# ==============================================================================
msg_info "Installing Elasticsearch 8.11"
ES_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
# Add Elasticsearch repository
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" >/etc/apt/sources.list.d/elasticsearch.list
$STD apt-get update
$STD apt-get install -y elasticsearch=8.11.3
# Configure Elasticsearch for single-node
cat <<EOF >/etc/elasticsearch/elasticsearch.yml
cluster.name: ragflow-cluster
node.name: ragflow-node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node
xpack.security.enabled: true
xpack.security.enrollment.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.license.self_generated.type: basic
indices.query.bool.max_clause_count: 262144
search.max_buckets: 100000
EOF
# Configure JVM heap (use 4GB for 16GB+ RAM systems)
ES_HEAP="4g"
if [[ $(free -m | awk '/Mem:/ {print $2}') -lt 16384 ]]; then
ES_HEAP="2g"
fi
echo "-Xms${ES_HEAP}" >/etc/elasticsearch/jvm.options.d/heap.options
echo "-Xmx${ES_HEAP}" >>/etc/elasticsearch/jvm.options.d/heap.options
# Configure system limits for Elasticsearch
cat <<EOF >/etc/security/limits.d/elasticsearch.conf
elasticsearch soft nofile 65535
elasticsearch hard nofile 65535
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
EOF
# Create data and log directories
mkdir -p /var/lib/elasticsearch /var/log/elasticsearch
chown -R elasticsearch:elasticsearch /var/lib/elasticsearch /var/log/elasticsearch
systemctl enable -q --now elasticsearch
# Wait for Elasticsearch to be ready
for i in {1..60}; do
if curl -s http://localhost:9200/_cluster/health 2>/dev/null | grep -q '"status"'; then
break
fi
sleep 2
done
# Set Elasticsearch password
echo -e "${ES_PASS}\n${ES_PASS}" | $STD /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i -b 2>/dev/null || true
msg_ok "Elasticsearch Installed"
# ==============================================================================
# MINIO INSTALLATION
# ==============================================================================
msg_info "Installing MinIO"
MINIO_USER="rag_flow"
MINIO_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
# Download MinIO binary
curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio -o /usr/local/bin/minio
chmod +x /usr/local/bin/minio
# Create MinIO user and directories
useradd -r -s /bin/false minio-user 2>/dev/null || true
mkdir -p /var/lib/minio/data
chown -R minio-user:minio-user /var/lib/minio
# Create MinIO service
cat <<EOF >/etc/systemd/system/minio.service
[Unit]
Description=MinIO Object Storage
After=network.target
Wants=network-online.target
[Service]
Type=notify
User=minio-user
Group=minio-user
Environment="MINIO_ROOT_USER=${MINIO_USER}"
Environment="MINIO_ROOT_PASSWORD=${MINIO_PASS}"
Environment="MINIO_BROWSER=on"
ExecStart=/usr/local/bin/minio server /var/lib/minio/data --console-address ":9001"
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now minio
# Wait for MinIO to be ready
for i in {1..30}; do
if curl -s http://localhost:9000/minio/health/live 2>/dev/null | grep -q .; then
break
fi
sleep 1
done
# Create bucket for RAGFlow
$STD curl -s -X PUT "http://localhost:9000/minio/health/live" || true
msg_ok "MinIO Installed"
# ==============================================================================
# PYTHON ENVIRONMENT
# ==============================================================================
PYTHON_VERSION="3.12" setup_uv
# Install jemalloc for memory management
$STD apt-get install -y libjemalloc-dev
# Clone RAGFlow repository
msg_info "Cloning RAGFlow Repository"
cd /opt || exit
$STD gi || exitt clone --depth 1 https://github.com/infiniflow/ragflow.git ragflow
cd /opt/ragflow || exit
git describe -- || exittags --abbrev=0 > /opt/ragflow/version.txt 2>/dev/null || echo "v0.24.0" > /opt/ragflow/version.txt
msg_ok "Cloned RAGFlow Repository"
# Install Python dependencies
msg_info "Installing Python Dependencies"
cd /opt/ragflow || exit
export UV_SYSTE || exitM_PYTHON=1
$STD /root/.local/bin/uv sync --python 3.12
$STD /root/.local/bin/uv run download_deps.py
msg_ok "Installed Python Dependencies"
# ==============================================================================
# RAGFLOW CONFIGURATION
# ==============================================================================
msg_info "Creating RAGFlow Configuration"
# Create configuration directory
mkdir -p /opt/ragflow/conf /opt/ragflow/data /opt/ragflow/logs
# Create service configuration
cat <<EOF >/opt/ragflow/conf/service_conf.yaml
ragflow:
host: 0.0.0.0
http_port: 9380
admin:
host: 0.0.0.0
http_port: 9381
mysql:
name: '${MYSQL_RAGFLOW_DB}'
user: '${MYSQL_RAGFLOW_USER}'
password: '${MYSQL_RAGFLOW_PASS}'
host: 'localhost'
port: 3306
max_connections: 900
stale_timeout: 300
max_allowed_packet: 1073741824
minio:
user: '${MINIO_USER}'
password: '${MINIO_PASS}'
host: 'localhost:9000'
bucket: 'ragflow'
prefix_path: ''
es:
hosts: 'http://localhost:9200'
username: 'elastic'
password: '${ES_PASS}'
redis:
db: 1
username: ''
password: '${REDIS_PASS}'
host: 'localhost:6379'
user_default_llm:
default_models:
embedding_model:
api_key: 'xxx'
base_url: 'http://localhost:6380'
EOF
# Create environment file
cat <<EOF >/opt/ragflow/.env
DOC_ENGINE=elasticsearch
DEVICE=cpu
COMPOSE_PROFILES=elasticsearch,cpu
STACK_VERSION=8.11.3
ES_HOST=localhost
ES_PORT=9200
ELASTIC_PASSWORD=${ES_PASS}
MYSQL_PASSWORD=${MYSQL_RAGFLOW_PASS}
MYSQL_HOST=localhost
MYSQL_DBNAME=${MYSQL_RAGFLOW_DB}
MYSQL_PORT=3306
MINIO_HOST=localhost
MINIO_PORT=9000
MINIO_USER=${MINIO_USER}
MINIO_PASSWORD=${MINIO_PASS}
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=${REDIS_PASS}
SVR_WEB_HTTP_PORT=80
SVR_WEB_HTTPS_PORT=443
SVR_HTTP_PORT=9380
ADMIN_SVR_HTTP_PORT=9381
SVR_MCP_PORT=9382
RAGFLOW_IMAGE=infiniflow/ragflow:v0.24.0
TZ=UTC
REGISTER_ENABLED=1
THREAD_POOL_MAX_WORKERS=128
EOF
msg_ok "Created RAGFlow Configuration"
# ==============================================================================
# SYSTEMD SERVICES
# ==============================================================================
msg_info "Creating Systemd Services"
# RAGFlow Backend Server
cat <<EOF >/etc/systemd/system/ragflow-server.service
[Unit]
Description=RAGFlow Backend Server
After=network.target mysql.service elasticsearch.service valkey.service minio.service
Requires=mysql.service elasticsearch.service valkey.service minio.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ragflow
Environment=PYTHONPATH=/opt/ragflow
Environment=LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
Environment=NLTK_DATA=/opt/ragflow/nltk_data
ExecStartPre=/bin/sleep 10
ExecStart=/root/.local/bin/uv run python api/ragflow_server.py
Restart=on-failure
RestartSec=10
TimeoutStartSec=300
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
# RAGFlow Task Executor
cat <<EOF >/etc/systemd/system/ragflow-task-executor.service
[Unit]
Description=RAGFlow Task Executor
After=network.target mysql.service elasticsearch.service valkey.service minio.service ragflow-server.service
Requires=mysql.service elasticsearch.service valkey.service minio.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ragflow
Environment=PYTHONPATH=/opt/ragflow
Environment=LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
Environment=NLTK_DATA=/opt/ragflow/nltk_data
ExecStart=/root/.local/bin/uv run python rag/svr/task_executor.py 0
Restart=on-failure
RestartSec=10
TimeoutStartSec=300
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
msg_ok "Created Systemd Services"
# ==============================================================================
# NGINX FRONTEND
# ==============================================================================
msg_info "Setting up Nginx Frontend"
$STD apt-get install -y nginx
# Download RAGFlow frontend from Docker image
msg_info "Extracting RAGFlow Frontend"
mkdir -p /var/www/ragflow
cd /tmp || exit
# Pull and extract frontend from Docker image
if command -v docker &>/dev/null; then
$STD docker pull infiniflow/ragflow:v0.24.0
$STD docker create --name ragflow-temp infiniflow/ragflow:v0.24.0
$STD docker cp ragflow-temp:/ragflow/web /var/www/ragflow/
$STD docker rm ragflow-temp
else
# Fallback: clone and build frontend
NODE_VERSION="22" setup_nodejs
cd /opt/ragflow/web
$STD npm install || exit
$STD npm run build
cp -r /opt/ragflow/web/dist/* /var/www/ragflow/
fi
# Configure Nginx
cat <<EOF >/etc/nginx/sites-available/ragflow.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
client_max_body_size 1G;
location / {
root /var/www/ragflow;
try_files \$uri \$uri/ /index.html;
}
location /v1/ {
proxy_pass http://127.0.0.1:9380/v1/;
proxy_http_version 1.1;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
}
location /api/ {
proxy_pass http://127.0.0.1:9380/api/;
proxy_http_version 1.1;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
}
location /docs/ {
proxy_pass http://127.0.0.1:9380/docs/;
proxy_http_version 1.1;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
location /static/ {
alias /var/www/ragflow/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
EOF
$STD rm -f /etc/nginx/sites-enabled/default
$STD ln -sf /etc/nginx/sites-available/ragflow.conf /etc/nginx/sites-enabled/
$STD systemctl enable -q --now nginx
msg_ok "Nginx Frontend Configured"
# ==============================================================================
# SAVE CREDENTIALS
# ==============================================================================
msg_info "Saving Credentials"
cat <<EOF >~/ragflow.creds
RAGFlow Credentials
===================
MySQL Database: ${MYSQL_RAGFLOW_DB}
MySQL User: ${MYSQL_RAGFLOW_USER}
MySQL Password: ${MYSQL_RAGFLOW_PASS}
Elasticsearch User: elastic
Elasticsearch Password: ${ES_PASS}
Redis Password: ${REDIS_PASS}
MinIO User: ${MINIO_USER}
MinIO Password: ${MINIO_PASS}
Web Interface: http://<IP>:80
API Endpoint: http://<IP>:9380
MinIO Console: http://<IP>:9001
Configuration: /opt/ragflow/conf/service_conf.yaml
Environment: /opt/ragflow/.env
EOF
chmod 600 ~/ragflow.creds
msg_ok "Saved Credentials"
# ==============================================================================
# START SERVICES
# ==============================================================================
msg_info "Starting RAGFlow Services"
systemctl start ragflow-server
sleep 5
systemctl start ragflow-task-executor
msg_ok "Started RAGFlow Services"
# ==============================================================================
# FINALIZATION
# ==============================================================================
motd_ssh
customize
cleanup_lxc
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}RAGFlow has been successfully installed!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:80${CL}"
echo -e "${INFO}${YW} API endpoint: http://${IP}:9380${CL}"
echo -e "${INFO}${YW} MinIO Console: http://${IP}:9001${CL}"
echo -e "${INFO}${YW} Credentials saved to: ~/ragflow.creds${CL}"
echo -e ""
echo -e "${INFO}${YW} Important Notes:${CL}"
echo -e "${TAB}- Configure your LLM API key in the web interface"
echo -e "${TAB}- Default uses CPU for document processing"
echo -e "${TAB}- For GPU acceleration, additional configuration required"
echo -e "${TAB}- Elasticsearch may take 1-2 minutes to fully initialize"
@@ -0,0 +1,52 @@
{
"name": "Kali Linux",
"slug": "kali",
"categories": [
6
],
"date_created": "2026-03-12",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://www.kali.org/docs/",
"website": "https://www.kali.org/",
"logo": "https://www.kali.org/images/kali-dragon-icon.svg",
"config_path": null,
"description": "Kali Linux is an open-source, Debian-based Linux distribution geared towards various information security testing tasks. Includes essential security tools like nmap, wireshark, john, hashcat, hydra, and metasploit-framework.",
"install_methods": [
{
"type": "default",
"script": "ct/kali.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 20,
"os": "kali",
"version": "current"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Install additional Kali tools with: apt install kali-tools-<category>",
"type": "info"
},
{
"text": "Available categories: kali-tools-top10, kali-tools-information-gathering, kali-tools-vulnerability, kali-tools-web, kali-tools-password, kali-tools-wireless, kali-tools-exploitation, kali-tools-forensic, kali-tools-reporting",
"type": "info"
},
{
"text": "Full installation: apt install kali-linux-everything",
"type": "info"
},
{
"text": "Template downloaded from images.linuxcontainers.org (not pveam)",
"type": "warning"
}
]
}
@@ -289,9 +289,9 @@ cleanup_tool_keyrings() {
local tool_patterns=("$@")
for pattern in "${tool_patterns[@]}"; do
rm -f /usr/share/keyrings/${pattern}*.gpg \
/etc/apt/keyrings/${pattern}*.gpg \
/etc/apt/trusted.gpg.d/${pattern}*.gpg 2>/dev/null || true
rm -f /usr/share/keyrings/"${pattern}"*.gpg \
/etc/apt/keyrings/"${pattern}"*.gpg \
/etc/apt/trusted.gpg.d/"${pattern}"*.gpg 2>/dev/null || true
done
}
@@ -791,7 +791,7 @@ manage_tool_repository() {
repo_component="main"
[[ "$distro_id" == "ubuntu" ]] && repo_component="multiverse"
cat <<EOF >/etc/apt/sources.list.d/mongodb-org-${version}.sources
cat <<EOF >/etc/apt/sources.list.d/mongodb-org-"${version}".sources
Types: deb
URIs: ${repo_url}
Suites: ${suite}/mongodb-org/${version}
@@ -1371,7 +1371,7 @@ download_file() {
local curl_opts=(-fsSL)
[[ "$show_progress" == "true" ]] && curl_opts=(-fL#)
for attempt in $(seq 1 $max_retries); do
for attempt in $(seq 1 "$max_retries"); do
if curl "${curl_opts[@]}" -o "$output" "$url"; then
return 0
fi
@@ -1846,7 +1846,7 @@ setup_deb822_repo() {
[[ -n "$architectures" ]] && echo "Architectures: $architectures"
echo "Signed-By: /etc/apt/keyrings/${name}.gpg"
[[ -n "$enabled" ]] && echo "Enabled: $enabled"
} >/etc/apt/sources.list.d/${name}.sources
} >/etc/apt/sources.list.d/"${name}".sources
$STD apt update || {
msg_warn "apt update failed after adding repository: ${name}"
@@ -2672,7 +2672,7 @@ function fetch_and_deploy_codeberg_release() {
# Codeberg archive URL format: https://codeberg.org/{owner}/{repo}/archive/{tag}.tar.gz
local archive_url="https://codeberg.org/$repo/archive/${tag_name}.tar.gz"
if curl $download_timeout -fsSL -o "$tmpdir/$filename" "$archive_url"; then
if curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$archive_url"; then
download_success=true
fi
@@ -2722,7 +2722,7 @@ function fetch_and_deploy_codeberg_release() {
local max_retries=3 retry_delay=2 attempt=1 success=false resp http_code
while ((attempt <= max_retries)); do
resp=$(curl $api_timeout -fsSL -w "%{http_code}" -o /tmp/codeberg_rel.json "$api_url") && success=true && break
resp=$(curl "$api_timeout" -fsSL -w "%{http_code}" -o /tmp/codeberg_rel.json "$api_url") && success=true && break
sleep "$retry_delay"
((attempt++))
done
@@ -2769,7 +2769,7 @@ function fetch_and_deploy_codeberg_release() {
# Codeberg archive URL format
local archive_url="https://codeberg.org/$repo/archive/${tag_name}.tar.gz"
if curl $download_timeout -fsSL -o "$tmpdir/$filename" "$archive_url"; then
if curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$archive_url"; then
download_success=true
fi
@@ -2843,7 +2843,7 @@ function fetch_and_deploy_codeberg_release() {
fi
filename="${url_match##*/}"
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$url_match" || {
curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$url_match" || {
msg_error "Download failed: $url_match"
rm -rf "$tmpdir"
return 1
@@ -2886,7 +2886,7 @@ function fetch_and_deploy_codeberg_release() {
}
filename="${asset_url##*/}"
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$asset_url" || {
curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$asset_url" || {
msg_error "Download failed: $asset_url"
rm -rf "$tmpdir"
return 1
@@ -2987,7 +2987,7 @@ function fetch_and_deploy_codeberg_release() {
local target_file="$app"
[[ "$use_filename" == "true" ]] && target_file="$filename"
curl $download_timeout -fsSL -o "$target/$target_file" "$asset_url" || {
curl "$download_timeout" -fsSL -o "$target/$target_file" "$asset_url" || {
msg_error "Download failed: $asset_url"
rm -rf "$tmpdir"
return 1
@@ -3206,7 +3206,7 @@ function fetch_and_deploy_gh_release() {
local max_retries=3 retry_delay=2 attempt=1 success=false http_code
while ((attempt <= max_retries)); do
http_code=$(curl $api_timeout -sSL -w "%{http_code}" -o /tmp/gh_rel.json "${header[@]}" "$api_url" 2>/dev/null) || true
http_code=$(curl "$api_timeout" -sSL -w "%{http_code}" -o /tmp/gh_rel.json "${header[@]}" "$api_url" 2>/dev/null) || true
if [[ "$http_code" == "200" ]]; then
success=true
break
@@ -3280,7 +3280,7 @@ function fetch_and_deploy_gh_release() {
local direct_tarball_url="https://github.com/$repo/archive/refs/tags/$tag_name.tar.gz"
filename="${app_lc}-${version_safe}.tar.gz"
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$direct_tarball_url" || {
curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$direct_tarball_url" || {
msg_error "Download failed: $direct_tarball_url"
rm -rf "$tmpdir"
return 1
@@ -3383,7 +3383,7 @@ function fetch_and_deploy_gh_release() {
fi
filename="${url_match##*/}"
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$url_match" || {
curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$url_match" || {
msg_error "Download failed: $url_match"
rm -rf "$tmpdir"
return 1
@@ -3395,7 +3395,7 @@ function fetch_and_deploy_gh_release() {
local dpkg_opts=""
[[ "${DPKG_FORCE_CONFOLD:-}" == "1" ]] && dpkg_opts="-o Dpkg::Options::=--force-confold"
[[ "${DPKG_FORCE_CONFNEW:-}" == "1" ]] && dpkg_opts="-o Dpkg::Options::=--force-confnew"
DEBIAN_FRONTEND=noninteractive SYSTEMD_OFFLINE=1 $STD apt install -y $dpkg_opts "$tmpdir/$filename" || {
DEBIAN_FRONTEND=noninteractive SYSTEMD_OFFLINE=1 $STD apt install -y "$dpkg_opts" "$tmpdir/$filename" || {
SYSTEMD_OFFLINE=1 $STD dpkg -i "$tmpdir/$filename" || {
msg_error "Both apt and dpkg installation failed"
rm -rf "$tmpdir"
@@ -3450,7 +3450,7 @@ function fetch_and_deploy_gh_release() {
}
filename="${asset_url##*/}"
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$asset_url" || {
curl "$download_timeout" -fsSL -o "$tmpdir/$filename" "$asset_url" || {
msg_error "Download failed: $asset_url"
rm -rf "$tmpdir"
return 1
@@ -3571,7 +3571,7 @@ function fetch_and_deploy_gh_release() {
local target_file="$app"
[[ "$use_filename" == "true" ]] && target_file="$filename"
curl $download_timeout -fsSL -o "$target/$target_file" "$asset_url" || {
curl "$download_timeout" -fsSL -o "$target/$target_file" "$asset_url" || {
msg_error "Download failed: $asset_url"
rm -rf "$tmpdir"
return 1
@@ -4724,7 +4724,7 @@ _setup_nvidia_gpu() {
if [[ -n "$available_version" ]]; then
msg_info "Found available NVIDIA version: ${available_version}"
local nvidia_pkgs="libcuda1=${available_version} libnvcuvid1=${available_version} libnvidia-encode1=${available_version} libnvidia-ml1=${available_version}"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends "$nvidia_pkgs" 2>/dev/null; then
msg_ok "Installed NVIDIA libraries (${available_version})"
else
msg_warn "Failed to install NVIDIA ${available_version} - trying unversioned"
@@ -4788,7 +4788,7 @@ NVIDIA_PIN
if [[ -n "$available_version" ]]; then
msg_info "Installing NVIDIA libraries (version ${available_version})"
local nvidia_pkgs="libcuda1=${available_version} libnvcuvid1=${available_version} libnvidia-encode1=${available_version} libnvidia-ml1=${available_version}"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends "$nvidia_pkgs" 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
msg_warn "Version-pinned install failed - trying unpinned"
@@ -4851,13 +4851,13 @@ NVIDIA_PIN
if [[ -n "$available_version" ]]; then
msg_info "Installing NVIDIA libraries (version ${available_version})"
local nvidia_pkgs="libcuda1=${available_version} libnvcuvid1=${available_version} libnvidia-encode1=${available_version} libnvidia-ml1=${available_version}"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends "$nvidia_pkgs" 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
# Fallback to Ubuntu repo packages with versioned nvidia-utils
msg_warn "CUDA repo install failed - trying Ubuntu native packages (nvidia-utils-${nvidia_major_version})"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends \
libnvidia-decode-${nvidia_major_version} libnvidia-encode-${nvidia_major_version} nvidia-utils-${nvidia_major_version} 2>/dev/null; then
libnvidia-decode-"${nvidia_major_version}" libnvidia-encode-"${nvidia_major_version}" nvidia-utils-"${nvidia_major_version}" 2>/dev/null; then
msg_ok "Installed Ubuntu NVIDIA packages (${nvidia_major_version})"
else
msg_warn "NVIDIA driver installation failed - please install manually: apt install nvidia-utils-${nvidia_major_version}"
@@ -4868,7 +4868,7 @@ NVIDIA_PIN
# Fallback to Ubuntu repo packages with versioned nvidia-utils
msg_info "Trying Ubuntu native packages (nvidia-utils-${nvidia_major_version})"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends \
libnvidia-decode-${nvidia_major_version} libnvidia-encode-${nvidia_major_version} nvidia-utils-${nvidia_major_version} 2>/dev/null; then
libnvidia-decode-"${nvidia_major_version}" libnvidia-encode-"${nvidia_major_version}" nvidia-utils-"${nvidia_major_version}" 2>/dev/null; then
msg_ok "Installed Ubuntu NVIDIA packages (${nvidia_major_version})"
else
msg_warn "NVIDIA driver installation failed - please install manually: apt install nvidia-utils-${nvidia_major_version}"
@@ -5948,6 +5948,23 @@ function setup_mysql() {
return 0
fi
# Debian 13+ Fix: MySQL repo has expired GPG key (as of 2025-10-22), use MariaDB
# See: https://bugs.mysql.com/bug.php?id=119212
# This check MUST be before prepare_repository_setup to avoid adding broken repo
if [[ "$DISTRO_ID" == "debian" && "$DISTRO_CODENAME" =~ ^(trixie|forky|sid)$ ]]; then
msg_info "Debian ${DISTRO_CODENAME} detected → using MariaDB (MySQL repo GPG key expired)"
# Use distro's MariaDB directly - no external repo needed
install_packages_with_retry "mariadb-server" "mariadb-client" || {
msg_error "Failed to install MariaDB on Debian ${DISTRO_CODENAME}"
return 1
}
cache_installed_version "mysql" "mariadb"
msg_ok "Setup MariaDB (MySQL-compatible, Debian ${DISTRO_CODENAME})"
return 0
fi
# Scenario 2: Different version installed - clean upgrade
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" != "$MYSQL_VERSION" ]]; then
msg_info "Upgrade MySQL from $CURRENT_VERSION to $MYSQL_VERSION"
@@ -5962,47 +5979,6 @@ function setup_mysql() {
return 1
}
# Debian 13+ Fix: MySQL 8.0 incompatible with libaio1t64, use 8.4 LTS
if [[ "$DISTRO_ID" == "debian" && "$DISTRO_CODENAME" =~ ^(trixie|forky|sid)$ ]]; then
msg_info "Debian ${DISTRO_CODENAME} detected → using MySQL 8.4 LTS (libaio1t64 compatible)"
if ! download_gpg_key "https://repo.mysql.com/RPM-GPG-KEY-mysql-2023" "/etc/apt/keyrings/mysql.gpg" "dearmor"; then
msg_error "Failed to import MySQL GPG key"
return 1
fi
cat >/etc/apt/sources.list.d/mysql.sources <<EOF
Types: deb
URIs: https://repo.mysql.com/apt/debian/
Suites: bookworm
Components: mysql-8.4-lts
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/mysql.gpg
EOF
$STD apt update || {
msg_error "Failed to update APT for MySQL 8.4 LTS"
return 1
}
# Install with retry logic
if ! install_packages_with_retry "mysql-community-server" "mysql-community-client"; then
msg_warn "MySQL 8.4 LTS installation failed falling back to MariaDB"
cleanup_old_repo_files "mysql"
$STD apt update
install_packages_with_retry "mariadb-server" "mariadb-client" || {
msg_error "Failed to install database engine (MySQL/MariaDB fallback)"
return 1
}
msg_ok "Setup Database Engine (MariaDB fallback on Debian ${DISTRO_CODENAME})"
return 0
fi
cache_installed_version "mysql" "8.4"
msg_ok "Setup MySQL 8.4 LTS (Debian ${DISTRO_CODENAME})"
return 0
fi
# Standard setup for other distributions
local SUITE
if [[ "$DISTRO_ID" == "debian" ]]; then
@@ -6016,7 +5992,7 @@ EOF
# Setup repository
manage_tool_repository "mysql" "$MYSQL_VERSION" "https://repo.mysql.com/apt/${DISTRO_ID}" \
"https://repo.mysql.com/RPM-GPG-KEY-mysql-2023" || {
"https://repo.mysql.com/RPM-GPG-KEY-mysql-2025" || {
msg_error "Failed to setup MySQL repository"
return 1
}
@@ -6439,8 +6415,8 @@ EOF
msg_warn "php${PHP_VERSION}-fpm not available"
fi
# Create systemd override for PHP-FPM to fix runtime directory issues in LXC containers
mkdir -p /etc/systemd/system/php${PHP_VERSION}-fpm.service.d/
cat <<EOF >/etc/systemd/system/php${PHP_VERSION}-fpm.service.d/override.conf
mkdir -p /etc/systemd/system/php"${PHP_VERSION}"-fpm.service.d/
cat <<EOF >/etc/systemd/system/php"${PHP_VERSION}"-fpm.service.d/override.conf
[Service]
RuntimeDirectory=php
RuntimeDirectoryMode=0755
@@ -6466,7 +6442,7 @@ EOF
msg_info "Installing PHP ${PHP_VERSION} packages"
# First attempt: Install all verified packages at once
if ! $STD apt install -y $MODULE_LIST 2>/dev/null; then
if ! $STD apt install -y "$MODULE_LIST" 2>/dev/null; then
msg_warn "Bulk installation failed, attempting individual installation"
# Install main package first (critical)
@@ -6520,8 +6496,8 @@ EOF
# Enable and restart PHP-FPM if requested
if [[ "$PHP_FPM" == "YES" ]]; then
if systemctl list-unit-files | grep -q "php${PHP_VERSION}-fpm.service"; then
$STD systemctl enable php${PHP_VERSION}-fpm
safe_service_restart php${PHP_VERSION}-fpm
$STD systemctl enable php"${PHP_VERSION}"-fpm
safe_service_restart php"${PHP_VERSION}"-fpm
fi
fi
@@ -0,0 +1,183 @@
#!/usr/bin/env bash
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/refs/heads/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL}"/misc/build.func)
# Author: Heretek-AI
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://images.linuxcontainers.org/
APP="Kali"
var_tags="${var_tags:-security;pentest;kali;linux}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-20}"
var_os="${var_os:-kali}"
var_version="${var_version:-current}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/os-release ]] || ! grep -qi "kali" /etc/os-release 2>/dev/null; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating ${APP} LXC Container"
$STD apt-get update
$STD apt-get upgrade -y
msg_ok "Updated ${APP} LXC Container"
exit
}
# Download Kali template from images.linuxcontainers.org
# This runs BEFORE build_container to ensure template is available
function fetch_kali_template() {
local STORAGE="${var_template_storage:-local}"
local TEMPLATE_DIR
# Get template directory based on storage
if [[ "$STORAGE" == "local" ]]; then
TEMPLATE_DIR="/var/lib/vz/template/cache"
else
# Get path from Proxmox storage config
TEMPLATE_DIR=$(grep -E "^[^:]+: ${STORAGE}$" /etc/pve/storage.cfg -A10 2>/dev/null | grep "path" | awk '{print $2}')
[[ -z "$TEMPLATE_DIR" ]] && TEMPLATE_DIR="/var/lib/vz"
TEMPLATE_DIR="${TEMPLATE_DIR}/template/cache"
fi
# Create directory if it doesn't exist
mkdir -p "${TEMPLATE_DIR}"
# Kali template URL from images.linuxcontainers.org
# Structure: https://images.linuxcontainers.org/images/kali/current/amd64/default/YYYYMMDD_HH:MM/rootfs.tar.xz
local KALI_BASE_URL="https://images.linuxcontainers.org/images/kali/current/amd64/default/"
msg_info "Fetching latest Kali template from images.linuxcontainers.org"
# Get the directory listing to find the latest date folder
local PAGE_CONTENT
PAGE_CONTENT=$(curl -fsSL "${KALI_BASE_URL}" 2>/dev/null)
if [[ -z "$PAGE_CONTENT" ]]; then
msg_error "Failed to fetch Kali template listing from ${KALI_BASE_URL}"
msg_error "Please check your network connection and try again"
exit 225
fi
# Parse the page to find the latest date directory
# The page format is: [YYYYMMDD_HH:MM/](url) with date
# We need to extract the directory names like 20260311_17:14
local LATEST_DIR
# Simple approach: use grep to find all date patterns and sort them
# Pattern: 8 digits, underscore, 2 digits, colon, 2 digits
LATEST_DIR=$(echo "$PAGE_CONTENT" | grep -o '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9]:[0-9][0-9]' | sort -r | head -n 1)
if [[ -z "$LATEST_DIR" ]]; then
msg_error "Could not find Kali template directory in the listing"
msg_error "Please visit ${KALI_BASE_URL} manually"
exit 225
fi
# Remove trailing slash if present
LATEST_DIR="${LATEST_DIR%/}"
msg_info "Found latest Kali template directory: ${LATEST_DIR}"
# Construct the full URL to rootfs.tar.xz
local TEMPLATE_URL="${KALI_BASE_URL}${LATEST_DIR}/rootfs.tar.xz"
# Create a friendly template name for Proxmox (replace : with - for compatibility)
local DATE_PART="${LATEST_DIR//:/-}"
local TEMPLATE_NAME="kali-current-amd64-default-${DATE_PART}.tar.xz"
local TEMPLATE_PATH="${TEMPLATE_DIR}/${TEMPLATE_NAME}"
# Check if template already exists and is valid
# Kali minimal templates can be as small as 50MB when compressed
if [[ -f "$TEMPLATE_PATH" ]]; then
local FILE_SIZE
FILE_SIZE=$(stat -c%s "$TEMPLATE_PATH" 2>/dev/null || echo 0)
if [[ $FILE_SIZE -gt 50000000 ]]; then
msg_ok "Kali template already downloaded: ${TEMPLATE_NAME}"
echo "${TEMPLATE_NAME}"
return 0
else
msg_warn "Existing template file too small (${FILE_SIZE} bytes), re-downloading"
rm -f "$TEMPLATE_PATH"
fi
fi
msg_info "Downloading Kali template: ${TEMPLATE_NAME}"
msg_info "URL: ${TEMPLATE_URL}"
msg_info "Target: ${TEMPLATE_PATH}"
# Download with progress
local DOWNLOAD_STATUS=0
if command -v wget &>/dev/null; then
if wget --progress=bar:force -O "${TEMPLATE_PATH}" "${TEMPLATE_URL}" 2>&1; then
DOWNLOAD_STATUS=1
fi
elif command -v curl &>/dev/null; then
if curl -L --progress-bar -o "${TEMPLATE_PATH}" "${TEMPLATE_URL}" 2>&1; then
DOWNLOAD_STATUS=1
fi
else
msg_error "Neither wget nor curl available for download"
exit 222
fi
if [[ $DOWNLOAD_STATUS -eq 0 ]]; then
msg_error "Failed to download Kali template"
rm -f "${TEMPLATE_PATH}"
exit 222
fi
# Verify download
# Kali minimal templates can be as small as 50MB when compressed
local DOWNLOADED_SIZE
DOWNLOADED_SIZE=$(stat -c%s "${TEMPLATE_PATH}" 2>/dev/null || echo 0)
if [[ $DOWNLOADED_SIZE -lt 50000000 ]]; then
msg_error "Downloaded template is too small (${DOWNLOADED_SIZE} bytes)"
msg_error "Expected at least 50MB for a valid Kali template"
rm -f "${TEMPLATE_PATH}"
exit 222
fi
msg_ok "Successfully downloaded Kali template: ${TEMPLATE_NAME} ($(numfmt --to=iec --from-unit=1024 --format %.1f "${DOWNLOADED_SIZE}" 2>/dev/null || echo "${DOWNLOADED_SIZE}")B)"
# Return the template name for use by build_container
echo "${TEMPLATE_NAME}"
}
# Build function override to handle Kali template download
# This runs before build_container to set up the template
function build_kali_container() {
# Download template first
local KALI_TEMPLATE
KALI_TEMPLATE=$(fetch_kali_template)
# Set template for build_container
export TEMPLATE="${KALI_TEMPLATE}"
export TEMPLATE_SOURCE="local"
# Now call the standard build_container which sets up PCT_OPTIONS
# and calls create_lxc_container internally
build_container
}
start
build_kali_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} LXC has been successfully created!${CL}"
echo -e "${INFO}${YW} Access it using: ${BGN}pct enter ${CTID}${CL}"
echo -e "${INFO}${YW} Or SSH: ${BGN}ssh root@${IP}${CL}"
@@ -0,0 +1,94 @@
#!/usr/bin/env bash
# Author: Heretek-AI
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://images.linuxcontainers.org/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Kali Linux Essential Tools"
# Pre-configure debconf to avoid interactive prompts
export DEBIAN_FRONTEND=noninteractive
# Pre-answer wireshark-common prompt about non-root packet capture
echo "wireshark-common wireshark-common/install-setuid boolean false" | debconf-set-selections 2>/dev/null || true
# Install essential Kali security tools (minimal footprint)
$STD apt-get install -y \
nmap \
curl \
wget \
git \
net-tools \
iputils-ping \
dnsutils \
whois \
netcat-openbsd \
tcpdump \
john \
hashcat \
hydra
# Install optional larger packages (may fail in minimal environment)
$STD apt-get install -y wireshark-common 2>/dev/null || true
$STD apt-get install -y metasploit-framework 2>/dev/null || true
$STD apt-get install -y kali-tools-top10 2>/dev/null || true
msg_ok "Installed Kali Linux Essential Tools"
msg_info "Configuring Kali Environment"
# Ensure Kali repositories are configured
if [[ ! -f /etc/apt/sources.list.d/kali.list ]]; then
cat <<EOF > /etc/apt/sources.list.d/kali.list
# Kali Linux Repository
deb http://http.kali.org/kali kali-rolling main contrib non-free non-free-firmware
EOF
fi
# Update package lists with Kali repos
$STD apt-get update 2>/dev/null || true
msg_ok "Configured Kali Environment"
motd_ssh
customize
cleanup_lxc
# Get container IP for display
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo ""
echo "=========================================="
echo " Kali Linux LXC Installation Complete!"
echo "=========================================="
echo ""
echo "Access the container:"
echo " pct enter ${CTID}"
echo " ssh root@${LOCAL_IP}"
echo ""
echo "Install additional Kali tools:"
echo " apt install kali-tools-<category>"
echo ""
echo "Available tool categories:"
echo " kali-tools-top10 - Top 10 tools"
echo " kali-tools-information-gathering"
echo " kali-tools-vulnerability"
echo " kali-tools-web"
echo " kali-tools-password"
echo " kali-tools-wireless"
echo " kali-tools-exploitation"
echo " kali-tools-forensic"
echo " kali-tools-reporting"
echo " kali-tools-social-engineering"
echo ""
echo "Full installation:"
echo " apt install kali-linux-everything"
echo "=========================================="
@@ -0,0 +1,70 @@
#!/usr/bin/env bash
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/refs/heads/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL}"/misc/build.func)
# Author: Heretek-AI
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/vxcontrol/pentagi
APP="PentAGI"
var_tags="${var_tags:-ai;security;pentest;automation}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-50}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/pentagi ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if [[ ! -f /opt/pentagi/docker-compose.yml ]]; then
msg_error "No ${APP} docker-compose.yml Found!"
exit
fi
msg_info "Stopping ${APP} Services"
systemctl stop pentagi
msg_ok "Stopped ${APP} Services"
msg_info "Backing up Configuration"
cp /opt/pentagi/.env /opt/pentagi_env_backup
msg_ok "Backed up Configuration"
msg_info "Updating ${APP} Container Images"
cd /opt/pentagi || exit
$STD docker compose pull
msg_ok "Updated ${APP} Container Images"
msg_info "Restoring Configuration"
cp /opt/pentagi_env_backup /opt/pentagi/.env
msg_ok "Restored Configuration"
msg_info "Starting ${APP} Services"
systemctl start pentagi
msg_ok "Started ${APP} Services"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8443${CL}"
echo -e "${INFO}${YW} Default credentials: admin@pentagi.com / admin${CL}"
echo -e "${INFO}${YW} Configure your LLM provider API keys in Settings${CL}"
@@ -0,0 +1,76 @@
{
"name": "PentAGI",
"slug": "pentagi",
"categories": [
20
],
"date_created": "2026-03-12",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8443,
"documentation": "https://github.com/vxcontrol/pentagi",
"website": "https://github.com/vxcontrol/pentagi",
"logo": null,
"config_path": "/opt/pentagi/.env",
"description": "PentAGI is an AI-powered autonomous penetration testing system that leverages multiple LLM providers (OpenAI, Anthropic, Gemini, Bedrock, Ollama, DeepSeek, GLM, Kimi, Qwen) for security testing. Features include knowledge graph integration (Graphiti/Neo4j), LLM observability (Langfuse), 20+ professional pentesting tools in sandboxed Docker containers, and comprehensive REST/GraphQL APIs. Docker is installed inside the container.",
"install_methods": [
{
"type": "default",
"script": "ct/pentagi.sh",
"resources": {
"cpu": 4,
"ram": 8192,
"hdd": 50,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin@pentagi.com",
"password": "admin"
},
"notes": [
{
"text": "Access the Web UI at https://<IP>:8443 (note: HTTPS)",
"type": "info"
},
{
"text": "Docker is installed inside the container - no host socket passthrough required",
"type": "info"
},
{
"text": "Configure at least one LLM provider API key before use (OpenAI, Anthropic, Gemini, etc.)",
"type": "warning"
},
{
"text": "Configuration file: /opt/pentagi/.env",
"type": "info"
},
{
"text": "Credentials stored in: /opt/pentagi/CREDENTIALS.txt",
"type": "info"
},
{
"text": "Configuration guide: /opt/pentagi/CONFIGURATION.md",
"type": "info"
},
{
"text": "Optional: Enable Graphiti knowledge graph with docker-compose-graphiti.yml",
"type": "info"
},
{
"text": "Optional: Enable Langfuse observability with docker-compose-langfuse.yml",
"type": "info"
},
{
"text": "Optional: Enable monitoring stack with docker-compose-observability.yml",
"type": "info"
},
{
"text": "Change default password immediately after first login",
"type": "warning"
}
]
}
@@ -0,0 +1,347 @@
#!/usr/bin/env bash
# Author: Heretek-AI
# License: MIT | https://github.com/Heretek-AI/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/vxcontrol/pentagi
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
curl \
wget \
ca-certificates \
gnupg \
lsb-release \
jq
msg_ok "Installed Dependencies"
msg_info "Installing Docker"
# Add Docker's official GPG key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker packages
$STD apt-get update
$STD apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
msg_ok "Installed Docker"
msg_info "Creating Directories"
mkdir -p /opt/pentagi
mkdir -p /opt/pentagi/data
mkdir -p /opt/pentagi/ssl
mkdir -p /var/log/pentagi
msg_ok "Created Directories"
msg_info "Downloading PentAGI Configuration"
curl -fsSL https://raw.githubusercontent.com/vxcontrol/pentagi/master/docker-compose.yml -o /opt/pentagi/docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/vxcontrol/pentagi/master/.env.example -o /opt/pentagi/.env.example
msg_ok "Downloaded PentAGI Configuration"
msg_info "Generating Secure Configuration"
# Generate random passwords and salts
POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
COOKIE_SALT=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
INSTALLATION_ID=$(cat /proc/sys/kernel/random/uuid)
# Create .env file from template
cp /opt/pentagi/.env.example /opt/pentagi/.env
# Strip inline comments (Go env parser doesn't handle them)
# Remove everything after # on lines that have = (but keep the value)
sed -i 's/=\([^#]*\)#.*/=\1/' /opt/pentagi/.env
# Trim trailing whitespace from values
sed -i 's/ *= */=/' /opt/pentagi/.env
sed -i 's/ *$//' /opt/pentagi/.env
# Set secure defaults
sed -i "s/^PENTAGI_POSTGRES_PASSWORD=.*/PENTAGI_POSTGRES_PASSWORD=${POSTGRES_PASSWORD}/" /opt/pentagi/.env
sed -i "s/^COOKIE_SIGNING_SALT=.*/COOKIE_SIGNING_SALT=${COOKIE_SALT}/" /opt/pentagi/.env
sed -i "s/^INSTALLATION_ID=.*/INSTALLATION_ID=${INSTALLATION_ID}/" /opt/pentagi/.env
# Set public URL to container IP
LOCAL_IP=$(hostname -I | awk '{print $1}')
sed -i "s|^PUBLIC_URL=.*|PUBLIC_URL=https://${LOCAL_IP}:8443|" /opt/pentagi/.env
sed -i "s|^CORS_ORIGINS=.*|CORS_ORIGINS=https://${LOCAL_IP}:8443,https://localhost:8443|" /opt/pentagi/.env
# Listen on all interfaces for external access
sed -i "s|^PENTAGI_LISTEN_IP=.*|PENTAGI_LISTEN_IP=0.0.0.0|" /opt/pentagi/.env
# Set scraper credentials
SCRAPER_USER="pentagi"
SCRAPER_PASS=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 16)
sed -i "s/^LOCAL_SCRAPER_USERNAME=.*/LOCAL_SCRAPER_USERNAME=${SCRAPER_USER}/" /opt/pentagi/.env
sed -i "s/^LOCAL_SCRAPER_PASSWORD=.*/LOCAL_SCRAPER_PASSWORD=${SCRAPER_PASS}/" /opt/pentagi/.env
sed -i "s|^SCRAPER_PRIVATE_URL=.*|SCRAPER_PRIVATE_URL=https://${SCRAPER_USER}:${SCRAPER_PASS}@scraper/|" /opt/pentagi/.env
# Set Langfuse passwords
LANGFUSE_POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
LANGFUSE_REDIS_AUTH=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
LANGFUSE_SALT=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
LANGFUSE_ENCRYPTION_KEY=$(openssl rand -hex 32)
LANGFUSE_NEXTAUTH_SECRET=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
LANGFUSE_S3_ACCESS_KEY_ID=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 16)
LANGFUSE_S3_SECRET_ACCESS_KEY=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
LANGFUSE_INIT_USER_PASSWORD=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 16)
LANGFUSE_INIT_PROJECT_PUBLIC_KEY="pk-lf-$(cat /proc/sys/kernel/random/uuid | tr -d '-')"
LANGFUSE_INIT_PROJECT_SECRET_KEY="sk-lf-$(cat /proc/sys/kernel/random/uuid | tr -d '-')"
sed -i "s/^LANGFUSE_POSTGRES_PASSWORD=.*/LANGFUSE_POSTGRES_PASSWORD=${LANGFUSE_POSTGRES_PASSWORD}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_REDIS_AUTH=.*/LANGFUSE_REDIS_AUTH=${LANGFUSE_REDIS_AUTH}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_SALT=.*/LANGFUSE_SALT=${LANGFUSE_SALT}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_ENCRYPTION_KEY=.*/LANGFUSE_ENCRYPTION_KEY=${LANGFUSE_ENCRYPTION_KEY}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_NEXTAUTH_SECRET=.*/LANGFUSE_NEXTAUTH_SECRET=${LANGFUSE_NEXTAUTH_SECRET}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_S3_ACCESS_KEY_ID=.*/LANGFUSE_S3_ACCESS_KEY_ID=${LANGFUSE_S3_ACCESS_KEY_ID}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_S3_SECRET_ACCESS_KEY=.*/LANGFUSE_S3_SECRET_ACCESS_KEY=${LANGFUSE_S3_SECRET_ACCESS_KEY}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_INIT_USER_PASSWORD=.*/LANGFUSE_INIT_USER_PASSWORD=${LANGFUSE_INIT_USER_PASSWORD}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_INIT_PROJECT_PUBLIC_KEY=.*/LANGFUSE_INIT_PROJECT_PUBLIC_KEY=${LANGFUSE_INIT_PROJECT_PUBLIC_KEY}/" /opt/pentagi/.env
sed -i "s/^LANGFUSE_INIT_PROJECT_SECRET_KEY=.*/LANGFUSE_INIT_PROJECT_SECRET_KEY=${LANGFUSE_INIT_PROJECT_SECRET_KEY}/" /opt/pentagi/.env
# Set Neo4j password for Graphiti
NEO4J_PASSWORD=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
sed -i "s/^NEO4J_PASSWORD=.*/NEO4J_PASSWORD=${NEO4J_PASSWORD}/" /opt/pentagi/.env
msg_ok "Generated Secure Configuration"
msg_info "Creating Systemd Service"
cat <<EOF >/etc/systemd/system/pentagi.service
[Unit]
Description=PentAGI - AI-Powered Autonomous Penetration Testing
After=network.target network-online.target docker.service
Wants=network-online.target
Requires=docker.service
[Service]
Type=simple
WorkingDirectory=/opt/pentagi
EnvironmentFile=/opt/pentagi/.env
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down
Restart=always
RestartSec=10
TimeoutStartSec=300
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
EOF
msg_ok "Created Systemd Service"
msg_info "Pulling Docker Images"
cd /opt/pentagi || exit
$STD docker compose pull
msg_ok "Pulled Docker Images"
msg_info "Starting PentAGI Service"
systemctl daemon-reload
systemctl enable -q pentagi
systemctl start pentagi
msg_ok "Started PentAGI Service"
# Store credentials for user reference
cat <<EOF >/opt/pentagi/CREDENTIALS.txt
PentAGI Credentials
===================
Web Interface:
URL: https://${LOCAL_IP}:8443
Default Username: admin@pentagi.com
Default Password: admin
PostgreSQL Database:
User: postgres
Password: ${POSTGRES_PASSWORD}
Database: pentagidb
Scraper Service:
Username: ${SCRAPER_USER}
Password: ${SCRAPER_PASS}
Langfuse (if enabled):
Admin Email: admin@pentagi.com
Admin Password: ${LANGFUSE_INIT_USER_PASSWORD}
Project Public Key: ${LANGFUSE_INIT_PROJECT_PUBLIC_KEY}
Project Secret Key: ${LANGFUSE_INIT_PROJECT_SECRET_KEY}
Neo4j (for Graphiti, if enabled):
User: neo4j
Password: ${NEO4J_PASSWORD}
IMPORTANT:
1. Change the default web interface password after first login
2. Configure at least one LLM provider API key in Settings
3. This file contains sensitive credentials - secure it appropriately
EOF
chmod 600 /opt/pentagi/CREDENTIALS.txt
msg_info "Creating Configuration Guide"
cat <<EOF >/opt/pentagi/CONFIGURATION.md
# PentAGI Configuration Guide
## Required Configuration
Before using PentAGI, you must configure at least one LLM provider.
### LLM Provider Configuration
Edit /opt/pentagi/.env and add your API key for at least one provider:
#### OpenAI
\`\`\`
OPEN_AI_KEY=your_openai_api_key
\`\`\`
#### Anthropic (Claude)
\`\`\`
ANTHROPIC_API_KEY=your_anthropic_api_key
\`\`\`
#### Google Gemini
\`\`\`
GEMINI_API_KEY=your_gemini_api_key
\`\`\`
#### AWS Bedrock
\`\`\`
BEDROCK_REGION=us-east-1
BEDROCK_DEFAULT_AUTH=true
# Or use static credentials:
# BEDROCK_ACCESS_KEY_ID=your_access_key
# BEDROCK_SECRET_ACCESS_KEY=your_secret_key
\`\`\`
#### Ollama (Local)
\`\`\`
OLLAMA_SERVER_URL=http://your-ollama-server:11434
OLLAMA_SERVER_MODEL=llama3.1:8b-instruct-q8_0
\`\`\`
### Optional: Enable Graphiti Knowledge Graph
To enable the knowledge graph feature:
1. Download the Graphiti compose file:
\`\`\`
cd /opt/pentagi
curl -O https://raw.githubusercontent.com/vxcontrol/pentagi/master/docker-compose-graphiti.yml
\`\`\`
2. Edit /etc/systemd/system/pentagi.service and change:
\`\`\`
ExecStart=/usr/bin/docker compose -f docker-compose.yml -f docker-compose-graphiti.yml up
ExecStop=/usr/bin/docker compose -f docker-compose.yml -f docker-compose-graphiti.yml down
\`\`\`
3. Enable Graphiti in .env:
\`\`\`
GRAPHITI_ENABLED=true
GRAPHITI_URL=http://graphiti:8000
\`\`\`
4. Reload and restart:
\`\`\`
systemctl daemon-reload
systemctl restart pentagi
\`\`\`
### Optional: Enable Langfuse Observability
To enable LLM observability:
1. Download the Langfuse compose file:
\`\`\`
cd /opt/pentagi
curl -O https://raw.githubusercontent.com/vxcontrol/pentagi/master/docker-compose-langfuse.yml
\`\`\`
2. Edit /etc/systemd/system/pentagi.service and change:
\`\`\`
ExecStart=/usr/bin/docker compose -f docker-compose.yml -f docker-compose-langfuse.yml up
ExecStop=/usr/bin/docker compose -f docker-compose.yml -f docker-compose-langfuse.yml down
\`\`\`
3. Enable Langfuse in .env:
\`\`\`
LANGFUSE_BASE_URL=http://langfuse-web:3000
LANGFUSE_PUBLIC_KEY=<from CREDENTIALS.txt>
LANGFUSE_SECRET_KEY=<from CREDENTIALS.txt>
\`\`\`
4. Reload and restart:
\`\`\`
systemctl daemon-reload
systemctl restart pentagi
\`\`\`
## Service Management
- Start: \`systemctl start pentagi\`
- Stop: \`systemctl stop pentagi\`
- Restart: \`systemctl restart pentagi\`
- Status: \`systemctl status pentagi\`
- Logs: \`journalctl -u pentagi -f\`
## Updating
Run the update script from the Proxmox host:
\`\`\`
./ct/pentagi.sh
\`\`\`
Or manually:
\`\`\`
cd /opt/pentagi
docker compose pull
systemctl restart pentagi
\`\`\`
## External Access
To access PentAGI from other machines, edit /opt/pentagi/.env:
\`\`\`
PENTAGI_LISTEN_IP=0.0.0.0
PUBLIC_URL=https://your-server-ip:8443
CORS_ORIGINS=https://your-server-ip:8443,https://localhost:8443
\`\`\`
Then restart: \`systemctl restart pentagi\`
## More Information
- Documentation: https://github.com/vxcontrol/pentagi
- Discord: https://discord.gg/2xrMh7qX6m
- Telegram: https://t.me/+Ka9i6CNwe71hMWQy
EOF
msg_ok "Created Configuration Guide"
motd_ssh
customize
cleanup_lxc
echo ""
echo "=========================================="
echo " PentAGI Installation Complete!"
echo "=========================================="
echo ""
echo "Access the web interface at: https://${LOCAL_IP}:8443"
echo "Default credentials: admin@pentagi.com / admin"
echo ""
echo "IMPORTANT: Configure your LLM provider API key before use!"
echo "See /opt/pentagi/CONFIGURATION.md for detailed setup instructions."
echo "Credentials are stored in /opt/pentagi/CREDENTIALS.txt"
echo ""
echo "Start the service with: systemctl start pentagi"
echo "=========================================="
@@ -0,0 +1,490 @@
# AMD ROCm Addon Installation Guide
This document explains how to install AMD ROCm (Radeon Open Compute) in Proxmox LXC containers using the Heretek Scripts addon.
---
## Overview
AMD ROCm is a software stack for GPU programming on AMD GPUs. It provides a comprehensive development platform for high-performance computing and machine learning applications.
There are **two ways** to install ROCm:
| Method | Description | Use Case |
|--------|-------------|----------|
| **Standalone Addon** | Interactive script run inside existing container | Adding ROCm to an already-created container |
| **Automatic Installation** | Built-in function during container creation | New containers with GPU passthrough enabled |
---
## Prerequisites
### 1. GPU Passthrough Required
Before running this script, you **must** configure GPU passthrough in your LXC container configuration.
**On the Proxmox Host:**
1. Find the render group GID:
```bash
ls -la /dev/dri/renderD128
# Note the GID (typically 104 or similar)
```
2. Edit the container configuration file:
```bash
nano /etc/pve/lxc/<CTID>.conf
```
3. Add GPU device passthrough:
```conf
# For AMD GPUs - add these lines:
dev0: /dev/kfd,gid=<GID>
dev1: /dev/dri/renderD128,gid=<GID>
```
Replace `<GID>` with the group ID from step 1 (e.g., `104`).
4. Restart the container:
```bash
pct stop <CTID>
pct start <CTID>
```
### 2. Supported Operating Systems
The ROCm addon supports the following operating systems in LXC containers:
| OS | Version | Codename |
|----|---------|----------|
| Debian | 12 | bookworm |
| Debian | 13 | trixie |
| Ubuntu | 22.04 | jammy |
| Ubuntu | 24.04 | noble |
### 3. Supported AMD GPUs
- AMD Radeon Instinct (MI series)
- AMD Radeon Pro (professional GPUs)
- Some consumer Radeon GPUs (RX 7000 series recommended)
---
## Installation Methods
### Method 1: Standalone Addon Script (Existing Containers)
Execute the script directly inside your LXC container:
```bash
# Enter the container console
pct enter <CTID>
# Run the ROCm addon script
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/main/tools/addon/rocm.sh)"
```
Or run from the Proxmox host shell:
```bash
# Execute inside a specific container
pct exec <CTID> -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/main/tools/addon/rocm.sh)"
```
### Method 2: Automatic Installation (New Containers)
When creating a new container with AMD GPU passthrough enabled, ROCm is installed automatically via the `_setup_rocm()` function in [`misc/tools.func`](misc/tools.func).
**How it works:**
1. During container creation, if you enable GPU passthrough and select **AMD** as the GPU type
2. The build system automatically:
- Increases disk size by 4GB for ROCm runtime
- Calls `_setup_rocm()` during the container setup phase
- Installs ROCm runtime packages (not the full development SDK)
**Enabling GPU Passthrough:**
When running a container creation script, use the advanced settings to enable GPU passthrough:
```bash
# Example: Creating a container with AMD GPU support
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Heretek-AI/ProxmoxVE/main/ct/llamacpp.sh)"
# During setup, select "Yes" for GPU passthrough and choose "AMD"
```
**Code Reference - [`misc/tools.func`](misc/tools.func:4587-4670):**
```bash
# ROCm compute stack (OpenCL + HIP)
_setup_rocm "$os_id" "$os_codename"
```
The `_setup_rocm()` function:
- Detects OS and maps to appropriate ROCm repository
- Adds AMD ROCm and GPU driver repositories
- Installs runtime packages: `rocm-opencl-runtime`, `rocm-hip-runtime`, `rocm-smi-lib`
- Configures environment variables in `/etc/profile.d/rocm.sh`
- Adds user to `render` and `video` groups
**Code Reference - [`misc/build.func`](misc/build.func:3949-3958):**
```bash
# Increase disk size for AMD ROCm runtime (~4GB extra needed)
if [[ "${GPU_TYPE:-}" == "AMD" ]]; then
local rocm_extra=4
local new_disk_size=$((PCT_DISK_SIZE + rocm_extra))
if pct resize "$CTID" rootfs "${new_disk_size}G" >/dev/null 2>&1; then
msg_ok "Disk resized ${PCT_DISK_SIZE}GB → ${new_disk_size}GB for ROCm"
fi
fi
```
---
## Interactive Prompts
The script is interactive and will prompt for confirmation:
### Fresh Installation
```
____ ____ ________ ___
/ __ \/ __ \/ ____/ |/ /
/ /_/ / / / / / / /|_/ /
/ _, _/ /_/ / /___/ / / /
/_/ |_|\____/\____/_/ /_/
ROCM Installer for Proxmox LXC Containers
⚠ ROCm is not installed.
This will install AMD ROCm on Debian 13
Supported GPUs: AMD Radeon Instinct, Radeon Pro, and some consumer GPUs
Install ROCm? (y/N):
```
### Existing Installation
If ROCm is already installed:
```
⚠ ROCm is already installed.
Uninstall ROCm? (y/N):
Update ROCm? (y/N):
```
---
## Post-Installation
### 1. Update Environment
After installation, update your PATH:
```bash
# Option 1: Source the environment script
source /etc/profile.d/rocm.sh
# Option 2: Log out and back in
exit
pct enter <CTID>
```
### 2. Verify Installation
```bash
# Check ROCm info
rocminfo
# Check GPU status
rocm-smi
```
### 3. Test GPU Access
```bash
# Verify /dev/kfd is accessible
ls -la /dev/kfd
# Should show something like:
# crw-rw---- 1 root render 235, 0 Mar 12 12:00 /dev/kfd
```
---
## Troubleshooting
### "Unable to open /dev/kfd"
This error indicates GPU passthrough is not configured correctly:
1. Verify the container config has the device entries
2. Check the GID matches your system's render group
3. Ensure the container has been restarted after config changes
### ROCm Commands Not Found
If `rocminfo` or `rocm-smi` commands are not found:
```bash
# Source the environment
source /etc/profile.d/rocm.sh
# Or add to your shell profile
echo 'source /etc/profile.d/rocm.sh' >> ~/.bashrc
```
### Permission Denied on GPU Devices
```bash
# Add your user to render and video groups
usermod -aG render,video <username>
# Log out and back in for changes to take effect
```
---
## Uninstallation
To remove ROCm:
1. Run the script again in a container with ROCm installed
2. When prompted, answer `y` to "Uninstall ROCm?"
Or manually:
```bash
apt remove -y rocm
apt autoremove -y
rm -f /etc/apt/sources.list.d/rocm.sources
rm -f /etc/apt/keyrings/rocm.gpg
rm -f /etc/apt/preferences.d/rocm-pin-600
rm -f /etc/profile.d/rocm.sh
```
---
## Updating
To update ROCm to the latest version:
1. Run the script in a container with ROCm installed
2. When prompted, answer `y` to "Update ROCm?"
---
## Technical Details
### Installed Components
| Component | Location |
|-----------|----------|
| ROCm binaries | `/opt/rocm/bin/` |
| ROCm libraries | `/opt/rocm/lib/` |
| Environment script | `/etc/profile.d/rocm.sh` |
| GPG key | `/etc/apt/keyrings/rocm.gpg` |
| APT sources | `/etc/apt/sources.list.d/rocm.sources` |
| Package preferences | `/etc/apt/preferences.d/rocm-pin-600` |
### ROCm Version
The script installs **ROCm 7.2** by default. This version provides:
- HIP runtime
- ROCm libraries
- Development tools
- GPU management utilities
### OS Detection and Repository Mapping
Both the standalone addon and automatic installation use the same OS detection and repository mapping logic to ensure compatibility.
#### OS Detection Flow
```mermaid
flowchart TD
A[Start] --> B{detect_os}
B --> C[OS_TYPE]
B --> D[OS_VERSION]
C --> E{debian or ubuntu?}
E -->|debian| F{version?}
E -->|ubuntu| G{version?}
E -->|other| H[Error: Unsupported OS]
F -->|12| I[bookworm → jammy repo]
F -->|13| J[trixie → noble repo]
F -->|other| H
G -->|22.04| K[jammy → jammy repo]
G -->|24.04| L[noble → noble repo]
G -->|other| H
```
#### Repository Mapping Logic
The ROCm repositories use Ubuntu-based package naming, so Debian systems must map to compatible Ubuntu codenames:
| Host OS | OS Codename | ROCm Repo Codename | Reason |
|---------|-------------|-------------------|--------|
| Debian 12 | bookworm | jammy | Ubuntu 22.04 LTS base |
| Debian 13 | trixie | noble | Ubuntu 24.04 LTS base |
| Ubuntu 22.04 | jammy | jammy | Native support |
| Ubuntu 24.04 | noble | noble | Native support |
**Code Reference - [`tools/addon/rocm.sh`](tools/addon/rocm.sh:48-96):**
```bash
function setup_rocm_repo_mapping() {
ROCM_VERSION="7.2"
case "${OS_TYPE}" in
debian)
OS="Debian"
case "${OS_VERSION}" in
12)
OS_CODENAME="bookworm"
ROCM_REPO_CODENAME="jammy" # Maps to Ubuntu 22.04
;;
13)
OS_CODENAME="trixie"
ROCM_REPO_CODENAME="noble" # Maps to Ubuntu 24.04
;;
*)
msg_error "Unsupported Debian version: ${OS_VERSION}"
exit 1
;;
esac
;;
ubuntu)
OS="Ubuntu"
case "${OS_VERSION}" in
22.04)
OS_CODENAME="jammy"
ROCM_REPO_CODENAME="jammy" # Native
;;
24.04)
OS_CODENAME="noble"
ROCM_REPO_CODENAME="noble" # Native
;;
*)
msg_error "Unsupported Ubuntu version: ${OS_VERSION}"
exit 1
;;
esac
;;
*)
msg_error "Unsupported OS: ${OS_TYPE}"
exit 1
;;
esac
}
```
#### Architecture Check
ROCm is only available for **amd64 (x86_64)** architecture. The automatic installation includes an architecture check:
**Code Reference - [`misc/tools.func`](misc/tools.func:4591-4594):**
```bash
# Only amd64 is supported
if [[ "$(dpkg --print-architecture 2>/dev/null)" != "amd64" ]]; then
msg_warn "ROCm is only available for amd64 — skipping"
return 0
fi
```
#### Repository Configuration
Both methods configure two APT repositories:
1. **ROCm Main Repository** - Core ROCm packages
- URL: `https://repo.radeon.com/rocm/apt/7.2`
- Components: `main`
2. **AMDGPU Driver Repository** - GPU driver components
- URL: `https://repo.radeon.com/amdgpu/latest/ubuntu`
- Components: `main`
**Repository File Structure** (`/etc/apt/sources.list.d/rocm.sources`):
```
Types: deb
URIs: https://repo.radeon.com/rocm/apt/7.2
Suites: noble
Components: main
Architectures: amd64
Signed-By: /etc/apt/keyrings/rocm.gpg
Types: deb
URIs: https://repo.radeon.com/amdgpu/latest/ubuntu
Suites: noble
Components: main
Architectures: amd64
Signed-By: /etc/apt/keyrings/rocm.gpg
```
#### Package Pinning
Both methods configure APT pinning to prioritize ROCm packages:
**File:** `/etc/apt/preferences.d/rocm-pin-600`
```
Package: *
Pin: release o=repo.radeon.com
Pin-Priority: 600
```
This ensures ROCm packages from the Radeon repository take precedence over any conflicting packages from the distribution's default repositories.
---
## Comparison: Standalone vs Automatic Installation
| Feature | Standalone Addon | Automatic Installation |
|---------|-----------------|------------------------|
| **When to use** | Existing containers | New container creation |
| **Disk resize** | Manual (if needed) | Automatic (+4GB) |
| **Packages installed** | Full `rocm` meta-package | Runtime only (smaller) |
| **Interactive** | Yes (prompts for confirmation) | No (automatic) |
| **Uninstall option** | Yes (interactive) | Manual removal only |
| **Update option** | Yes (interactive) | Manual update required |
| **GPU detection** | Warns if `/dev/kfd` missing | Assumes GPU configured |
### Package Differences
**Standalone Addon** ([`tools/addon/rocm.sh`](tools/addon/rocm.sh)):
```bash
apt install -y rocm # Full meta-package (~15GB+ with dev tools)
```
**Automatic Installation** ([`misc/tools.func`](misc/tools.func:4644-4648)):
```bash
apt install -y rocm-opencl-runtime rocm-hip-runtime rocm-smi-lib
# Runtime packages only (smaller footprint)
```
If you need development tools after using automatic installation:
```bash
# Install full ROCm development stack
apt install -y rocm-dev
```
---
## Related Scripts
- **llama.cpp Server** - Uses ROCm for GPU-accelerated LLM inference
- **SwarmUI** - Uses ROCm for Stable Diffusion image generation
- **Lemonade** - Uses ROCm for local LLM inference
---
## Additional Resources
- [AMD ROCm Documentation](https://rocm.docs.amd.com/)
- [AMD GPU Passthrough Guide](https://rocm.docs.amd.com/en/latest/how-to/gpu-isolation.html)
- [Proxmox GPU Passthrough](https://pve.proxmox.com/wiki/Passthrough_Physical_Disk_to_Virtual_Machine)
@@ -0,0 +1,38 @@
# ---------------------------------------
# Treat Shell files as first-class code
# ---------------------------------------
*.sh linguist-detectable=true
*.bash linguist-language=Shell
*.func linguist-language=Shell
*.install linguist-language=Shell
# ---------------------------------------
# Treat Golang files as Go (for /api/)
api/**/*.go linguist-language=Go
# ---------------------------------------
# Treat frontend as JavaScript/TypeScript (optional)
frontend/**/*.ts linguist-language=TypeScript
frontend/**/*.js linguist-language=JavaScript
# ---------------------------------------
# Exclude documentation from stats
*.md linguist-documentation
docs/** linguist-documentation
README.md linguist-documentation
CONTRIBUTING.md linguist-documentation
SECURITY.md linguist-documentation
# ---------------------------------------
# Exclude generated/config files
*.json linguist-generated
frontend/public/json/*.json linguist-generated=false
*.lock linguist-generated
*.yml linguist-generated
*.yaml linguist-generated
.github/** linguist-generated
.vscode/** linguist-generated
# ---------------------------------------
# Standard text handling
* text=auto eol=lf
@@ -0,0 +1,132 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
@@ -0,0 +1,39 @@
title: "[Script request]: "
labels: ["enhancement"]
body:
- type: input
attributes:
label: Application Name
description: Enter the application name.
placeholder: "e.g., Home Assistant"
validations:
required: true
- type: input
attributes:
label: Website
description: Official website or github page.
placeholder: "e.g., https://www.home-assistant.io/"
validations:
required: true
- type: textarea
attributes:
label: Description
description: Explain what the application does and why it should be added to Proxmox VE Helper-Scripts.
placeholder: "e.g., Home Assistant is a popular open-source platform that brings all your smart home devices together in one place. Adding it to Proxmox VE Helper-Scripts would make setup and management on Proxmox easy, letting users quickly get a powerful, self-hosted smart home system up and running."
validations:
required: true
- type: checkboxes
attributes:
label: Due Diligence
options:
- label: "I have searched existing [scripts](https://community-scripts.github.io/Proxmox/scripts) and found no duplicates."
required: true
- label: "I have searched existing [discussions](https://github.com/community-scripts/ProxmoxVE/discussions?discussions_q=) and found no duplicate requests."
required: true
- label: "The application requested has 600+ stars on Github (if applicable), is older than 6 months, actively maintained and has release tarballs published."
required: true
- label: "I understand that not all applications will be accepted due to various reasons and criteria by the community-scripts ORG."
required: true
- type: markdown
attributes:
value: "Thanks for submitting your request! The team will review it and reach out if we need more information."
@@ -0,0 +1,119 @@
name: "🐞 Script Issue Report"
description: Report a specific issue with a script. For other inquiries, please use the Discussions section.
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
## ⚠️ **IMPORTANT - READ FIRST**
- 🔍 **Search first:** Before submitting, check if the issue has already been reported or resolved in [closed issues](https://github.com/community-scripts/ProxmoxVE/issues?q=is%3Aissue+is%3Aclosed). If found, comment on that issue instead of creating a new one.
Alternatively, check the **[Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)** under the *"Announcement"* or *"Guide"* categories for relevant information.
- 🔎 If you encounter `[ERROR] in line 23: exit code *: while executing command "$@" > /dev/null 2>&1`, rerun the script with verbose mode before submitting the issue.
- 📜 **Read the script:** Familiarize yourself with the script's content and its purpose. This will help you understand the issue better and provide more relevant information
Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
- type: input
id: guidelines
attributes:
label: ✅ Have you read and understood the above guidelines?
placeholder: "yes"
validations:
required: true
- type: dropdown
id: verbose_run
attributes:
label: 🔎 Did you run the script with verbose mode enabled?
description: "Required for debugging any script issue. A verbose log is mandatory."
options:
- ""
- "Yes, verbose mode was enabled and the output is included below"
- "No (this issue will likely be closed automatically)"
validations:
required: true
- type: input
id: script_name
attributes:
label: 📜 What is the name of the script you are using?
placeholder: "e.g., NextcloudPi, Zigbee2MQTT"
validations:
required: true
- type: input
id: script_command
attributes:
label: 📂 What was the exact command used to execute the script?
placeholder: "e.g., bash -c \"$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/zigbee2mqtt.sh)\" or \"update\""
validations:
required: true
- type: checkboxes
validations:
required: true
attributes:
label: ⚙️ What settings are you using?
options:
- label: Default Settings
- label: Advanced Settings
- type: markdown
attributes:
value: "💡 **Tip:** If you are using Advanced Settings, please test with Default Settings before submitting an issue."
- type: dropdown
id: linux_distribution
attributes:
label: 🖥️ Which Linux distribution are you using?
options:
-
- Alpine
- Debian 11
- Debian 12
- Debian 13
- Ubuntu 22.04
- Ubuntu 24.04
- Ubuntu 24.10
validations:
required: true
- type: input
id: pve_version
attributes:
label: 📈 Which Proxmox version are you on?
placeholder: "run pveversion in your PVE node console"
validations:
required: true
- type: textarea
id: issue_description
attributes:
label: 📝 Provide a clear and concise description of the issue.
validations:
required: true
- type: textarea
id: steps_to_reproduce
attributes:
label: 🔄 Steps to reproduce the issue.
placeholder: "e.g., Step 1: ..., Step 2: ..."
validations:
required: true
- type: textarea
id: error_output
attributes:
label: ❌ Paste the full error output (if available).
placeholder: "Include any relevant logs or error messages."
validations:
required: true
- type: textarea
id: additional_context
attributes:
label: 🖼️ Additional context (optional).
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
validations:
required: false
@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 🌟 new Script request
url: https://github.com/community-scripts/ProxmoxVE/discussions/new?category=request-script
about: For feature/script requests, please use the Discussions section.
- name: 🤔 Questions and Help
url: https://github.com/community-scripts/ProxmoxVE/discussions
about: For suggestions or questions, please use the Discussions section.
- name: 💻 Discord
url: https://discord.gg/jsYVk5JBxq
about: Join our Discord server to chat with other users in the Proxmox Helper Scripts community.
@@ -0,0 +1,33 @@
name: "✨ Feature Request"
description: "Suggest a new feature or enhancement. (not for script requests)"
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
# ✨ **Feature Request**
Have an idea for a new feature? Share your thoughts below!
- type: input
id: feature_summary
attributes:
label: "🌟 Briefly describe the feature"
placeholder: "e.g., Add support for XYZ"
validations:
required: true
- type: textarea
id: feature_description
attributes:
label: "📝 Detailed description"
placeholder: "Explain the feature in detail"
validations:
required: true
- type: textarea
id: use_case
attributes:
label: "💡 Why is this useful?"
placeholder: "Describe the benefit of this feature"
validations:
required: true
@@ -0,0 +1,75 @@
name: "🌐 Website Issue Report"
description: Report an issue, an optimization request or an documentation issue specifically related to the website.
labels: "website"
body:
- type: markdown
attributes:
value: |
**IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure.
- Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one.
- If the problem is related to a bug in the website, kindly check for browser compatibility and ensure the issue occurs in multiple browsers before submitting.
- For suggestions, questions, or feature requests, please use the [Discussions section.](https://github.com/community-scripts/ProxmoxVE/discussions)
- type: input
id: guidelines
attributes:
label: Please verify that you have read and understood the guidelines.
placeholder: 'yes'
validations:
required: true
- type: dropdown
id: issue_type
validations:
required: true
attributes:
label: What type of issue is this?
options:
-
- Bug
- Optimization
- Documentation
- Other
- type: textarea
id: bug_description
attributes:
label: A clear and concise description of the issue.
validations:
required: true
- type: dropdown
id: browser
validations:
required: true
attributes:
label: Which browser are you using?
options:
-
- Chrome
- Firefox
- Safari
- Edge
- Other
- type: markdown
attributes:
value: |
**If the issue is browser-related**, please provide information on the version and platform (Windows, MacOS, Linux, etc.).
- type: textarea
id: screenshot
attributes:
label: If relevant, including screenshots or a code block can be helpful in clarifying the issue.
placeholder: "Code blocks begin and conclude by enclosing the code with three backticks (```) above and below it."
validations:
required: false
- type: textarea
id: reproduce
attributes:
label: Please provide detailed steps to reproduce the issue.
placeholder: "First do this, then this ..."
validations:
required: false
@@ -0,0 +1,25 @@
name: "🛠️ Task / General Request"
description: "Request a general task, improvement, or refactor."
labels: ["task"]
body:
- type: markdown
attributes:
value: |
# 🛠️ **Task / General Request**
Request a task that isn't a bug or feature request.
- type: input
id: task_summary
attributes:
label: "📌 Task summary"
placeholder: "e.g., Refactor XYZ"
validations:
required: true
- type: textarea
id: task_details
attributes:
label: "📋 Task details"
placeholder: "Explain what needs to be done"
validations:
required: true
@@ -0,0 +1,137 @@
{
"new script": [
{
"fileStatus": "added",
"includeGlobs": [
"ct/**",
"install/**",
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
}
],
"update script": [
{
"fileStatus": "modified",
"includeGlobs": [
"ct/**",
"install/**",
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
}
],
"delete script": [
{
"fileStatus": "removed",
"includeGlobs": [
"ct/**",
"install/**",
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
}
],
"vm": [
{
"fileStatus": null,
"includeGlobs": [
"vm/**"
],
"excludeGlobs": []
}
],
"tools": [
{
"fileStatus": null,
"includeGlobs": [
"tools/**"
],
"excludeGlobs": []
}
],
"addon": [
{
"fileStatus": null,
"includeGlobs": [
"tools/addon/**"
],
"excludeGlobs": []
}
],
"pve-tool": [
{
"fileStatus": null,
"includeGlobs": [
"tools/pve/**"
],
"excludeGlobs": []
}
],
"core": [
{
"fileStatus": null,
"includeGlobs": [
"misc/*.func"
],
"excludeGlobs": [
"misc/api.func"
]
}
],
"documentation": [
{
"fileStatus": null,
"includeGlobs": [
"docs/**"
],
"excludeGlobs": []
}
],
"github": [
{
"fileStatus": null,
"includeGlobs": [
".github/**",
"README.md",
"SECURITY.md",
"LICENSE",
"CHANGELOG.md"
],
"excludeGlobs": []
}
],
"api": [
{
"fileStatus": null,
"includeGlobs": [
"api/**",
"misc/api.func"
],
"excludeGlobs": []
}
],
"website": [
{
"fileStatus": null,
"includeGlobs": [
"frontend/**"
],
"excludeGlobs": [
"frontend/public/json/**"
]
}
],
"json": [
{
"fileStatus": "modified",
"includeGlobs": [
"frontend/public/json/**"
],
"excludeGlobs": []
}
]
}
@@ -0,0 +1,212 @@
[
{
"title": "🆕 New Scripts",
"labels": [
"new script"
]
},
{
"title": "🚀 Updated Scripts",
"labels": [
"update script"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "🔧 Refactor",
"labels": [
"refactor"
],
"notes": []
}
]
},
{
"title": "🗑️ Deleted Scripts",
"labels": [
"delete script"
]
},
{
"title": "💾 Core",
"labels": [
"core"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "🔧 Refactor",
"labels": [
"refactor"
],
"notes": []
}
]
},
{
"title": "🧰 Tools",
"labels": [
"tools"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "🔧 Refactor",
"labels": [
"refactor"
],
"notes": []
}
]
},
{
"title": "📚 Documentation",
"labels": [
"documentation"
]
},
{
"title": "📂 Github",
"labels": [
"github"
]
},
{
"title": "📡 API",
"labels": [
"api"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "🔧 Refactor",
"labels": [
"refactor"
],
"notes": []
}
]
},
{
"title": "🌐 Website",
"labels": [
"website"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "📝 Script Information",
"labels": [
"json"
],
"notes": []
}
]
},
{
"title": "❔ Uncategorized",
"labels": [
"needs triage"
]
}
]
@@ -0,0 +1,65 @@
## 2022-01-30
### Changed
- **Zigbee2MQTT LXC**
- Clean up / Improve script
- Improve documentation
## 2022-01-29
### Changed
- **Node-Red LXC**
- Clean up / Improve script
- Improve documentation
## 2022-01-25
### Changed
- **Jellyfin Media Server LXC**
- new script
## 2022-01-24
### Changed
- **Plex Media Server LXC**
- better Hardware Acceleration Support
- `va-driver-all` is preinstalled
- now using Ubuntu 21.10
- **misc**
- new GUI script to copy data from one Plex Media Server LXC to another Plex Media Server LXC
## Initial Catch up - 2022-01-23
### Changed
- **Plex Media Server LXC**
- add Hardware Acceleration Support
- add script to install Intel Drivers
- **Zwavejs2MQTT LXC**
- new script to solve no auto start at boot
- **Nginx Proxy Manager LXC**
- new script to use Debian 11
- **Ubuntu 21.10 LXC**
- new script
- **Mariadb LXC**
- add MariaDB Package Repository
- **MQTT LXC**
- add Eclipse Mosquitto Package Repository
- **Home Assistant Container LXC**
- change if ZFS filesystem is detected, execute automatic installation of static fuse-overlayfs
- add script for easy Home Assistant update
- **Home Assistant Container LXC (Podman)**
- change if ZFS filesystem is detected, execute automatic installation of static fuse-overlayfs
- **Home Assistant OS VM**
- change disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk
- clean up
- **Proxmox VE 7 Post Install**
- new *No-Nag* method
- **misc**
- new GUI script to copy data from one Home Assistant LXC to another Home Assistant LXC
- new GUI script to copy data from one Zigbee2MQTT LXC to another Zigbee2MQTT LXC
@@ -0,0 +1,143 @@
## 2022-02-28
### Changed
- **Vaultwarden LXC**
- Add Update Script
## 2022-02-24
### Changed
- **Nginx Proxy Manager LXC**
- New V2 Install Script
## 2022-02-23
### Changed
- **Adguard Home LXC**
- New V2 Install Script
- **Zigbee2MQTT LXC**
- New V2 Install Script
- **Home Assistant Container LXC**
- Update Menu usability improvements
## 2022-02-22
### Changed
- **Home Assistant Container LXC**
- New V2 Install Script
- **Node-Red LXC**
- New V2 Install Script
- **Mariadb LXC**
- New V2 Install Script
- **MQTT LXC**
- New V2 Install Script
- **Debian 11 LXC**
- New V2 Install Script
- **Ubuntu 21.10 LXC**
- New V2 Install Script
## 2022-02-20
### Changed
- **Home Assistant Container LXC**
- New Script to migrate to the latest Update Menu
## 2022-02-19
### Changed
- **Nginx Proxy Manager LXC**
- Add Update Script
- **Vaultwarden LXC**
- Make unattended install & Cleanup Script
## 2022-02-18
### Changed
- **Node-Red LXC**
- Add Install Themes Script
## 2022-02-16
### Changed
- **Home Assistant Container LXC**
- Add Options to Update Menu
## 2022-02-14
### Changed
- **Home Assistant Container LXC**
- Add Update Menu
## 2022-02-13
### Changed
- **Mariadb LXC**
- Add Adminer (formerly phpMinAdmin), a full-featured database management tool
## 2022-02-12
### Changed
- **Home Assistant Container LXC (Podman)**
- Add Yacht web interface for managing Podman containers
- new GUI script to copy data from a **Home Assistant LXC** to a **Podman Home Assistant LXC**
- Improve documentation for several LXC's
## 2022-02-10
### Changed
- **GamUntu LXC**
- New Script
- **Jellyfin Media Server LXC**
- new script to fix [start issue](https://github.com/tteck/Proxmox/issues/29#issue-1127457380)
- **MotionEye NVR LXC**
- New script
## 2022-02-09
### Changed
- **Zigbee2MQTT LXC**
- added USB passthrough during installation (no extra script)
- Improve documentation
- **Zwavejs2MQTT LXC**
- added USB passthrough during installation (no extra script)
- **Jellyfin Media Server LXC**
- Moved to testing due to issues.
- Changed install method.
- **Home Assistant Container LXC (Podman)**
- add script for easy Home Assistant update
## 2022-02-06
### Changed
- **Debian 11 LXC**
- Add Docker Support
- **Ubuntu 21.10 LXC**
- Add Docker Support
## 2022-02-05
### Changed
- **Vaultwarden LXC**
- New script
## 2022-02-01
### Changed
- **All Scripts**
- Fix issue where some networks were slow to assign a IP address to the container causing scripts to fail.
@@ -0,0 +1,168 @@
## 2022-03-28
### Changed
- **Docker LXC**
- Add Docker Compose Option (@wovalle)
## 2022-03-27
### Changed
- **Heimdall Dashboard LXC**
- New Update Script
## 2022-03-26
### Changed
- **UniFi Network Application LXC**
- New Script V2
- **Omada Controller LXC**
- New Script V2
## 2022-03-25
### Changed
- **Proxmox CPU Scaling Governor**
- New Script
## 2022-03-24
### Changed
- **Plex Media Server LXC**
- Switch to Ubuntu 20.04 to support HDR tone mapping
- **Docker LXC**
- Add Portainer Option
## 2022-03-23
### Changed
- **Heimdall Dashboard LXC**
- New Script V2
## 2022-03-20
### Changed
- **Scripts** (V2)
- ADD choose between Automatic or Manual DHCP
## 2022-03-18
### Changed
- **Technitium DNS LXC**
- New Script V2
- **WireGuard LXC**
- Add WGDashboard
## 2022-03-17
### Changed
- **Docker LXC**
- New Script V2
## 2022-03-16
### Changed
- **PhotoPrism LXC**
- New Update/Branch Script
## 2022-03-15
### Changed
- **Dashy LXC**
- New Update Script
## 2022-03-14
### Changed
- **Zwavejs2MQTT LXC**
- New Update Script
## 2022-03-12
### Changed
- **PhotoPrism LXC**
- New Script V2
## 2022-03-11
### Changed
- **Vaultwarden LXC**
- New V2 Install Script
## 2022-03-08
### Changed
- **Scripts** (V2)
- Choose between Privileged or Unprivileged CT and Automatic or Password Login
- **ESPHome LXC**
- New V2 Install Script
- **Zwavejs2MQTT LXC**
- New V2 Install Script
- **Motioneye LXC**
- New V2 Install Script
- **Pihole LXC**
- New V2 Install Script
- **GamUntu LXC**
- New V2 Install Script
## 2022-03-06
### Changed
- **Zwavejs2MQTT LXC**
- New GUI script to copy data from one Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC
## 2022-03-05
### Changed
- **Homebridge LXC**
- New Script V2
## 2022-03-04
### Changed
- **Proxmox Kernel Clean**
- New Script
## 2022-03-03
### Changed
- **WireGuard LXC**
- New Script V2
## 2022-03-02
### Changed
- **Proxmox LXC Updater**
- New Script
- **Dashy LXC**
- New Script V2
- **Grafana LXC**
- New Script V2
- **InfluxDB/Telegraf LXC**
- New Script V2
## 2022-03-01
### Changed
- **Daemon Sync Server LXC**
- New Script V2
@@ -0,0 +1,114 @@
## 2022-04-28
### Changed
- **v3 Script**
- Remove Internet Check
## 2022-04-27
### Changed
- **Home Assistant OS VM**
- ADD Option to set Bridge, VLAN and MAC Address
- **v3 Script**
- Improve Internet Check (prevent ‼ ERROR 4@57)
## 2022-04-26
### Changed
- **Home Assistant OS VM**
- Fixed bad path
- ADD Option to create VM using Latest or Stable image
- **UniFi Network Application LXC**
- ADD Local Controller Option
## 2022-04-25
### Changed
- **v3 Script**
- Improve Error Handling
## 2022-04-23
### Changed
- **v3 Script**
- ADD Internet Connection Check
- **Proxmox VE 7 Post Install**
- NEW v3 Script
- **Proxmox Kernel Clean**
- NEW v3 Script
## 2022-04-22
### Changed
- **Omada Controller LXC**
- Update script to install version 5.1.7
- **Uptime Kuma LXC**
- ADD Update script
## 2022-04-20
### Changed
- **Ubuntu LXC**
- ADD option to install version 20.04 or 21.10
- **v3 Script**
- ADD option to set Bridge
## 2022-04-19
### Changed
- **ALL LXC's**
- New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162)
- **ioBroker LXC**
- New Script V3
## 2022-04-13
### Changed
- **Uptime Kuma LXC**
- New Script V2
## 2022-04-11
### Changed
- **Proxmox LXC Updater**
- ADD option to skip stopped containers
- **Proxmox VE 7 Post Install**
- ADD PVE 7 check
## 2022-04-10
### Changed
- **Debian 11 LXC**
- ADD An early look at the v3 install script
## 2022-04-09
### Changed
- **NocoDB LXC**
- New Script V2
## 2022-04-05
### Changed
- **MeshCentral LXC**
- New Script V2
## 2022-04-01
### Changed
- **Scripts** (V2)
- FIX Pressing enter without making a selection first would cause an Error
@@ -0,0 +1,64 @@
## 2022-05-29
### Changed
- **Vaultwarden LXC**
- Code refactoring
- **CrowdSec**
- NEW Script
## 2022-05-21
### Changed
- **Home Assistant OS VM**
- Code refactoring
## 2022-05-19
### Changed
- **Keycloak LXC**
- NEW Script
## 2022-05-18
### Changed
- **File Browser**
- NEW Script
## 2022-05-13
### Changed
- **PostgreSQL LXC**
- NEW Script
## 2022-05-10
### Changed
- **deCONZ LXC**
- NEW Script
## 2022-05-07
### Changed
- **NocoDB LXC**
- ADD update script
## 2022-05-06
### Changed
- **PhotoPrism LXC**
- ADD GO Dependencies for full functionality
## 2022-05-05
### Changed
- **Ubuntu LXC**
- ADD option to define version (18.04 20.04 21.10 22.04)
@@ -0,0 +1,80 @@
## 2022-07-26
### Changed
- **Home Assistant OS VM**
- Set the real time clock (RTC) to local time.
- Disable the USB tablet device (save resources / not needed).
## 2022-07-24
### Changed
- **Home Assistant OS VM**
- Present the drive to the guest as a solid-state drive rather than a rotational hard disk. There is no requirement that the underlying storage actually be backed by SSD's.
- When the VMs filesystem marks blocks as unused after deleting files, the SCSI controller will relay this information to the storage, which will then shrink the disk image accordingly.
- 👉 [more info](https://github.com/tteck/Proxmox/discussions/378)
## 2022-07-22
### Changed
- **n8n LXC** (thanks to @cyakimov)
- NEW Script
## 2022-07-21
### Changed
- **grocy LXC**
- NEW Script
## 2022-07-17
### Changed
- **Vaultwarden LXC**
- NEW Vaultwarden Update (post 2022-05-29 installs only) Script
- NEW Web-vault Update (any) Script
## 2022-07-14
### Changed
- **MagicMirror Server LXC**
- NEW Script
## 2022-07-13
### Changed
- **Proxmox Edge Kernel Tool**
- NEW Script
## 2022-07-11
### Changed
- **Home Assistant OS VM**
- Supports lvmthin, zfspool, nfs, dir and btrfs storage types.
## 2022-07-08
### Changed
- **openHAB LXC**
- NEW Script
## 2022-07-03
### Changed
- **Tailscale**
- NEW Script
## 2022-07-01
### Changed
- **Home Assistant OS VM**
- Allow different storage types (lvmthin, nfs, dir).
@@ -0,0 +1,57 @@
## 2022-08-31
### Changed
- **All LXC's**
- Add Internet & DNS Check
## 2022-08-22
### Changed
- **Wiki.js LXC**
- NEW Script
- **Emby Media Server LXC**
- NEW Script
## 2022-08-20
### Changed
- **Mikrotik RouterOS VM**
- NEW Script
## 2022-08-19
### Changed
- **PhotoPrism LXC**
- Fixed .env bug (Thanks @cklam2)
## 2022-08-13
### Changed
- **Home Assistant OS VM**
- Option to create VM using Stable, Beta or Dev Image
## 2022-08-11
### Changed
- **Home Assistant OS VM**
- Validate Storage
## 2022-08-04
### Changed
- **VS Code Server**
- NEW Script
## 2022-08-02
### Changed
- **All LXC/VM**
- v4 Script - Whiptail menu's
@@ -0,0 +1,81 @@
## 2022-09-29
### Changed
- **Home Assistant Container LXC**
- If the LXC is created Privileged, the script will automatically set up USB passthrough.
- **Home Assistant Core LXC**
- NEW Script
- **PiMox HAOS VM**
- NEW Script
## 2022-09-23
### Changed
- **EMQX LXC**
- NEW Script
## 2022-09-22
### Changed
- **NextCloudPi LXC**
- NEW Script
## 2022-09-21
### Changed
- **Proxmox Backup Server Post Install**
- NEW Script
- **Z-wave JS UI LXC**
- NEW Script (and all sub scripts 🤞)
- **Zwave2MQTT LXC**
- Bye Bye Script
## 2022-09-20
### Changed
- **OpenMediaVault LXC**
- NEW Script
## 2022-09-16
### Changed
- **Paperless-ngx LXC**
- NEW Script (Thanks @Donkeykong307)
## 2022-09-11
### Changed
- **Trilium LXC**
- NEW Script
## 2022-09-10
### Changed
- **Syncthing LXC**
- NEW Script
## 2022-09-09
### Changed
- **CasaOS LXC**
- NEW Script
- **Proxmox Kernel Clean**
- Now works with Proxmox Backup Server
## 2022-09-08
### Changed
- **Navidrome LXC**
- NEW Script
- **Homepage LXC**
- NEW Script
@@ -0,0 +1,57 @@
## 2022-11-27
### Changed
- **Shinobi LXC**
- NEW Script
## 2022-11-24
### Changed
- **Home Assistant OS VM**
- Add option to set machine type during VM creation (Advanced)
## 2022-11-23
### Changed
- **All LXC's**
- Add option to enable root ssh access during LXC creation (Advanced)
## 2022-11-21
### Changed
- **Proxmox LXC Updater**
- Now updates Ubuntu, Debian, Devuan, Alpine Linux, CentOS-Rocky-Alma, Fedora, ArchLinux [(@Uruknara)](https://github.com/community-scripts/ProxmoxVE/commits?author=Uruknara)
## 2022-11-13
### Changed
- **All LXC's**
- Add option to continue upon Internet NOT Connected
## 2022-11-11
### Changed
- **HA Bluetooth Integration Preparation**
- [NEW Script](https://github.com/tteck/Proxmox/discussions/719)
## 2022-11-04
### Changed
- **Scrypted LXC**
- NEW Script
## 2022-11-01
### Changed
- **Alpine LXC**
- NEW Script
- **Arch LXC**
- NEW Script
@@ -0,0 +1,67 @@
## 2022-12-31
### Changed
- **v5 Scripts** (Testing before moving forward https://github.com/tteck/Proxmox/discussions/881)
- Adguard Home LXC
- Docker LXC
- Home Assistant Core LXC
- PhotoPrism LXC
- Shinobi NVR LXC
- Vaultwarden LXC
## 2022-12-27
### Changed
- **Home Assistant Container LXC**
- Add an option to use Fuse Overlayfs (ZFS) (Advanced)
- **Docker LXC**
- Add an option to use Fuse Overlayfs (ZFS) (Advanced)
- If the LXC is created Privileged, the script will automatically set up USB passthrough.
## 2022-12-22
### Changed
- **All LXC's**
- Add an option to run the script in Verbose Mode (Advanced)
## 2022-12-20
### Changed
- **Hyperion LXC**
- NEW Script
## 2022-12-17
### Changed
- **Home Assistant Core LXC**
- Linux D-Bus Message Broker
- Mariadb & PostgreSQL Ready
- Bluetooth Ready
- Fix for Inconsistent Dependency Versions (dbus-fast & bleak)
## 2022-12-16
### Changed
- **Home Assistant Core LXC**
- Python 3.10.8
## 2022-12-09
### Changed
- **Change Detection LXC**
- NEW Script
## 2022-12-03
### Changed
- **All LXC's**
- Add options to set DNS Server IP Address and DNS Search Domain (Advanced)
@@ -0,0 +1,143 @@
## 2023-01-28
### Changed
- **LXC Cleaner**
- Code refactoring to give the user the option to choose whether cache or logs will be deleted for each app/service.
- Leaves directory structure intact
## 2023-01-27
### Changed
- **LXC Cleaner**
- NEW Script
## 2023-01-26
### Changed
- **ALL LXC's**
- Add an option to disable IPv6 (Advanced)
## 2023-01-25
### Changed
- **Home Assistant OS VM**
- switch to v5
- add an option to set MTU size (Advanced)
- add arch check (no ARM64) (issue from community.home-assistant.io)
- add check to insure VMID isn't already used before VM creation (Advanced) (issue from forum.proxmox.com)
- code refactoring
- **PiMox Home Assistant OS VM**
- switch to v5
- add an option to set MTU size (Advanced)
- add arch check (no AMD64)
- add pve check (=>7.2)
- add check to insure VMID isn't already used before VM creation (Advanced)
- code refactoring
- **All LXC's**
- add arch check (no ARM64) (issue from forum.proxmox.com)
## 2023-01-24
### Changed
- **Transmission LXC**
- NEW Script
## 2023-01-23
### Changed
- **ALL LXC's**
- Add [Midnight Commander (mc)](https://www.linuxcommand.org/lc3_adv_mc.php)
## 2023-01-22
### Changed
- **Autobrr LXC**
- NEW Script
## 2023-01-21
### Changed
- **Kavita LXC**
- NEW Script
## 2023-01-19
### Changed
- **SABnzbd LXC**
- NEW Script
## 2023-01-17
### Changed
- **Homer LXC**
- NEW Script
## 2023-01-14
### Changed
- **Tdarr LXC**
- NEW Script
- **Deluge LXC**
- NEW Script
## 2023-01-13
### Changed
- **Lidarr LXC**
- NEW Script
- **Prowlarr LXC**
- NEW Script
- **Radarr LXC**
- NEW Script
- **Readarr LXC**
- NEW Script
- **Sonarr LXC**
- NEW Script
- **Whisparr LXC**
- NEW Script
## 2023-01-12
### Changed
- **ALL LXC's**
- Add an option to set MTU size (Advanced)
## 2023-01-11
### Changed
- **Home Assistant Core LXC**
- Auto Initialize
- **Cronicle Primary/Worker LXC**
- NEW Script
## 2023-01-09
### Changed
- **ALL LXC's**
- v5
- **k0s Kubernetes LXC**
- NEW Script
- **Podman LXC**
- NEW Script
## 2023-01-04
### Changed
- **YunoHost LXC**
- NEW Script
@@ -0,0 +1,55 @@
## 2023-02-24
### Changed
- **qBittorrent LXC** (Thanks @romka777)
- NEW Script
- **Jackett LXC** (Thanks @romka777)
- NEW Script
## 2023-02-23
### Changed
- **Proxmox LXC Updater**
- Skip all templates, allowing for the starting, updating, and shutting down of containers to be resumed automatically.
- Exclude an additional container by adding the CTID at the end of the shell command ( -s 103).
## 2023-02-16
### Changed
- **RSTPtoWEB LXC**
- NEW Script
- **go2rtc LXC**
- NEW Script
## 2023-02-12
### Changed
- **OliveTin**
- NEW Script
## 2023-02-10
### Changed
- **Home Assistant OS VM**
- Code Refactoring
## 2023-02-05
### Changed
- **Devuan LXC**
- NEW Script
## 2023-02-02
### Changed
- **Audiobookshelf LXC**
- NEW Script
- **Rocky Linux LXC**
- NEW Script
@@ -0,0 +1,74 @@
## 2023-03-31
### Changed
- **Home Assistant OS VM**
- Include a choice within the "Advanced" settings to configure the disk cache between none (default) or Write Through.
## 2023-03-27
### Changed
- **Removed Alpine-ESPHome LXC**
- Nonoperational
- **All Scripts**
- Incorporate code that examines whether SSH is being used and, if yes, offers a suggestion against it without restricting or blocking its usage.
## 2023-03-25
### Changed
- **Alpine-ESPHome LXC**
- NEW Script
- **Alpine-Whoogle LXC**
- NEW Script
## 2023-03-22
### Changed
- **The latest iteration of the scripts**
- Going forward, versioning will no longer be utilized in order to avoid breaking web-links in blogs and YouTube videos.
- The scripts have been made more legible as the repetitive code has been moved to function files, making it simpler to share among the scripts and hopefully easier to maintain. This also makes it simpler to contribute to the project.
- When a container is created with privileged mode enabled, the USB passthrough feature is automatically activated.
## 2023-03-18
### Changed
- **Alpine-AdGuard Home LXC** (Thanks @nicedevil007)
- NEW Script
- **Alpine-Docker LXC**
- NEW Script
- **Alpine-Zigbee2MQTT LXC**
- NEW Script
## 2023-03-15
### Changed
- **Alpine-Grafana LXC** (Thanks @nicedevil007)
- NEW Script
## 2023-03-10
### Changed
- **Proxmox LXC Updater**
- You can use the command line to exclude multiple containers simultaneously.
## 2023-03-08
### Changed
- **Proxmox CPU Scaling Governor**
- Menu options dynamically based on the available scaling governors.
## 2023-03-07
### Changed
- **Alpine-Vaultwarden LXC**
- NEW Script
- **All LXC Scripts**
- Retrieve the time zone from Proxmox and configure the container to use the same time zone
@@ -0,0 +1,65 @@
## 2023-04-30
### Changed
- **Proxmox VE Monitor-All**
- NEW Script
- Replaces Proxmox VE LXC Monitor
## 2023-04-28
### Changed
- **Proxmox VE LXC Monitor**
- NEW Script
## 2023-04-26
### Changed
- **The site can now be accessed through a more memorable URL, which is [helper-scripts.com](http://helper-scripts.com).**
## 2023-04-23
### Changed
- **Non-Alpine LXC's**
- Advanced settings provide the option for users to switch between Debian and Ubuntu distributions. However, some applications or services, such as Deconz, grocy or Omada, may not be compatible with the selected distribution due to dependencies.
## 2023-04-16
### Changed
- **Home Assistant Core LXC**
- Python 3.11.2
## 2023-04-15
### Changed
- **InfluxDB LXC**
- Choosing InfluxDB v1 will result in Chronograf being installed automatically.
- **[User Submitted Guides](https://github.com/community-scripts/ProxmoxVE/blob/main/USER_SUBMITTED_GUIDES.md)**
- Informative guides that demonstrate how to install various software packages using Proxmox VE Helper Scripts.
## 2023-04-14
### Changed
- **Cloudflared LXC**
- NEW Script
## 2023-04-05
### Changed
- **Jellyfin LXC**
- Set Ubuntu 22.04 as default
- Use the Deb822 format jellyfin.sources configuration (jellyfin.list configuration has been obsoleted)
## 2023-04-02
### Changed
- **Home Assistant OS VM**
- Include a choice within the "Advanced" settings to configure the CPU model between kvm64 (default) or host.
@@ -0,0 +1,69 @@
## 2023-05-27
### Changed
- **Proxmox VE 7 Post Install**
- If an Intel N-series processor is detected, ~the script provides options to install both the Proxmox 6.2 kernel and the Intel microcode.~ and using PVE7, recommend using PVE8
## 2023-05-23
### Changed
- **OpenWrt VM**
- NEW Script
## 2023-05-17
### Changed
- **Alpine-AdGuard Home LXC**
- Removed, it wasn't installed through the Alpine package manager.
- **Alpine-Whoogle LXC**
- Removed, it wasn't installed through the Alpine package manager.
## 2023-05-16
### Changed
- **Proxmox VE LXC Updater**
- Add information about the boot disk, which provides an easy way to determine if you need to expand the disk.
- **Proxmox VE Processor Microcode**
- [Intel microcode-20230512 Release](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20230512)
## 2023-05-13
### Changed
- **Tautulli LXC**
- NEW Script
## 2023-05-12
### Changed
- **Bazarr LXC**
- NEW Script
## 2023-05-08
### Changed
- **Proxmox VE Intel Processor Microcode**
- Renamed to **Proxmox VE Processor Microcode**
- Automatically identifies the processor vendor (Intel/AMD) and installs the appropriate microcode.
## 2023-05-07
### Changed
- **FHEM LXC**
- NEW Script
## 2023-05-01
### Changed
- **OctoPrint LXC**
- NEW Script
- **Proxmox VE Intel Processor Microcode**
- NEW Script
@@ -0,0 +1,45 @@
## 2023-06-18
### Changed
- **OpenObserve LXC**
- NEW Script
## 2023-06-17
### Changed
- **UniFi Network Application LXC**
- Now distribution agnostic.
- **Omada Controller LXC**
- Now distribution agnostic.
## 2023-06-16
### Changed
- **Proxmox VE Monitor-All**
- Skip instances based on onboot and templates. [8c2a3cc](https://github.com/community-scripts/ProxmoxVE/commit/8c2a3cc4d774fa13d17f695d6bdf9a4deedb1372).
## 2023-06-12
### Changed
- **Proxmox VE Edge Kernel**
- Removed, with the Proxmox opt-in kernels and the upcoming Proxmox Virtual Environment 8, edge kernels are no longer needed.
- **Proxmox VE Kernel Clean**
- Now compatible with PVE8.
## 2023-06-11
### Changed
- **Proxmox VE Post Install**
- Now compatible with both Proxmox Virtual Environment 7 (PVE7) and Proxmox Virtual Environment 8 (PVE8).
## 2023-06-02
### Changed
- **Proxmox VE 7 Post Install**
- In a non-clustered environment, you can choose to disable high availability, which helps save system resources.
@@ -0,0 +1,40 @@
## 2023-07-24
### Changed
- **Ombi LXC**
- NEW Script
## 2023-07-23
### Changed
- **Zoraxy LXC**
- NEW Script
## 2023-07-18
### Changed
- **Proxmox VE Cron LXC Updater**
- NEW Script
## 2023-07-11
### Changed
- **Scrypted LXC**
- Add VAAPI hardware transcoding
## 2023-07-07
### Changed
- **Real-Debrid Torrent Client LXC**
- NEW Script
## 2023-07-05
### Changed
- There have been more than 110 commits since June 18th, although not all of them are significant, with a majority focused on ensuring compatibility with Proxmox VE 8 and Debian 12.
@@ -0,0 +1,80 @@
## 2023-08-31
### Changed
- **TurnKey ZoneMinder LXC**
- NEW Script
- **TurnKey OpenVPN LXC**
- NEW Script
## 2023-08-30
### Changed
- **TurnKey**
- Introducing a **NEW** Category on the Site.
- My intention is to maintain the TurnKey scripts in their simplest form, contained within a single file, and with minimal options, if any.
- **TurnKey Core LXC**
- NEW Script
- **TurnKey File Server LXC**
- NEW Script
- **TurnKey Gitea LXC**
- NEW Script
- **TurnKey GitLab LXC**
- NEW Script
- **TurnKey Nextcloud LXC**
- NEW Script
- **TurnKey Observium LXC**
- NEW Script
- **TurnKey ownCloud LXC**
- NEW Script
- **TurnKey Torrent Server LXC**
- NEW Script
- **TurnKey Wordpress LXC**
- NEW Script
## 2023-08-24
### Changed
- **qBittorrent LXC**
- Added back to repository with UPnP disabled and password changed.
## 2023-08-24
### Changed
- **qBittorrent LXC**
- Removed from this repository for potential malicious hidden code https://github.com/tteck/Proxmox/discussions/1725
## 2023-08-16
### Changed
- **Homarr LXC**
- NEW Script
## 2023-08-10
### Changed
- **Proxmox VE Processor Microcode**
- AMD microcode-20230808 Release
## 2023-08-09
### Changed
- **Omada Controller LXC**
- Update via script
- **Proxmox VE Processor Microcode**
- [Intel microcode-20230808 Release](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20230808)
## 2023-08-01
### Changed
- **Overseerr LXC**
- NEW Script
- **Jellyseerr LXC**
- NEW Script
@@ -0,0 +1,80 @@
## 2023-09-30
### Changed
- **All Templates**
- NEW Script
## 2023-09-28
### Changed
- **Alpine Nextcloud Hub LXC**
- NEW Script (Thanks to @nicedevil007)
## 2023-09-14
### Changed
- **Proxmox VE Processor Microcode**
- Allow users to select available microcode packages.
## 2023-09-13
### Changed
- **Pi.Alert LXC**
- NEW Script
- **Proxmox VE Kernel Clean**
- Code overhaul with a fresh start. This script offers the flexibility to select specific kernels for removal, unlike the previous version, which was an all-or-nothing approach.
## 2023-09-11
### Changed
- **Paperless-ngx LXC**
- Modify the script to incorporate Redis and PostgreSQL, while also introducing an option to include Adminer during installation.
## 2023-09-10
### Changed
- **TurnKey Game Server LXC**
- NEW Script
## 2023-09-09
### Changed
- **Proxmox VE Host Backup**
- Users are now able to specify both the backup path and the directory in which they wish to work.
## 2023-09-07
### Changed
- **Proxmox VE Host Backup**
- NEW Script
## 2023-09-06
### Changed
- **Proxmox VE LXC Cleaner**
- Added a new menu that allows you to choose which containers you want to exclude from the clean process.
- **Tailscale**
- Added a menu that enables you to choose the specific container where you want to install Tailscale.
## 2023-09-05
### Changed
- **Proxmox VE LXC Updater**
- Added a new menu that allows you to choose which containers you want to exclude from the update process.
## 2023-09-01
### Changed
- **TurnKey Media Server LXC**
- NEW Script
@@ -0,0 +1,59 @@
## 2023-10-31
### Changed
- **Debian 12 VM**
- NEW Script
## 2023-10-29
### Changed
- **Unmanic LXC**
- NEW Script
## 2023-10-27
### Changed
- **Webmin**
- A full code overhaul.
## 2023-10-15
### Changed
- **TasmoAdmin LXC**
- NEW Script
## 2023-10-14
### Changed
- **Sonarr LXC**
- Include an option to install v4 (experimental)
## 2023-10-11
### Changed
- **Proxmox VE CPU Scaling Governor**
- A full code overhaul.
- Include an option to configure a crontab for ensuring that the CPU Scaling Governor configuration persists across reboots.
## 2023-10-08
### Changed
- **Proxmox VE LXC Updater**
- Now displays which containers require a reboot.
- **File Browser**
- Uninstall by re-executing the script
- Option to use No Authentication
## 2023-10-05
### Changed
- **Pingvin Share LXC**
- NEW Script
@@ -0,0 +1,57 @@
## 2023-11-19
### Changed
- **Dockge LXC**
- NEW Script
## 2023-11-18
### Changed
- **Ubuntu 22.04 VM**
- NEW Script
## 2023-11-14
### Changed
- **TurnKey Nextcloud VM**
- NEW Script
- **TurnKey ownCloud VM**
- NEW Script
## 2023-11-11
### Changed
- **Homarr LXC**
- Returns with v0.14.0 (The authentication update).
## 2023-11-9
### Changed
- **AgentDVR LXC**
- NEW Script
## 2023-11-8
### Changed
- **Linkwarden LXC**
- NEW Script
## 2023-11-2
### Changed
- **PhotoPrism LXC**
- Transitioned to PhotoPrism's latest installation package, featuring Linux binaries.
## 2023-11-1
### Changed
- **Owncast LXC**
- NEW Script
@@ -0,0 +1,84 @@
## 2024-01-25
### Changed
- **PairDrop LXC**
- NEW Script
## 2024-01-20
### Changed
- **Apache-Cassandra LXC**
- NEW Script
- **Redis LXC**
- NEW Script
## 2024-01-17
### Changed
- **ntfy LXC**
- NEW Script
- **HyperHDR LXC**
- NEW Script
## 2024-01-16
### Changed
- **Website Improvements**
- Refine and correct pointers.
- Change hover colors to intuitively indicate categories/items.
- Implement opening links in new tabs for better navigation.
- Enhance the Copy button to better indicate that the command has been successfully copied.
- Introduce a Clear Search button.
- While not directly related to the website, it's worth mentioning that the logo in newly created LXC notes now serves as a link to the website, conveniently opening in a new tab.
## 2024-01-12
### Changed
- **Apt-Cacher-NG LXC**
- NEW Script
- **New Feature**
- The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to decrease bandwidth usage and expedite package installation and updates. https://github.com/tteck/Proxmox/discussions/2332
## 2024-01-09
### Changed
- **Verbose mode**
- Only entries with `$STD` will be shown
## 2024-01-07
### Changed
- **Stirling-PDF LXC**
- NEW Script
- **SFTPGo LXC**
- NEW Script
## 2024-01-04
### Changed
- **CommaFeed LXC**
- NEW Script
## 2024-01-03
### Changed
- **Sonarr LXC**
- Breaking Change
- Complete recode
- https://github.com/tteck/Proxmox/discussions/1738#discussioncomment-8005107
## 2024-01-01
### Changed
- **Gotify LXC**
- NEW Script
@@ -0,0 +1,73 @@
## 2024-02-26
### Changed
- **Mafl LXC**
- NEW Script
## 2024-02-23
### Changed
- **Tandoor Recipes LXC**
- NEW Script (Thanks @MickLesk)
## 2024-02-21
### Changed
- **All scripts**
- As of today, the scripts require the Bash shell specifically. ([more info](https://github.com/tteck/Proxmox/discussions/2536))
## 2024-02-19
### Changed
- **PairDrop LXC**
- Removed from the website ([more info](https://github.com/tteck/Proxmox/discussions/2516))
## 2024-02-16
### Changed
- **Proxmox VE LXC Filesystem Trim**
- NEW Script ([more info](https://github.com/tteck/Proxmox/discussions/2505#discussion-6226037))
## 2024-02-11
### Changed
- **HiveMQ CE LXC**
- NEW Script
- **Apache-CouchDB LXC**
- NEW Script
## 2024-02-06
### Changed
- **All Scripts**
- The scripts will only work with PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later.
## 2024-02-05
### Changed
- **Gokapi LXC**
- NEW Script
- **Nginx Proxy Manager LXC**
- Option to install v2.10.4
## 2024-02-04
### Changed
- **Pi-hole LXC**
- Option to add Unbound
## 2024-02-02
### Changed
- **Readeck LXC**
- NEW Script

Some files were not shown because too many files have changed in this diff Show More