Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions ct/langflow.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

incorrect repository URL - should be ProxmoxVED not ProxmoxVE

Suggested change
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)

# Copyright (c) 2021-2026 community-scripts ORG
# Author: Yamon
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

incorrect repository URL - should be ProxmoxVED not ProxmoxVE

Suggested change
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE

# Source: https://www.langflow.org/

APP="Langflow"
var_tags="${var_tags:-ai;interface}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-12288}"
var_disk="${var_disk:-16}"
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/langflow || ! -f /etc/systemd/system/langflow.service || ! -x /opt/langflow/.venv/bin/python ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

local TS BACKUP_DIR OLD_VERSION TARGET_VERSION
TS="$(date +%Y%m%d-%H%M%S)"
BACKUP_DIR="/opt/langflow/backups/${TS}"
TARGET_VERSION="${LANGFLOW_TARGET_VERSION:-latest}"
OLD_VERSION="$([ -x /opt/langflow/.venv/bin/python ] && /opt/langflow/.venv/bin/python -m pip show langflow 2>/dev/null | awk '/^Version:/ {print $2}')"
LATEST_VERSION="$(get_latest_github_release "langflow-ai/langflow" 2>/dev/null || echo "unknown")"

msg_info "Installed Version: ${OLD_VERSION:-unknown} | Latest Upstream: ${LATEST_VERSION}"

msg_info "Preparing Backup"
mkdir -p "${BACKUP_DIR}"
cp -a /opt/langflow/.env "${BACKUP_DIR}/.env" 2>/dev/null || true
cp -a /opt/langflow/data/langflow.db* "${BACKUP_DIR}/" 2>/dev/null || true
msg_ok "Backup saved to ${BACKUP_DIR}"

msg_info "Stopping Service"
systemctl stop langflow
msg_ok "Stopped Service"

PYTHON_VERSION="3.12" setup_uv
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS:-2}"
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS:-1}"
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS:-1}"
LANGFLOW_NO_CACHE="${LANGFLOW_NO_CACHE:-false}"
UV_CACHE_ARGS=()
if [[ "${LANGFLOW_NO_CACHE,,}" == "true" || "${LANGFLOW_NO_CACHE}" == "1" ]]; then
UV_CACHE_ARGS+=(--no-cache)
fi

msg_info "Pinning CPU Torch"
if ! $STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" \
--index-strategy unsafe-best-match \
--index-url https://download.pytorch.org/whl/cpu \
--extra-index-url https://pypi.org/simple \
"torch==2.8.0+cpu"; then
msg_error "Failed to install CPU torch"
exit 1
fi
msg_ok "Pinned CPU Torch"

msg_info "Updating Langflow (${TARGET_VERSION})"
if [[ "${TARGET_VERSION}" == "latest" ]]; then
if ! $STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" --upgrade langflow; then
msg_error "Langflow update failed"
if [[ -n "${OLD_VERSION}" ]]; then
msg_info "Rolling back to ${OLD_VERSION}"
$STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" "langflow==${OLD_VERSION}" || true
fi
cp -a "${BACKUP_DIR}/.env" /opt/langflow/.env 2>/dev/null || true
cp -a "${BACKUP_DIR}/langflow.db"* /opt/langflow/data/ 2>/dev/null || true
systemctl start langflow || true
exit 1
fi
else
if ! $STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" "langflow==${TARGET_VERSION}"; then
msg_error "Langflow update to ${TARGET_VERSION} failed"
if [[ -n "${OLD_VERSION}" ]]; then
msg_info "Rolling back to ${OLD_VERSION}"
$STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" "langflow==${OLD_VERSION}" || true
fi
cp -a "${BACKUP_DIR}/.env" /opt/langflow/.env 2>/dev/null || true
cp -a "${BACKUP_DIR}/langflow.db"* /opt/langflow/data/ 2>/dev/null || true
systemctl start langflow || true
exit 1
fi
fi
msg_ok "Updated Langflow"

msg_info "Starting Service"
systemctl start langflow

