Skip to content

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

82 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

   ____ _            _           _____ _               
  / ___| | __ _  ___(_) ___ _ __|  ___| | _____      __
 | |  _| |/ _` |/ __| |/ _ \ '__| |_  | |/ _ \ \ /\ / /
 | |_| | | (_| | (__| |  __/ |  |  _| | | (_) \ V  V / 
  \____|_|\__,_|\___|_|\___|_|  |_|   |_|\___/ \_/\_/  
                                                       

GlacierFlow

A lightweight toolkit for managing local AI inference servers (llama.cpp / stable-diffusion.cpp / audio.cpp) on Linux, with hot-swap model presets, embedding server support, and automatic container orchestration. Includes Web UI, TUI and pi.dev container for software development.


What It Does

GlacierFlow runs llama.cpp inside Docker and lets you switch between model presets on the fly — no manual container restarts needed. A background daemon watches your config and applies changes automatically.

Current features:

  • llama.cpp / stable-diffusion.cpp / audio.cpp inference server managed via Docker Compose
  • Hot-swap between inference presets (YAML configs)
  • Automatic container restarts when preset changes
  • Preset loading time tracking & status monitoring
  • Example configs for various GPU setups
  • Docker-based code generation assistant (pi.dev)
  • Hermes AI agent container with web dashboard and kanban task support
  • Multi-model benchmarking suite
  • GPU layers autotune — binary search for optimal VRAM offload with stability testing and quick benchmark
  • MTP preset grid generator — sweep --spec-draft-n-max / --spec-draft-p-min to generate a 9×9 grid of inference presets
  • Web-based UI for preset management and status monitoring
  • Embedding server (llama.cpp) for vector embeddings, toggleable via override config
  • FIFO proxy for serializing chat requests (prevents stream cut-offs during model hot-swap)
  • Automatic LLM ↔ Stable Diffusion mode switching in the FIFO proxy (chat and image generation through one endpoint, e.g. Cherry Studio)
  • Caddy reverse proxy with SSL/TLS termination and basic auth for Web UI, pi.dev TTYD, Hermes TTYD and VS Code
  • User/group ID customization via GF_USER_ID / GF_USER_GROUP_ID environment variables (affects all containers)

Prerequisites

  • Linux (tested on Arch/Manjaro)
  • Docker & Docker Compose
  • GPU drivers (Vulkan for AMD/NVIDIA)
  • Bash, curl, git, grep, awk, md5sum, openssl, unzip, and other coreutils

Quick Start

1. Clone & prepare

git clone https://github.com/howanski/GlacierFlow.git
cd GlacierFlow

2. Copy a preset

Pick an example preset and copy it to your local presets directory:

cp data/shared/inference_presets/examples/vulkan_8gb_gemma4_e4b_q4.yml \
   data/shared/inference_presets/local/

By default a self-signed certificate is auto-generated on first run. To use your own certificates, place cert.pem and key.pem in data/ssl_certs/ before starting the daemon.

# Generate self-signed cert manually (daemon does this automatically if files are missing)
openssl req -x509 -newkey rsa:4096 -keyout data/ssl_certs/key.pem -out data/ssl_certs/cert.pem -days 3650 -nodes

3. Configure environment

Create a .env file with your paths:

GF_AUTO_MERGE_PRESETS= # optional: merge preset files on daemon start, e.g. "A+B=C;D+E=F" (see "Auto-merging presets")
GF_HERMES_AUTOSTART=0 # set to 1 to auto-start Hermes container with the daemon
GF_HERMES_TTYD_PORT=7682
GF_HERMES_WEB_PORT=7683
GF_HERMES_WORKDIR=/path/to/hermes/workdir
GF_USER_GROUP_ID=1000 # group ID for all containers (defaults to 1000)
GF_USER_ID=1000 # user ID for all containers (defaults to 1000)
GF_AUDIO_CPP_ENABLE=0 # set to 1 to auto-clone/build audio.cpp binaries on daemon start (CPU-heavy)
GF_DEFAULT_MODEL_LLM= # preset name for chat mode, loaded by the daemon on start (see "Automatic Mode Switching")
GF_DEFAULT_MODEL_SD= # preset name for image generation mode (see "Automatic Mode Switching")
GF_STABLE_DIFFUSION_ENABLE=0 # set to 1 to auto-download/update stable-diffusion.cpp binaries on daemon start
GF_VSCODE_AUTOSTART=0 # set to 1 to auto-start VS Code container with the daemon
GF_VSCODE_WEB_PORT=7684
GF_HTTP_PASSWORD=glacierflow
GF_HTTP_USER=glacierflow
GF_LLAMA_MEMORY_LIMIT=50g
GF_LLAMA_SERVER_VERSION=server-vulkan
GF_LOG_STATS=0 # set to 1 to enable performance stats logging
GF_MODELS_DIRECTORY=/path/to/your/models
GF_PI_DEV_TTYD_PORT=7681
GF_PI_DEV_WORKDIR=/path/to/coder/workdir
GF_PROXY_AUTO_MODE=0 # set to 1 to enable automatic LLM ↔ SD mode switching in the FIFO proxy
GF_PROXY_DUMP_REQUESTS=0 # set to 1 to dump request/response pairs to JSON files
GF_WEB_UI_PORT=8090

4. Start the daemon

Run the background service to spin up the inference server:

cd scripts
./glacierflow_host_daemon

Personally I've just added it to my crontab @reboot via thin wrapper in case it blows up (and fancy blocker when I launch Steam)

For a one-shot check (no daemon loop):

cd scripts
./glacierflow_host_daemon --once

5. Switch presets

List available presets:

cd scripts
./glacierflow_inference_select_preset

Load a preset by name or hash:

cd scripts
./glacierflow_inference_select_preset vulkan_8gb_gemma4_e4b_q4
./glacierflow_inference_select_preset <md5hash>

Web UI

GlacierFlow includes a web-based management interface for monitoring and controlling the inference server and presets.

Setup

Make sure GF_WEB_UI_PORT is set in your .env file:

GF_WEB_UI_PORT=8090

Usage

Start the daemon first:

cd scripts
./glacierflow_host_daemon

Open https://localhost:8090 in your browser. The UI provides:

  • Preset management — list, select, and track active presets
  • Status monitoring — (almost) real-time server status (RUNNING, LOADING, STOPPED, etc.)
  • Lock/unlock — to force keep inference server off when in locked state
  • Stats Viewer — Chart.js-based visualization of inference performance metrics (fill TPS, gen TPS, draft acceptance rate)
  • pi.dev httpd — direct link to the TTYD web terminal for the code generation assistant
  • hermes httpd — direct link to the TTYD web terminal for the Hermes agent
  • hermes Web UI — direct link to the Hermes dashboard
  • VS Code — direct link to the code-server instance

The web UI communicates directly with the shared data directory, so it stays in sync with the daemon and CLI tools.


Preset Files

Preset files are Docker Compose YAML snippets that override the base compose.yml. They define:

  • command:inference server arguments (model path, context size, GPU layers, diffusion models, etc.)
  • devices: GPU device passthrough (e.g., /dev/dri for AMD)
  • volumes: Model directory mount paths

Preset names are derived from their filename (.yml extension stripped). You can reference them by full name or by MD5 hash.

Example presets live in inference_presets/examples/ (tracked). Your custom presets go in inference_presets/local/ (gitignored).

Auto-merging presets

scripts/gf_auto_merge_presets merges preset files by plain concatenation (no parsing, no dedup) inside data/shared/inference_presets/local/. It is driven entirely by GF_AUTO_MERGE_PRESETS in your .env:

GF_AUTO_MERGE_PRESETS="A.ini+B.ini=C.ini;D.ini+E.ini=F.ini"
  • Sequences are separated by ; and executed strictly in order, so an earlier sequence's output can feed a later one (e.g. A.ini+B.ini+C.ini=E.ini;D.ini+E.ini=F.ini).
  • Within a sequence, inputs are separated by + and concatenated in the given order into the output file named after =.
  • Unset or empty → the script does nothing and exits 0.

The daemon runs it automatically on start (once, before the services come up) when the variable is set. You can also run it manually at any time:

cd scripts
./gf_auto_merge_presets

On any error (malformed sequence, missing input, output colliding with an input) the script aborts with a non-zero exit code; the daemon keeps running, so fix the .env and re-run.


Benchmarking

GlacierFlow includes a benchmark runner that measures throughput (tokens/sec) across multiple models and problem types:

# Show results table (presets × benchmarks)
cd scripts
./glacierflow_benchmark

# Run benchmarks for the currently loaded model (default 3 passes per benchmark)
cd scripts
./glacierflow_benchmark run

# Run benchmarks with a custom number of passes per benchmark
cd scripts
./glacierflow_benchmark run 5

The runner:

  • Executes each benchmark N times and reports the average TPS (default 3; set via the passes argument or the interactive prompt)
  • Skips benchmarks already completed for a given model hash
  • Stores results in data/shared/benchmarks/<benchmark_name>.txt (one line per model hash)
  • Requires the inference server to be running (RUNNING status)

Benchmark problems

File Type Description
c1.json SQL Generate a MySQL query from a schema
c2.json Bash Write a file-sorting script
c3.json PHP Optimize a user-processing loop
c4.json Python Add token-bucket rate limiting to an API gateway
c5.json TypeScript Refactor a checkout service into a typed module
c6.json Go Fix a data race in a shared counter
c7.json HTML,CSS,Javascript Create chart based on pasted yml data

gf_benchy

gf_benchy is a generic, prompt-agnostic benchmark that measures raw prompt-processing (PP) and token-generation (TG) throughput at various KV-cache depths. It runs llama-benchy (via uvx) against the currently loaded model, filling the context to a chosen depth (2k / 32k / 132k) and reporting mean TPS. Results are cached per model hash and depth, so presets can be benchmarked one by one without re-running completed ones.

cd scripts
./gf_benchy

The interactive menu lets you run a single depth, run across all presets, list results, or switch presets.

Note: Because the test texts are generic prose (not real coding tasks), gf_benchy is good for pinpointing the best general model configuration, but it is not a reliable way to tune MTP (multi-token prediction) settings. For MTP tuning, prefer glacierflow_benchmark, which uses real-life coding tasks.


GPU Layers Autotune

GlacierFlow includes a GPU layers autotune script that finds the optimal number of layers to offload to the GPU. It uses binary search to locate the highest layer count that still passes a context stability test, then optionally runs a quick benchmark across all layers.

cd scripts
./glacierflow_autotune_gpu_layers

How It Works

  • Stability test — runs llama-benchy (via uvx) with a given context size (--pp) and checks whether the inference server can process the prompt without OOM or errors
  • Binary search — starts from the current --gpu-layers value and searches up or down to find the flip point (highest passing layer)
  • Quick benchmark — sends 3 requests using the c1.json preset and averages the predicted TPS, stepping down one layer at a time

The script modifies --gpu-layers in the compose source file and restarts the inference server between each test. It requires the daemon to be running so it can manage the server lifecycle.

Caveats

  • The autotune script works on currently loaded preset and does not support llama's router mode
  • The preset file must contain a --gpu-layers argument in one line for the script to work

MTP Preset Grid Generator

gf_gen_mtp_prob_presets_range generates a grid of inference presets from a prototype file for sweeping MTP (multi-token prediction) settings. It creates a 9×9 grid by varying:

  • --spec-draft-n-max from 1 to 9
  • --spec-draft-p-min from 0.1 to 0.9

Each combination is written as 000_testbed_mtp_<n-max>_prob_<p-min>.yml next to the prototype file (existing files are overwritten).

# With a prototype argument (bare filename or path)
cd scripts
./gf_gen_mtp_prob_presets_range preset_to_base_mtp_variations_on.yml

# Without an argument — prompts for the prototype file
# (default: preset_to_base_mtp_variations_on.yml)
cd scripts
./gf_gen_mtp_prob_presets_range

A bare filename is resolved against data/shared/inference_presets/local; a path (containing /) is used as-is. The prototype must contain both --spec-draft-n-max and --spec-draft-p-min on non-comment lines, otherwise the script exits with an error.

The generated presets are meant to be benchmarked one by one (e.g. with glacierflow_benchmark, which is the recommended tool for MTP tuning) to find the best n-max / p-min combination for a given model.


Stable Diffusion

GlacierFlow supports running stable-diffusion.cpp for image generation, replacing llama.cpp inference server. The daemon can automatically download and update the binaries on start.

Setup

  1. Enable in .env — set GF_STABLE_DIFFUSION_ENABLE=1 to have the daemon fetch/update stable-diffusion.cpp binaries automatically on each startup:
GF_STABLE_DIFFUSION_ENABLE=1

The source URL is configurable via GF_STABLE_DIFFUSION_SOURCE in .env. The default points to a Vulkan build. Binaries are extracted into data/stable_diffusion/binaries/, and the current version is tracked in data/stable_diffusion/current_source.txt.

  1. Pick a preset — example Stable Diffusion presets live in data/shared/inference_presets/examples/. Copy one to your local directory:
cp data/shared/inference_presets/examples/vulkan_8gb_stable_diffusion_realistic_stock_photo_v20.yml \
   data/shared/inference_presets/local/

Select it as usual via the preset switcher or Web UI.

  1. Restart the daemon — the binaries will be downloaded on next boot and the inference server will restart with the new preset.

Example Presets

Preset Model Notes
vulkan_8gb_stable_diffusion_realistic_stock_photo_v20.yml realisticStockPhoto v2.0 SD 1.5 model, Vulkan + CPU offload
vulkan_8gb_stable_diffusion_ideogram_4.yml ideogram-4 GGUF Includes LLM VAE pipeline with Qwen3-VL, Vulkan + CPU offload

How It Works

When GF_STABLE_DIFFUSION_ENABLE=1, the daemon calls data/stable_diffusion/update_source.sh during startup. The script:

  • Checks if the binary source URL has changed (compared against current_source.txt)
  • Downloads and extracts the release archive into binaries/
  • Overwrites any existing installation

The preset YAML files use a Dockerfile at data/stable_diffusion/docker/Dockerfile that installs Vulkan drivers and runs /app/sd-server as entrypoint. The inference server port (8080) is shared.


Audio.cpp

GlacierFlow supports running audio.cpp for audio model inference, replacing llama.cpp inference server. The daemon can automatically clone and build the source on start.

Setup

  1. Enable in .env — set GF_AUDIO_CPP_ENABLE=1 to have the daemon clone/build audio.cpp automatically on each startup:
GF_AUDIO_CPP_ENABLE=1

The source is cloned from https://github.com/0xShug0/audio.cpp.git into ~/.audio.cpp-src (configurable via GF_AUDIO_CPP_SRC_DIR). The build is CPU-heavy, so you may prefer to run data/audio_cpp/update_source.sh manually with GF_AUDIO_CPP_ENABLE=0. The current build version (git commit) is tracked in data/audio_cpp/last_build.txt — the build is skipped when the source is unchanged.

  1. Place models — audio.cpp models (GGUF) go into the AUDIO_CPP subdirectory of your models directory (GF_MODELS_DIRECTORY/AUDIO_CPP/). Models are available at audio-cpp/audio.cpp-gguf.

  2. Pick a preset — the example audio.cpp preset lives in data/shared/inference_presets/examples/. Copy it to your local directory:

cp data/shared/inference_presets/examples/vulkan_8gb_audio_cpp.yml \
   data/shared/inference_presets/local/

Select it as usual via the preset switcher or Web UI.

  1. Restart the daemon — the server will start with the new preset.

Example Presets

Preset Notes
vulkan_8gb_audio_cpp.yml Vulkan backend, web UI enabled (--ui --ui-management), single loaded model

How It Works

When GF_AUDIO_CPP_ENABLE=1, the daemon calls data/audio_cpp/update_source.sh during startup. The script:

  • Clones the audio.cpp repo if missing, then pulls the latest source
  • Compares the current git commit against last_build.txt and skips the build when unchanged
  • Builds the audiocpp_cli and audiocpp_server binaries with the Vulkan backend and copies them into data/audio_cpp/build/bin/

The preset is built from a Dockerfile at data/audio_cpp/docker/Dockerfile (Ubuntu 26.04 with libgomp and Mesa Vulkan drivers) that runs /app/audiocpp_server as entrypoint. The preset mounts the build output to /app and the AUDIO_CPP models directory to /app/models. The inference server port (8080) is shared.

See the audio.cpp server example docs for server options.


Status

The daemon tracks the server state in data/shared/inference_status.txt:

Status Meaning
RUNNING Server is up and responding (HTTP 200)
LOADING Server container started, model still loading
STOPPED Server is down
LAUNCHING Docker compose is pulling/starting
AUTO_SWITCHING FIFO proxy is switching the backend between LLM and SD presets (automatic mode switching)
LOCKED Server is locked (inference lock file present)
NOT CONFIGURED No active config found
DEGRADED Unexpected response

FIFO Proxy

GlacierFlow includes a Go-based FIFO (first-in-first-out) proxy that sits between clients and the llama.cpp inference server. It serializes /v1/chat/ requests so they are processed strictly one at a time, preventing SSE stream cut-offs when the model is hot-swapped mid-inference.

How It Works

  • Serialized routing: /v1/chat/ requests are queued and dispatched one-by-one to the backend
  • Parallel routing: All other routes (health checks, non-chat endpoints) are proxied in parallel via standard reverse proxy
  • Auto-rebuild: The entrypoint detects source changes and rebuilds the Go binary automatically
  • Restart loop: If the proxy crashes, it restarts after a 2-second delay

Configuration

The proxy runs on port 8070 (container port 8080). It is started automatically by the daemon — no manual setup required.

If you prefer to bypass the proxy entirely, uncomment the ports section in docker/llama_cpp/compose.yml and point your clients directly at port 8080 (Or create preset with ports section override).

Request/Response Dumping

The proxy can record request and response pairs to JSON files for debugging and inspection. Enable it by setting GF_PROXY_DUMP_REQUESTS=1 in your .env file:

GF_PROXY_DUMP_REQUESTS=1

When enabled, each request/response pair is dumped to docker/fifo_proxy/dumps/ as three files sharing a common <timestamp> prefix (format: YYYY_MM_DD_HH_MM_SS):

  • <timestamp>_request.json — the exact request body, unmodified
  • <timestamp>_response.json — the full response body, pretty-printed when it is valid JSON, raw bytes otherwise (e.g. SSE event streams)
  • <timestamp>_details.json — request method and path:
{
  "requestMethod": "POST",
  "requestPath": "/v1/chat/completions"
}

The dump is written when the response completes or when the client disconnects. Dumped files are gitignored.

Automatic Mode Switching (LLM ↔ Stable Diffusion)

The proxy can automatically switch the backend between a llama.cpp (chat) preset and a stable-diffusion.cpp (image) preset. This lets a single client — e.g. Cherry Studio — use both chat and image generation through the same endpoint (port 8070), without manually switching presets via the daemon, CLI or Web UI.

Requests are classified by route:

  • /v1/chat/* → LLM mode (llama.cpp preset)
  • /v1/images/* → SD mode (stable-diffusion.cpp preset)

When a request arrives in a mode different from the one currently loaded, the proxy:

  1. Waits until the backend is idle (RUNNING status)
  2. Remembers the preset currently loaded for the mode it is switching away from, so it can be restored on the next switch back
  3. Writes the target preset name to data/shared/inference_preset_name_target.txt and copies data/shared/inference_presets/local/<preset>.yml to data/shared/inference_config.yml
  4. Sets the status to AUTO_SWITCHING and waits for the daemon to restart the server and the status to return to RUNNING

The request that triggered the switch is held in the FIFO queue until the new model is ready. The proxy always starts in LLM mode.

Setup

  1. Enable in .env:
GF_PROXY_AUTO_MODE=1
GF_DEFAULT_MODEL_LLM=vulkan_8gb_gemma4_e4b_q4
GF_DEFAULT_MODEL_SD=vulkan_8gb_stable_diffusion_z_image_turbo
  • GF_PROXY_AUTO_MODE — set to 1 to enable automatic mode switching (default 0)
  • GF_DEFAULT_MODEL_LLM — name of the llama.cpp preset (filename without .yml) to load for chat mode. The daemon also loads this preset on startup, so the backend starts in LLM mode
  • GF_DEFAULT_MODEL_SD — name of the stable-diffusion.cpp preset to load for image generation mode
  1. Place both presets in data/shared/inference_presets/local/ — the proxy copies the preset file from the local presets directory, so example presets alone are not enough. You need to setup i.e. width and height for z-image.

  2. Keep the daemon running — the daemon is what applies the config change and restarts the inference container. The proxy only coordinates via the shared status/preset files in data/shared/ (mounted into the proxy container at /glacierflow-shared).

Caveats

  • The first request after a mode switch waits for the new model to load (status AUTO_SWITCHING), so expect a delay on that request
  • If GF_DEFAULT_MODEL_LLM / GF_DEFAULT_MODEL_SD is empty, or the preset file is missing, the switch is skipped and the request is proxied to the backend in its current mode
  • Manual preset switching (CLI / Web UI) still works as usual — the proxy picks up the manually selected preset name the next time it switches back to that mode.
  • Manual switching between sd and llm modes might get daemon confused but switching between i.e. gemma and qwen wis fine.

Performance Statistics

GlacierFlow can log inference performance metrics — fill TPS, gen TPS, draft acceptance rate, and total tokens — to per-preset log files and visualize them in the Web UI.

Setup

  1. Enable logging by setting GF_LOG_STATS=1 in your .env file:
GF_LOG_STATS=1
  1. Start the daemon. The daemon will write stats to data/stats/<YYMMDD>_<preset_name>_<hash>.log files — one per day per preset.

Usage

Open the Stats Viewer from the Web UI toolbar link. The viewer loads the log files and renders them as an interactive Chart.js chart. Clear all button resets the chart view.

Caveats

If preset is using llama's router mode you won't be able to recognize which model was actually called.


Embedding Server

GlacierFlow includes a configurable llama.cpp embedding server for generating vector embeddings. It is disabled by default and can be enabled by creating an override config.

Setup

  1. Enable the server by creating docker/llama_embeddings/compose.override.yml with your desired command:
services:
  glacierflow-embeddings:
    command: >
      -hf ggml-org/embeddinggemma-300M-GGUF
      --embeddings
  1. Configure the port in your .env file (defaults to 8060):
GF_EMBEDDING_PORT=8060

The embedding server starts automatically alongside the main daemon when the override config is present.

Usage

Once running, the embedding server exposes an OpenAI-compatible API at http://localhost:8060/v1/embeddings.


Coder: Code Generation Assistant

GlacierFlow ships with a Dockerized pi.dev development environment for AI-assisted code generation. It runs inside a full-featured dev container with all common languages and tools pre-installed.

Setup

  1. Configure the model provider in data/pi_dev/config/agent/models.json:
{
  "providers": {
    "glacierflow-llamacpp": {
      "baseUrl": "http://glacierflow-proxy:8080/v1",
      "api": "openai-completions",
      "apiKey": "none",
      "models": [
        { "id": "glacierflow-coder-feather" },
        { "id": "glacierflow-coder-light" },
        { "id": "glacierflow-coder-default" },
        { "id": "glacierflow-coder-heavy" },
        { "id": "glacierflow-coder-thinking-feather", "reasoning": true, "thinkingLevelMap": { "off": null } },
        { "id": "glacierflow-coder-thinking-light", "reasoning": true, "thinkingLevelMap": { "off": null } },
        { "id": "glacierflow-coder-thinking-default", "reasoning": true, "thinkingLevelMap": { "off": null } },
        { "id": "glacierflow-coder-thinking-heavy", "reasoning": true, "thinkingLevelMap": { "off": null } }
      ]
    }
  }
}

Note: By default this points through the FIFO proxy (glacierflow-proxy) so chat requests are serialized. If you bypass the proxy, change the URL to http://glacierflow-llamacpp:8080/v1.

  1. Set your inference preset — the pi.dev container by default uses the model you configured with glacierflow_inference_select_preset script.

Default Model

The start script tracks a default model (default: glacierflow-coder-thinking-default) and passes it to all pi invocations via --model. The current default is shown at the top of every menu, and you can change it with the [M] option (main and kick-off menus). The selection is persisted to ~/.default_model inside the container and restored on next start (unknown/stale values fall back to the built-in default).

Usage

The pi.dev container starts automatically with the daemon. You can access it in two ways:

Web Terminal (TTYD): Open https://localhost:7681 in your browser (or click "pi.dev httpd" from the Web UI toolbar). Log in with the credentials set via GF_HTTP_USER / GF_HTTP_PASSWORD (defaults: glacierflow / glacierflow). The terminal launches inside a persistent tmux session. Note: if using the default self-signed certificate, you'll need to accept the browser's security warning.

Management script: For start/stop/attach control:

cd scripts
./glacierflow_pi_code

Container Details

  • Image: Alpine-based with bash, curl, ttyd, tmux, git, npm, and vim as basic requirements. Additional packages can be passed via GF_PI_EXTRA_PACKAGES .env arg (space-separated list).
  • User: Runs as non-root (pi_dev, UID configurable via GF_USER_ID, defaults to 1000)
  • TTYD: Web terminal server on port 7681 with basic auth (configurable via GF_PI_DEV_TTYD_USER / GF_PI_DEV_TTYD_PASSWORD)
  • Auto-update: On startup, the container checks for and applies pi.dev updates automatically. Extensions are not pre-installed but can be added manually — they survive image rebuilds.
  • tmux: Persistent session (pi_dev_task) with custom config mounted from data/pi_dev/tmux.conf
  • Volume mounts:
    • Project root → /pi_dev (read-only)
    • Config → ~/.pi (read-write)
    • Scripts → /pi_dev_scripts (read-write, for builtin conversation-starter scripts)
    • tmux config → ~/.tmux.conf (read-only)
    • Workdir → configurable via GF_PI_DEV_WORKDIR env var (read-write)

Hermes: AI Agent Container

GlacierFlow ships with a Dockerized Hermes agent environment for AI-driven task management, research, and kanban workflows. It runs inside an Ubuntu-based container with Hermes CLI, web dashboard, and gateway pre-installed.

Setup

  1. Auto-start with daemon — set GF_HERMES_AUTOSTART=1 in your .env file to start the Hermes container automatically when the daemon launches:
GF_HERMES_AUTOSTART=1
  1. Manual start — use the management script:
cd scripts
./glacierflow_hermes

Usage

The Hermes container provides multiple access points:

Web Terminal (TTYD): Open https://localhost:7682 in your browser (or click "hermes httpd" from the Web UI toolbar). Log in with the credentials set via GF_HTTP_USER / GF_HTTP_PASSWORD.

Hermes Dashboard: Open https://localhost:7683 in your browser (or click "hermes Web UI" from the Web UI toolbar) for the web-based Hermes dashboard.

Configuring Hermes for Local Inference

To use your local llama.cpp inference server with Hermes:

  1. Attach to the container or use the TTYD terminal
  2. Run the configuration menu (C key) or hermes setup
  3. Use http://glacierflow-proxy:8080/v1 as the custom endpoint URL to route through the FIFO proxy

Container Details

  • Image: Ubuntu-based with bash, curl, ttyd, tmux, git, vim, python3, nodejs, npm, ripgrep, ffmpeg
  • User: Runs as non-root (ubuntu, UID configurable via GF_USER_ID / GF_USER_GROUP_ID, defaults to 1000)
  • TTYD: Web terminal server on port 7682 with basic auth
  • Dashboard: Web UI on port 7683
  • tmux: Persistent session (hermes_task)
  • Volume mounts:
    • Hermes data → data/hermes/ (read-write, configurable via GF_HERMES_WORKDIR)

VS Code: Online Code Editor

GlacierFlow includes a code-server instance for web-based code editing. It shares the same workspace as pi.dev and is accessible through the Caddy reverse proxy.

Setup

  1. Auto-start with daemon — set GF_VSCODE_AUTOSTART=1 in your .env file to start the VS Code container automatically when the daemon launches:
GF_VSCODE_AUTOSTART=1
  1. Configure the version (optional) — by default the latest image is used. Pin a specific version with:
GF_VSCODE_VERSION=4.96.1
  1. Configure the port (defaults to 7684):
GF_VSCODE_WEB_PORT=7684

Usage

Access VS Code at https://localhost:7684 in your browser, or click "VS Code" from the Web UI toolbar.

Container Details

  • Image: codercom/code-server (latest by default, configurable via GF_VSCODE_VERSION)
  • User: PUID/PGID configurable via GF_USER_ID / GF_USER_GROUP_ID
  • Healthcheck: Monitors HTTP availability on port 8080
  • Volume mounts:
    • Local data → data/vscode/local/ (user settings, extensions)
    • Config → data/vscode/config/ (code-server config)
    • Workdir → shared with pi.dev via GF_PI_DEV_WORKDIR
  • Caddy: Reverse proxied on port 7684 through the Caddy service

Remotes


License

GlacierFlow itself is a collection of custom scripts — no license applies. Third-party software (llama.cpp, stable-diffusion.cpp, audio.cpp, Docker, pi.dev, llama-benchy, vscode and so on.) is subject to their respective licenses.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages