Initial commit: pod setup and shell scripts
Add create_pod_langflow.sh (Langflow + Langfuse Podman pod with pinned image versions), set-colors.sh, .gitignore, and local .claude config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
16
.claude/settings.local.json
Normal file
16
.claude/settings.local.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(grep -o 'workspace.\\\\{0,40\\\\}current_dir.\\\\{0,300\\\\}')",
|
||||
"Bash(grep -o '.\\\\{420\\\\}exceeds_200k_tokens:t,fast_mode')",
|
||||
"Bash(grep -oE 'five_hour:\\\\{[^}]{0,200}')",
|
||||
"Bash(grep -oE '\\(five_hour|seven_day|used_pct|utilization|resets_at|status\\)[: ]\\\\{?[^,}]{0,60}')",
|
||||
"Bash(grep -oE 'five_hour:\\\\{[^@]{0,400}')",
|
||||
"Bash(grep -oE '.{0,20}\\(five_hour|seven_day\\):\\\\{[^{}]*\\\\}')",
|
||||
"Bash(grep -o 'five_hour:{used_percentage[^Z]\\\\{0,260\\\\}')",
|
||||
"Bash(grep -oE 'function s\\\\$f\\\\\\([^\\)]*\\\\\\)\\\\{[^@]{0,300}')",
|
||||
"Bash(grep -oE '\\(used_tokens|total_tokens|remaining_tokens|used_percent|max_tokens|compaction\\)[: ][^,}]{0,40}')",
|
||||
"Bash(grep -oE 'function u_n\\\\\\([^\\)]*\\\\\\)\\\\{[^@]{0,200}')"
|
||||
]
|
||||
}
|
||||
}
|
||||
50
.gitignore
vendored
Normal file
50
.gitignore
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# --- OS / filesystem cruft ---
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
|
||||
# --- Editor / IDE ---
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
.vscode/
|
||||
.idea/
|
||||
*.sublime-workspace
|
||||
|
||||
# --- Backups & patch leftovers ---
|
||||
*.bak
|
||||
*.bak-*
|
||||
*.bak[0-9]*
|
||||
*.backup
|
||||
*.orig
|
||||
*.rej
|
||||
*.tmp
|
||||
|
||||
# --- Logs ---
|
||||
*.log
|
||||
|
||||
# --- Secrets / credentials (never commit) ---
|
||||
.env
|
||||
.env.*
|
||||
*.pem
|
||||
*.key
|
||||
id_rsa
|
||||
id_ed25519
|
||||
*_secret*
|
||||
*.secret
|
||||
credentials
|
||||
secrets/
|
||||
|
||||
# --- Python (scripts may bring these) ---
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# --- Local scratch ---
|
||||
/tmp/
|
||||
scratchpad/
|
||||
322
create_pod_langflow.sh
Executable file
322
create_pod_langflow.sh
Executable file
@@ -0,0 +1,322 @@
|
||||
#!/bin/bash
|
||||
|
||||
# To be run by user lwc to create pod for Langflow, Langfuse and their tools
|
||||
|
||||
set -e
|
||||
|
||||
# Environment variables
|
||||
POD_NAME='langflow_pod'
|
||||
LANGFLOW_CTR_NAME='langflow_ctr'
|
||||
POSTGRES_CTR_NAME='postgres_ctr'
|
||||
LANGFUSE_WEB_CTR_NAME='langfuse-web_ctr'
|
||||
LANGFUSE_WORKER_CTR_NAME='langfuse-worker_ctr'
|
||||
CLICKHOUSE_CTR_NAME='clickhouse_ctr'
|
||||
MINIO_CTR_NAME='minio_ctr'
|
||||
REDIS_CTR_NAME='redis_ctr'
|
||||
|
||||
# All image tags are pinned to fixed, immutable versions (no floating tags
|
||||
# such as :latest, :3 or :16). Verified against the upstream registries on
|
||||
# 2026-06-23. Langflow 1.10.0 supports the MCP server (flows-as-tools).
|
||||
LANGFLOW_IMAGE='docker.io/langflowai/langflow:1.10.0'
|
||||
POSTGRES_IMAGE='docker.io/library/postgres:17.10'
|
||||
LANGFUSE_WEB_IMAGE='docker.io/langfuse/langfuse:3.195.0'
|
||||
LANGFUSE_WORKER_IMAGE='docker.io/langfuse/langfuse-worker:3.195.0'
|
||||
# ClickHouse pinned to the latest patch of the 25.11 minor (>= Langfuse's
|
||||
# minimum supported 24.3); 26.x is intentionally avoided as too bleeding-edge.
|
||||
CLICKHOUSE_IMAGE='docker.io/clickhouse/clickhouse-server:25.11.9.34'
|
||||
# Using official MinIO image here because the Chainguard image used in Langfuse
|
||||
# docker-compose example does not ship
|
||||
# a shell, but this script relies on a small shell wrapper to pre-create the
|
||||
# langfuse bucket. And Chainguard offers only tag :latest.
|
||||
MINIO_IMAGE='docker.io/minio/minio:RELEASE.2025-09-07T16-13-09Z'
|
||||
REDIS_IMAGE='docker.io/redis:7.4.9'
|
||||
|
||||
HOST_LOCAL_IP='127.0.0.1'
|
||||
# Expose Langflow on 8090 -> 7860
|
||||
LANGFLOW_HOST_PORT='8090'
|
||||
LANGFLOW_CONTAINER_PORT='7860'
|
||||
# Expose Langfuse Web on 8091 -> 3000
|
||||
LANGFUSE_HOST_PORT='8091'
|
||||
LANGFUSE_CONTAINER_PORT='3000'
|
||||
# MinIO API/console ports inside the pod (avoid conflict with ClickHouse native port 9000)
|
||||
MINIO_API_PORT='9100'
|
||||
MINIO_CONSOLE_PORT='9101'
|
||||
# All other services are only reachable inside the pod
|
||||
|
||||
BIND_DIR="$HOME/.local/share/$POD_NAME"
|
||||
LANGFLOW_DATA_DIR="$BIND_DIR/langflow-data"
|
||||
POSTGRES_DATA_DIR="$BIND_DIR/postgres-data"
|
||||
LANGFUSE_CLICKHOUSE_DATA_DIR="$BIND_DIR/langfuse-clickhouse-data"
|
||||
LANGFUSE_CLICKHOUSE_LOGS_DIR="$BIND_DIR/langfuse-clickhouse-logs"
|
||||
LANGFUSE_MINIO_DATA_DIR="$BIND_DIR/langfuse-minio-data"
|
||||
USER_SYSTEMD_DIR="$HOME/.config/systemd/user"
|
||||
|
||||
LANGFUSE_PUBLIC_URL="http://$HOST_LOCAL_IP:$LANGFUSE_HOST_PORT"
|
||||
LANGFLOW_DB_URL='postgresql://langflow:langflow@localhost:5432/langflow'
|
||||
|
||||
# --- Test / integration configuration ---------------------------------------
|
||||
# Langfuse is bootstrapped headlessly with a fixed org/project/user and a fixed
|
||||
# API key pair (see LANGFUSE_INIT_* below). This makes the environment usable
|
||||
# for automation out of the box. Change or blank these for a clean UI signup.
|
||||
LANGFUSE_INIT_ORG="test-org"
|
||||
LANGFUSE_INIT_PROJECT="test-project"
|
||||
LANGFUSE_INIT_PUBLIC_KEY="pk-lf-00000000-0000-0000-0000-000000000001"
|
||||
LANGFUSE_INIT_SECRET_KEY="sk-lf-00000000-0000-0000-0000-000000000002"
|
||||
LANGFUSE_INIT_EMAIL="admin@example.com"
|
||||
LANGFUSE_INIT_PASSWORD="langfuse-admin-pw"
|
||||
# Langflow sends its run traces to the in-pod Langfuse using the keys above.
|
||||
# NOTE: the Langfuse web (Next.js) server binds to the pod's hostname/IP, NOT
|
||||
# 127.0.0.1, so Langflow must address it via the pod name (which every pod
|
||||
# container resolves to the pod IP through /etc/hosts), not "localhost".
|
||||
LANGFUSE_INPOD_HOST="http://$POD_NAME:$LANGFUSE_CONTAINER_PORT"
|
||||
# Local OpenAI-compatible (vLLM) inference endpoint on the host, reachable from
|
||||
# inside the pod via the podman host gateway alias.
|
||||
LOCAL_LLM_BASE_URL="http://host.containers.internal:8081/v1"
|
||||
LOCAL_LLM_MODEL="AxionML/Qwen3.5-9B-NVFP4"
|
||||
|
||||
LANGFUSE_COMMON_ENV=(
|
||||
-e NEXTAUTH_URL="$LANGFUSE_PUBLIC_URL"
|
||||
-e DATABASE_URL="postgresql://langflow:langflow@localhost:5432/langfuse"
|
||||
-e SALT="qwexoiuzxequtbfvyqewregvg"
|
||||
-e ENCRYPTION_KEY="57db4291f0243a9f6bbbf82d3fbca1a72c58fd42f852a4d74e3db8b55bee720a"
|
||||
-e TELEMETRY_ENABLED=true
|
||||
-e LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=true
|
||||
-e CLICKHOUSE_MIGRATION_URL="clickhouse://localhost:9000"
|
||||
-e CLICKHOUSE_URL="http://localhost:8123"
|
||||
-e CLICKHOUSE_USER="clickhouse"
|
||||
-e CLICKHOUSE_PASSWORD="clickhouse"
|
||||
-e CLICKHOUSE_CLUSTER_ENABLED=false
|
||||
-e LANGFUSE_USE_AZURE_BLOB=false
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_BUCKET="langfuse"
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_REGION="auto"
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID="minio"
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY="miniosecret"
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT="http://localhost:$MINIO_API_PORT"
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE=true
|
||||
-e LANGFUSE_S3_EVENT_UPLOAD_PREFIX="events/"
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_BUCKET="langfuse"
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_REGION="auto"
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID="minio"
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY="miniosecret"
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT="http://localhost:$MINIO_API_PORT"
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE=true
|
||||
-e LANGFUSE_S3_MEDIA_UPLOAD_PREFIX="media/"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_ENABLED=false
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_BUCKET="langfuse"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_PREFIX="exports/"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_REGION="auto"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_ENDPOINT="http://localhost:$MINIO_API_PORT"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_EXTERNAL_ENDPOINT="$LANGFUSE_PUBLIC_URL"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_ACCESS_KEY_ID="minio"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY="miniosecret"
|
||||
-e LANGFUSE_S3_BATCH_EXPORT_FORCE_PATH_STYLE=true
|
||||
-e LANGFUSE_INGESTION_QUEUE_DELAY_MS=
|
||||
-e LANGFUSE_INGESTION_CLICKHOUSE_WRITE_INTERVAL_MS=
|
||||
-e REDIS_HOST="localhost"
|
||||
-e REDIS_PORT=6379
|
||||
-e REDIS_AUTH="myredissecret"
|
||||
-e REDIS_TLS_ENABLED=false
|
||||
-e REDIS_TLS_CA="/certs/ca.crt"
|
||||
-e REDIS_TLS_CERT="/certs/redis.crt"
|
||||
-e REDIS_TLS_KEY="/certs/redis.key"
|
||||
-e EMAIL_FROM_ADDRESS=
|
||||
-e SMTP_CONNECTION_URL=
|
||||
)
|
||||
|
||||
# Stop existing systemd-managed pod if present, to avoid conflicts on rerun
|
||||
echo "Stopping systemd-managed pod 'pod-$POD_NAME.service' if it exists..."
|
||||
if systemctl --user list-units --type=service --all 2>/dev/null | \
|
||||
grep -q "pod-$POD_NAME.service"; then
|
||||
systemctl --user stop "pod-$POD_NAME.service" || true
|
||||
fi
|
||||
|
||||
# Prepare directories
|
||||
mkdir -p "$LANGFLOW_DATA_DIR" "$POSTGRES_DATA_DIR" \
|
||||
"$LANGFUSE_CLICKHOUSE_DATA_DIR" "$LANGFUSE_CLICKHOUSE_LOGS_DIR" \
|
||||
"$LANGFUSE_MINIO_DATA_DIR" "$USER_SYSTEMD_DIR"
|
||||
|
||||
# The Langflow image (>= 1.10) runs as a non-root user (uid 1000) that belongs
|
||||
# to group 0 (root). Its config dir is bind-mounted from the host, where it is
|
||||
# owned by the (rootless) container root. Make the dir group-writable with the
|
||||
# setgid bit so the non-root Langflow process can write its config/log files
|
||||
# (the "arbitrary uid + gid 0" pattern the image is built for).
|
||||
chmod g+rwxs "$LANGFLOW_DATA_DIR"
|
||||
|
||||
# Create pod if not yet existing
|
||||
if ! podman pod exists "$POD_NAME"; then
|
||||
podman pod create -n "$POD_NAME" \
|
||||
-p "$HOST_LOCAL_IP:$LANGFLOW_HOST_PORT:$LANGFLOW_CONTAINER_PORT" \
|
||||
-p "$HOST_LOCAL_IP:$LANGFUSE_HOST_PORT:$LANGFUSE_CONTAINER_PORT"
|
||||
echo "Pod '$POD_NAME' created (rc=$?)"
|
||||
else
|
||||
echo "Pod '$POD_NAME' already exists."
|
||||
fi
|
||||
|
||||
# Remove any old containers (ignore errors if they don't exist)
|
||||
podman rm -f "$LANGFLOW_CTR_NAME" || true
|
||||
podman rm -f "$POSTGRES_CTR_NAME" || true
|
||||
podman rm -f "$LANGFUSE_WEB_CTR_NAME" || true
|
||||
podman rm -f "$LANGFUSE_WORKER_CTR_NAME" || true
|
||||
podman rm -f "$CLICKHOUSE_CTR_NAME" || true
|
||||
podman rm -f "$MINIO_CTR_NAME" || true
|
||||
podman rm -f "$REDIS_CTR_NAME" || true
|
||||
|
||||
# Postgres container (shared by Langflow and Langfuse)
|
||||
podman run -d --name "$POSTGRES_CTR_NAME" --pod "$POD_NAME" \
|
||||
-e POSTGRES_USER=langflow \
|
||||
-e POSTGRES_PASSWORD=langflow \
|
||||
-e POSTGRES_DB=langflow \
|
||||
-v "$POSTGRES_DATA_DIR:/var/lib/postgresql/data:Z" \
|
||||
"$POSTGRES_IMAGE"
|
||||
echo "Container '$POSTGRES_CTR_NAME' started (rc=$?)"
|
||||
# Wait for Postgres to be ready before starting Langflow / Langfuse
|
||||
echo "Waiting for Postgres to be ready (pg_isready)..."
|
||||
for attempt in $(seq 1 30); do
|
||||
if podman exec "$POSTGRES_CTR_NAME" pg_isready -q >/dev/null 2>&1; then
|
||||
echo "Postgres is ready."
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
if [ "$attempt" -eq 30 ]; then
|
||||
echo "ERROR: Postgres did not become ready in time." >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Ensure separate database for Langfuse in the shared Postgres instance
|
||||
echo "Ensuring 'langfuse' database exists for Langfuse..."
|
||||
if ! podman exec "$POSTGRES_CTR_NAME" psql -U langflow -d postgres \
|
||||
-tc "SELECT 1 FROM pg_database WHERE datname = 'langfuse';" | grep -q 1; then
|
||||
podman exec "$POSTGRES_CTR_NAME" psql -U langflow -d postgres \
|
||||
-c "CREATE DATABASE langfuse OWNER langflow;"
|
||||
fi
|
||||
echo "Database 'langfuse' is ready for Langfuse."
|
||||
|
||||
# Clickhouse container (Langfuse analytics store)
|
||||
podman run -d --name "$CLICKHOUSE_CTR_NAME" --pod "$POD_NAME" \
|
||||
-e CLICKHOUSE_DB=default \
|
||||
-e CLICKHOUSE_USER=clickhouse \
|
||||
-e CLICKHOUSE_PASSWORD=clickhouse \
|
||||
-v "$LANGFUSE_CLICKHOUSE_DATA_DIR:/var/lib/clickhouse:Z" \
|
||||
-v "$LANGFUSE_CLICKHOUSE_LOGS_DIR:/var/log/clickhouse-server:Z" \
|
||||
"$CLICKHOUSE_IMAGE"
|
||||
echo "Container '$CLICKHOUSE_CTR_NAME' started (rc=$?)"
|
||||
|
||||
# Minio container (S3-compatible storage for Langfuse)
|
||||
# NOTE: The official MinIO image uses the `minio` binary as entrypoint.
|
||||
# We call `server` directly as the container command.
|
||||
podman run -d --name "$MINIO_CTR_NAME" --pod "$POD_NAME" \
|
||||
-e MINIO_ROOT_USER=minio \
|
||||
-e MINIO_ROOT_PASSWORD=miniosecret \
|
||||
-v "$LANGFUSE_MINIO_DATA_DIR:/data:Z" \
|
||||
"$MINIO_IMAGE" \
|
||||
server --address ":$MINIO_API_PORT" --console-address ":$MINIO_CONSOLE_PORT" /data
|
||||
echo "Container '$MINIO_CTR_NAME' started (rc=$?)"
|
||||
|
||||
# Pre-create the 'langfuse' bucket. Langfuse does NOT create the bucket itself;
|
||||
# event/media ingestion fails with HTTP 500 if the bucket is missing. The
|
||||
# official MinIO image bundles the `mc` client, so we use it inside the
|
||||
# container to wait for the server and create the bucket idempotently.
|
||||
echo "Creating MinIO bucket 'langfuse'..."
|
||||
for attempt in $(seq 1 30); do
|
||||
if podman exec "$MINIO_CTR_NAME" mc alias set local \
|
||||
"http://localhost:$MINIO_API_PORT" minio miniosecret >/dev/null 2>&1; then
|
||||
podman exec "$MINIO_CTR_NAME" mc mb --ignore-existing local/langfuse
|
||||
echo "MinIO bucket 'langfuse' is ready."
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
if [ "$attempt" -eq 30 ]; then
|
||||
echo "ERROR: MinIO did not become ready in time." >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Redis container (queue/cache for Langfuse)
|
||||
podman run -d --name "$REDIS_CTR_NAME" --pod "$POD_NAME" \
|
||||
"$REDIS_IMAGE" \
|
||||
--requirepass myredissecret \
|
||||
--maxmemory-policy noeviction
|
||||
echo "Container '$REDIS_CTR_NAME' started (rc=$?)"
|
||||
|
||||
# Langflow container
|
||||
# Podman automatically provides the `host.containers.internal` hostname in the
|
||||
# container's /etc/hosts (pointing at the host), so flows can reach the local
|
||||
# vLLM OpenAI-compatible endpoint on the host without an explicit --add-host.
|
||||
podman run -d --name "$LANGFLOW_CTR_NAME" --pod "$POD_NAME" \
|
||||
-e LANGFLOW_DATABASE_URL="$LANGFLOW_DB_URL" \
|
||||
-e LANGFLOW_CONFIG_DIR=/app/langflow \
|
||||
-e LANGFLOW_LOG_FILE=/app/langflow/langflow.log \
|
||||
-e LANGFLOW_LOG_ENV=default \
|
||||
-e LANGFLOW_PRETTY_LOGS=true \
|
||||
-e LANGFLOW_LOG_LEVEL=INFO \
|
||||
-e DO_NOT_TRACK=True \
|
||||
-e LANGFUSE_PUBLIC_KEY="$LANGFUSE_INIT_PUBLIC_KEY" \
|
||||
-e LANGFUSE_SECRET_KEY="$LANGFUSE_INIT_SECRET_KEY" \
|
||||
-e LANGFUSE_HOST="$LANGFUSE_INPOD_HOST" \
|
||||
-v "$LANGFLOW_DATA_DIR:/app/langflow:Z" \
|
||||
"$LANGFLOW_IMAGE"
|
||||
echo "Container '$LANGFLOW_CTR_NAME' started (rc=$?)"
|
||||
|
||||
# Langfuse worker container
|
||||
podman run -d --name "$LANGFUSE_WORKER_CTR_NAME" --pod "$POD_NAME" \
|
||||
"${LANGFUSE_COMMON_ENV[@]}" \
|
||||
"$LANGFUSE_WORKER_IMAGE"
|
||||
echo "Container '$LANGFUSE_WORKER_CTR_NAME' started (rc=$?)"
|
||||
|
||||
# Langfuse web container (exposed on host port 8091 -> 3000)
|
||||
podman run -d --name "$LANGFUSE_WEB_CTR_NAME" --pod "$POD_NAME" \
|
||||
"${LANGFUSE_COMMON_ENV[@]}" \
|
||||
-e NEXTAUTH_SECRET="qwexczutbewrgerznupvemqyw" \
|
||||
-e LANGFUSE_INIT_ORG_ID="$LANGFUSE_INIT_ORG" \
|
||||
-e LANGFUSE_INIT_ORG_NAME="Test Org" \
|
||||
-e LANGFUSE_INIT_PROJECT_ID="$LANGFUSE_INIT_PROJECT" \
|
||||
-e LANGFUSE_INIT_PROJECT_NAME="Test Project" \
|
||||
-e LANGFUSE_INIT_PROJECT_PUBLIC_KEY="$LANGFUSE_INIT_PUBLIC_KEY" \
|
||||
-e LANGFUSE_INIT_PROJECT_SECRET_KEY="$LANGFUSE_INIT_SECRET_KEY" \
|
||||
-e LANGFUSE_INIT_USER_EMAIL="$LANGFUSE_INIT_EMAIL" \
|
||||
-e LANGFUSE_INIT_USER_NAME="Admin" \
|
||||
-e LANGFUSE_INIT_USER_PASSWORD="$LANGFUSE_INIT_PASSWORD" \
|
||||
"$LANGFUSE_WEB_IMAGE"
|
||||
echo "Container '$LANGFUSE_WEB_CTR_NAME' started (rc=$?)"
|
||||
|
||||
# Generate systemd service files
|
||||
cd "$USER_SYSTEMD_DIR"
|
||||
podman generate systemd --name --new --files "$POD_NAME"
|
||||
echo "Generated systemd service files (rc=$?)"
|
||||
|
||||
# Stop & remove live pod and containers
|
||||
podman pod stop --ignore --time 15 "$POD_NAME"
|
||||
podman pod rm -f --ignore "$POD_NAME"
|
||||
if podman pod exists "$POD_NAME"; then
|
||||
echo "ERROR: Pod $POD_NAME still exists." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "Stopped & removed live pod $POD_NAME and containers."
|
||||
fi
|
||||
|
||||
# Enable systemd user services
|
||||
systemctl --user daemon-reload
|
||||
# pod service (creates pod + containers)
|
||||
systemctl --user enable --now "pod-${POD_NAME}.service"
|
||||
systemctl --user is-enabled "pod-${POD_NAME}.service"
|
||||
systemctl --user is-active "pod-${POD_NAME}.service"
|
||||
echo "Enabled systemd service pod-${POD_NAME}.service (rc=$?)"
|
||||
echo "To view status: systemctl --user status pod-${POD_NAME}.service"
|
||||
echo "To view logs: journalctl --user -u pod-${POD_NAME}.service -f"
|
||||
|
||||
# Wait for Langflow API readiness
|
||||
CHECK_URL_LANGFLOW="http://$HOST_LOCAL_IP:$LANGFLOW_HOST_PORT"
|
||||
CHECK_URL_LANGFUSE="http://$HOST_LOCAL_IP:$LANGFUSE_HOST_PORT"
|
||||
for attempt in $(seq 1 30); do
|
||||
if curl -fsS "$CHECK_URL_LANGFLOW" >/dev/null 2>&1; then
|
||||
echo "Langflow Web UI is reachable at $CHECK_URL_LANGFLOW."
|
||||
echo "Langfuse Web UI is reachable at $CHECK_URL_LANGFUSE."
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
if [ "$attempt" -eq 30 ]; then
|
||||
echo "timeout error." >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
5
set-colors.sh
Executable file
5
set-colors.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
mkdir -p ~/.config/xfce4/terminal
|
||||
cat > ~/.config/xfce4/terminal/terminalrc << 'EOF'
|
||||
[Configuration]
|
||||
ColorPalette=#000000;#ef5350;#4e9a06;#c4a000;#5f87ff;#75507b;#06989a;#d3d7cf;#555753;#ef2929;#8ae234;#fce94f;#729fcf;#ad7fa8;#34e2e2;#eeeeec
|
||||
EOF
|
||||
Reference in New Issue
Block a user