if [[ "$(systemctl is-active langflow)" != "active" ]]; then
msg_error "Service failed to start"
if [[ -n "${OLD_VERSION}" ]]; then
msg_info "Rolling back to ${OLD_VERSION}"
$STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" "langflow==${OLD_VERSION}" || true
cp -a "${BACKUP_DIR}/.env" /opt/langflow/.env 2>/dev/null || true
cp -a "${BACKUP_DIR}/langflow.db"* /opt/langflow/data/ 2>/dev/null || true
systemctl restart langflow || true
fi
exit 1
fi

msg_info "Running Health Check"
ensure_dependencies curl || true
if command -v curl >/dev/null 2>&1; then
for _ in {1..30}; do
if curl -fsS http://127.0.0.1:7860/ >/dev/null 2>&1; then
break
fi
sleep 2
done
if ! curl -fsS http://127.0.0.1:7860/ >/dev/null 2>&1; then
msg_error "Health check failed. Check logs: journalctl -u langflow -n 100"
exit 1
fi
else
msg_info "curl not available, skipping HTTP health check"
fi
msg_ok "Health check passed"
msg_info "If migration errors occur, review Langflow docs before using 'langflow migration --fix'"
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}:7860${CL}"
52 changes: 52 additions & 0 deletions frontend/public/json/langflow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "Langflow",
"slug": "langflow",
"categories": [
20
],
"date_created": "2026-02-21",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 7860,
"documentation": "https://docs.langflow.org/",
"website": "https://www.langflow.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/langflow.webp",
"config_path": "/opt/langflow/.env",
"description": "Langflow is an open-source visual framework for building LLM workflows and multi-agent applications with a drag-and-drop interface.",
"install_methods": [
{
"type": "default",
"script": "ct/langflow.sh",
"resources": {
"cpu": 2,
"ram": 12288,
"hdd": 16,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin",
"password": null
},
"notes": [
{
"text": "Use `cat ~/langflow.creds` to view generated admin credentials and access URL.",
"type": "info"
},
{
"text": "Exposed port: 7860",
"type": "info"
},
{
"text": "Change the default admin password after first login.",
"type": "warning"
},
{
"text": "Installation and updates can take a long time due to large Python dependencies.",
"type": "warning"
}
]
}
137 changes: 137 additions & 0 deletions install/langflow-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/env bash

# Copyright (c) 2021-2026 community-scripts ORG
# Author: Yamon
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

incorrect repository URL - should be ProxmoxVED not ProxmoxVE

Suggested change
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE

# Source: https://www.langflow.org/

source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os

msg_info "Installing Dependencies"
if ! install_packages_with_retry \
build-essential \
python3-dev \
curl \
git; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

verify curl and git aren't preinstalled in base image - if they are, remove them from dependencies per project standards

Context Used: Rule from dashboard - What: Installation scripts must not reinstall dependencies that are already preinstalled in the base... (source)

msg_error "Failed to install dependencies"
exit 1
fi
msg_ok "Installed Dependencies"

PYTHON_VERSION="3.12" setup_uv
LANGFLOW_VERSION="${LANGFLOW_VERSION:-1.7.3}"
APPLICATION="Langflow"
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS:-2}"
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS:-1}"
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS:-1}"
LANGFLOW_NO_CACHE="${LANGFLOW_NO_CACHE:-false}"
UV_CACHE_ARGS=()
if [[ "${LANGFLOW_NO_CACHE,,}" == "true" || "${LANGFLOW_NO_CACHE}" == "1" ]]; then
UV_CACHE_ARGS+=(--no-cache)
fi

msg_info "Installing Langflow"
mkdir -p /opt/langflow/data
cd /opt/langflow
$STD uv venv --clear /opt/langflow/.venv
$STD /opt/langflow/.venv/bin/python -m ensurepip --upgrade
$STD /opt/langflow/.venv/bin/python -m pip install --upgrade pip
PYTHON_VENV_VERSION="$("/opt/langflow/.venv/bin/python" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
verify_tool_version "python" "3.12" "${PYTHON_VENV_VERSION}" || true
$STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" \
--index-strategy unsafe-best-match \
--index-url https://download.pytorch.org/whl/cpu \
--extra-index-url https://pypi.org/simple \
"torch==2.8.0+cpu"
$STD env \
UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS}" \
UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS}" \
UV_CONCURRENT_INSTALLS="${UV_CONCURRENT_INSTALLS}" \
uv pip install --python /opt/langflow/.venv/bin/python "${UV_CACHE_ARGS[@]}" "langflow==${LANGFLOW_VERSION}"
msg_ok "Installed Langflow"

msg_info "Configuring Langflow"
get_lxc_ip
LOCAL_IP="${LOCAL_IP:-$IP}"
APP_NAME="Langflow"
ADMIN_USER="admin"
ADMIN_PASS="$(openssl rand -base64 32 | tr -dc 'A-Za-z0-9' | head -c 20)"
if [[ ${#ADMIN_PASS} -lt 12 ]]; then
ADMIN_PASS="$(openssl rand -hex 16)"
fi
LANGFLOW_SECRET_KEY=$(openssl rand -base64 48 | tr -d '\n')
CPU_CORES="$(nproc 2>/dev/null || echo 2)"
if [[ "${CPU_CORES}" -ge 8 ]]; then
LANGFLOW_WORKERS_DEFAULT=4
elif [[ "${CPU_CORES}" -ge 4 ]]; then
LANGFLOW_WORKERS_DEFAULT=2
else
LANGFLOW_WORKERS_DEFAULT=1
fi
cat <<EOF2 >/opt/langflow/.env
LANGFLOW_CONFIG_DIR=/opt/langflow/data
LANGFLOW_SAVE_DB_IN_CONFIG_DIR=true
LANGFLOW_DATABASE_URL=sqlite:////opt/langflow/data/langflow.db
LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
LANGFLOW_AUTO_LOGIN=false
LANGFLOW_SUPERUSER=${ADMIN_USER}
LANGFLOW_SUPERUSER_PASSWORD=${ADMIN_PASS}
LANGFLOW_HOST=0.0.0.0
LANGFLOW_PORT=7860
LANGFLOW_OPEN_BROWSER=false
LANGFLOW_LOG_LEVEL=info
DO_NOT_TRACK=true
LANGFLOW_REMOVE_API_KEYS=true
LANGFLOW_FALLBACK_TO_ENV_VAR=false
LANGFLOW_STORE_ENVIRONMENT_VARIABLES=false
LANGFLOW_WORKERS=${LANGFLOW_WORKERS_DEFAULT}
LANGFLOW_WORKER_TIMEOUT=300
LANGFLOW_HEALTH_CHECK_MAX_RETRIES=5
LANGFLOW_LAZY_LOAD_COMPONENTS=false
EOF2
chmod 600 /opt/langflow/.env
{
echo "${APP_NAME} Credentials"
echo "Default Admin User: ${ADMIN_USER}"
echo "Username: ${ADMIN_USER}"
echo "Password: ${ADMIN_PASS}"
echo "Exposed Port: 7860"
echo "URL: http://${LOCAL_IP}:7860"
} >~/langflow.creds
chmod 600 ~/langflow.creds
msg_ok "Configured Langflow"

msg_info "Creating Service"
cat <<'EOF2' >/etc/systemd/system/langflow.service
[Unit]
Description=Langflow Service
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/langflow
EnvironmentFile=/opt/langflow/.env
ExecStart=/opt/langflow/.venv/bin/langflow run --env-file /opt/langflow/.env --no-open-browser
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF2
systemctl daemon-reload
systemctl enable -q --now langflow

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove daemon-reload per project standards - systemctl enable -q --now handles service activation

Suggested change
systemctl daemon-reload
systemctl enable -q --now langflow
systemctl enable -q --now langflow

Context Used: Rule from dashboard - What: All service creation must use systemctl enable -q --now to start and enable services in a si... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

msg_ok "Created Service"

motd_ssh
customize
cleanup_lxc