Alphakdeps.io is experimental and evolving — the registry and packages may change or reset.
Docker templatekdeps asset

kdeps-docker-image

v1.0.0

kdeps dockerfile: image

Install

A kdeps asset: kdeps installs it on first run and updates it without a new release.

kdeps update docker/image

Pin a version with kdeps update docker/image@<version>.

Contents

alpine.Dockerfile.tmpl

FROM {{ .BaseImage }}

# Set environment variables
ENV PYTHONUNBUFFERED=1 \
    PATH=/root/.local/bin:/opt/venv/bin:$PATH \
    KDEPS_BIND_HOST=0.0.0.0 \
    KDEPS_ASSETS_DIR=/app/.kdeps/assets \
    {{- if .LlamafileModels }}
    KDEPS_MODELS_DIR=/app/.kdeps/models \
    {{- end }}
    {{- if .InstallOllama }}
    OLLAMA_HOST=127.0.0.1 \
    OLLAMA_PORT={{ .BackendPort }} \
    OLLAMA_MODELS=/app/.ollama/models \
    {{- end }}
    BACKEND_PORT={{ .BackendPort }}
{{- if .Env }}

# User-defined environment variables
{{- range $key, $value := .Env }}
ENV {{ $key }}="{{ $value }}"
{{- end }}
{{- end }}

# Install base dependencies (upgrade first to pick up security patches
# published after the base image was built)
RUN apk upgrade --no-cache && \
    apk add --no-cache \
    zstd \
    python3 \
    py3-pip \
    curl \
    wget \
    bash \
    supervisor \
    ca-certificates \
    libstdc++ \
    ncurses \
    rsync

{{- if .UsePrepackagedBinary }}
# Install prepackaged kdeps binary (self-contained, workflow embedded).
# TARGETARCH is set automatically by `docker buildx build --platform`; for a
# plain `docker build` it falls back to the host arch via `uname -m`.
ARG TARGETARCH
{{- if .PrepackagedAMD64 }}
COPY kdeps-linux-amd64 /tmp/kdeps-linux-amd64
{{- end }}
{{- if .PrepackagedARM64 }}
COPY kdeps-linux-arm64 /tmp/kdeps-linux-arm64
{{- end }}
RUN ARCH="${TARGETARCH:-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')}" && \
    if [ -f "/tmp/kdeps-linux-${ARCH}" ]; then \
        mv "/tmp/kdeps-linux-${ARCH}" /usr/local/bin/kdeps; \
    else \
        curl -LsSf https://raw.githubusercontent.com/kdeps/kdeps/{{ .InstallerRef }}/install.sh | sh -s -- -b /usr/local/bin {{ .InstallerRef }}; \
    fi && \
    rm -f /tmp/kdeps-linux-amd64 /tmp/kdeps-linux-arm64 && \
    chmod +x /usr/local/bin/kdeps
{{- else }}
# Install kdeps binary
RUN curl -LsSf https://raw.githubusercontent.com/kdeps/kdeps/{{ .InstallerRef }}/install.sh | sh -s -- -b /usr/local/bin {{ .InstallerRef }}
{{- end }}

{{- if .OSPackages }}

# Install OS packages
RUN apk add --no-cache{{ range .OSPackages }} {{ . }}{{ end }}
{{- end }}

# Install LLM backend
{{ .BackendInstall }}

{{- if .InstallUV }}

# Install uv for Python package management
COPY --from=ghcr.io/astral-sh/uv:{{ .UVImageTag }} /uv /usr/local/bin/uv
RUN chmod +x /usr/local/bin/uv

# Create virtual environment
RUN /usr/local/bin/uv venv /opt/venv
{{- end }}

{{- if .PythonPackages }}

# Install Python packages
RUN /usr/local/bin/uv pip install{{ range .PythonPackages }} {{ . }}{{ end }}
{{- end }}

{{- if .RequirementsFile }}

# Install from requirements file
COPY {{ .RequirementsFile }} /tmp/requirements.txt
RUN /usr/local/bin/uv pip install -r /tmp/requirements.txt
{{- end }}

# kdeps assets (harness, tools, model registries, ...) from the build host,
# so the container needs no download at start
COPY kdeps-assets/ /app/.kdeps/assets/

# Copy workflow files
{{- if not .UsePrepackagedBinary }}
COPY workflow.yaml /app/workflow.yaml
{{- if .HasResources }}
COPY resources/ /app/resources/
{{- end }}
{{- if .HasData }}
COPY data/ /app/data/
{{- end }}
{{- end }}

# Copy entrypoint and supervisor config
COPY entrypoint.sh /entrypoint.sh
COPY supervisord.conf /etc/supervisord.conf
RUN chmod +x /entrypoint.sh

# Ensure log directory exists
RUN mkdir -p /var/log

{{- if and .OfflineMode .Models .InstallOllama }}

# Download models during build time for offline mode
RUN mkdir -p /llm

# Download Ollama models
RUN (OLLAMA_HOST=127.0.0.1 /usr/local/bin/ollama serve &) && \
    sleep 10 && \
    {{- range $i, $model := .Models }}{{ if $i }} && \{{ end }}
    OLLAMA_HOST=127.0.0.1 /usr/local/bin/ollama pull {{ $model }}{{ end }} && \
    pkill -f ollama && \
    sleep 2 && \
    # Copy to the image layer
    cp -r /root/.ollama/* /llm/
{{- end }}

{{- if .LlamafileModels }}

# Pre-bake llamafile models (file backend)
RUN mkdir -p /app/.kdeps/models && \
    {{- range .LlamafileModels }}
    curl -fL --retry 3 -o /app/.kdeps/models/{{ .File }} "{{ .URL }}" && \
    chmod +x /app/.kdeps/models/{{ .File }} && \
    {{- end }}
    true
{{- end }}

WORKDIR /app

# Run as non-root (supervisord + kdeps; Ollama models live under /app/.ollama).
RUN addgroup -S kdeps && adduser -S -G kdeps kdeps && \
    {{- if .InstallOllama }}
    mkdir -p /app/.ollama/models && \
    {{- end }}
    chown -R kdeps:kdeps /app /var/log /entrypoint.sh /etc/supervisord.conf
USER kdeps

# Expose ports
{{- if .HasAPIServer }}
EXPOSE {{ .APIPort }}
{{- end }}
{{- if .HasWebServer }}
EXPOSE {{ .WebServerPort }}
{{- end }}
{{- if .InstallOllama }}
EXPOSE {{ .BackendPort }}
{{- end }}

{{- if .HasAPIServer }}
# Healthcheck (API server serves /health)
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
  CMD wget -qO- http://localhost:{{ .APIPort }}/health || exit 1
{{- else if .HasWebServer }}
# Healthcheck (web server has no /health endpoint; check the TCP socket)
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
  CMD bash -c 'exec 3<>/dev/tcp/127.0.0.1/{{ .WebServerPort }}' || exit 1
{{- end }}

# Use entrypoint for backend management
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]

backend_install.tmpl

{{- if .InstallOllama }}
# Ollama included in base image
{{- else }}
# No LLM backend to install
{{- end }}

entrypoint.sh.tmpl

#!/bin/bash
set -euo pipefail

echo "=== KDeps Docker Container Starting ==="
{{- if .InstallOllama }}
echo "Ollama enabled on port: ${BACKEND_PORT:-11434}"
{{- else if .LlamafileModels }}
echo "LLM backend: file (llamafile, self-serving)"
{{- else }}
echo "No local LLM backend installed"
{{- end }}

{{- if .InstallOllama }}
# Function to wait for Ollama to be ready
wait_for_ollama() {
    local port=$1
    local max_attempts=30
    local attempt=0

    echo "Waiting for Ollama to be ready on port $port..."

    while [ $attempt -lt $max_attempts ]; do
        if curl -s http://localhost:$port/api/tags >/dev/null 2>&1; then
            echo "Ollama is ready!"
            return 0
        fi
        attempt=$((attempt + 1))
        echo "Attempt $attempt/$max_attempts: Ollama not ready yet..."
        sleep 2
    done

    echo "WARNING: Ollama did not become ready after $max_attempts attempts"
    return 1
}
{{- end }}

# Handle models based on offline mode
{{- if and .OfflineMode .Models .InstallOllama }}
if [ -d "/llm/models" ]; then
    echo "Offline mode: Copying pre-downloaded models to Ollama directory..."

    MODELS_DIR="${OLLAMA_MODELS:-/app/.ollama/models}"
    mkdir -p "$MODELS_DIR"
    rsync -avrPtz --human-readable /llm/models/. "$MODELS_DIR/" || \
    cp -r /llm/models/* "$MODELS_DIR/" 2>/dev/null || true
    echo "Ollama models copied successfully"
else
    echo "WARNING: No pre-downloaded Ollama models found in /llm/models"
fi
{{- else if and .Models .InstallOllama }}
# Download models if specified (not in offline mode)
echo "Pre-pulling Ollama models..."

# Start Ollama temporarily in the background if it's not already running
# so we can pull models during the entrypoint phase.
TEMP_OLLAMA_PID=""
if ! curl -s http://localhost:${BACKEND_PORT:-11434}/api/tags >/dev/null 2>&1; then
    echo "Starting Ollama server temporarily for model pulling..."
    /usr/local/bin/ollama serve > /tmp/ollama_entrypoint.log 2>&1 &
    TEMP_OLLAMA_PID=$!
    wait_for_ollama ${BACKEND_PORT:-11434}
fi

{{- range .Models }}
/usr/local/bin/ollama pull {{ . }} || echo "Failed to pull {{ . }}, will retry at runtime"
{{- end }}

# Kill the temporary Ollama process if we started one
if [ -n "$TEMP_OLLAMA_PID" ]; then
    echo "Stopping temporary Ollama server..."
    kill $TEMP_OLLAMA_PID || true
    sleep 2
fi
{{- end }}

# Ensure the workflow binds to all interfaces inside containers
# (overrides any hostIp: "127.0.0.1" in the workflow YAML)
if [ -f /app/workflow.yaml ]; then
    sed -i 's/hostIp: "127.0.0.1"/hostIp: "0.0.0.0"/g' /app/workflow.yaml
    sed -i 's/hostIp: 127.0.0.1/hostIp: 0.0.0.0/g' /app/workflow.yaml
fi

# Execute the command passed to docker run
exec "$@"

supervisord.conf.tmpl

[supervisord]
nodaemon=true
logfile=/var/log/supervisord.log
pidfile=/tmp/supervisord.pid
loglevel=info

{{- if .InstallOllama }}

[program:ollama]
command=/usr/local/bin/ollama serve
autostart=true
autorestart=true
startretries=10
stderr_logfile=/var/log/ollama.err.log
stdout_logfile=/var/log/ollama.out.log
priority=10
stopwaitsecs=30
environment=OLLAMA_HOST="127.0.0.1",OLLAMA_MODELS="/app/.ollama/models"

{{- end }}

[program:kdeps]
{{- if .UsePrepackagedBinary }}
command=/usr/local/bin/kdeps
{{- else }}
command=/usr/local/bin/kdeps run /app/workflow.yaml
{{- end }}
autostart=true
autorestart=true
startretries=3
stderr_logfile=/var/log/kdeps.err.log
stdout_logfile=/var/log/kdeps.out.log
priority=20
environment=KDEPS_BIND_HOST="0.0.0.0"
{{- if .InstallOllama }}
depends_on=ollama
{{- end }}

ubuntu.Dockerfile.tmpl

FROM {{ .BaseImage }}

# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive \
    PYTHONUNBUFFERED=1 \
    PATH=/opt/venv/bin:$PATH \
    KDEPS_BIND_HOST=0.0.0.0 \
    KDEPS_ASSETS_DIR=/app/.kdeps/assets \
    {{- if .LlamafileModels }}
    KDEPS_MODELS_DIR=/app/.kdeps/models \
    {{- end }}
    {{- if .InstallOllama }}
    OLLAMA_HOST=127.0.0.1 \
    OLLAMA_PORT={{ .BackendPort }} \
    OLLAMA_MODELS=/app/.ollama/models \
    {{- end }}
    BACKEND_PORT={{ .BackendPort }}
{{- if .Env }}

# User-defined environment variables
{{- range $key, $value := .Env }}
ENV {{ $key }}="{{ $value }}"
{{- end }}
{{- end }}

# Install base dependencies (upgrade first to pick up security patches
# published after the base image was built)
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y \
        zstd \
        python3 \
        python3-venv \
        python3-pip \
        curl \
        wget \
        ca-certificates \
        supervisor \
        bash \
        rsync && \
    rm -rf /var/lib/apt/lists/*

{{- if .UsePrepackagedBinary }}
# Install prepackaged kdeps binary (self-contained, workflow embedded).
# TARGETARCH is set automatically by `docker buildx build --platform`; for a
# plain `docker build` it falls back to the host arch via `uname -m`.
ARG TARGETARCH
{{- if .PrepackagedAMD64 }}
COPY kdeps-linux-amd64 /tmp/kdeps-linux-amd64
{{- end }}
{{- if .PrepackagedARM64 }}
COPY kdeps-linux-arm64 /tmp/kdeps-linux-arm64
{{- end }}
RUN ARCH="${TARGETARCH:-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')}" && \
    if [ -f "/tmp/kdeps-linux-${ARCH}" ]; then \
        mv "/tmp/kdeps-linux-${ARCH}" /usr/local/bin/kdeps; \
    else \
        curl -LsSf https://raw.githubusercontent.com/kdeps/kdeps/{{ .InstallerRef }}/install.sh | sh -s -- -b /usr/local/bin {{ .InstallerRef }}; \
    fi && \
    rm -f /tmp/kdeps-linux-amd64 /tmp/kdeps-linux-arm64 && \
    chmod +x /usr/local/bin/kdeps
{{- else }}
# Install kdeps binary
RUN curl -LsSf https://raw.githubusercontent.com/kdeps/kdeps/{{ .InstallerRef }}/install.sh | sh -s -- -b /usr/local/bin {{ .InstallerRef }}
{{- end }}

{{- if .OSPackages }}

# Install OS packages
RUN apt-get update && \
    apt-get install -y{{ range .OSPackages }} {{ . }}{{ end }} && \
    rm -rf /var/lib/apt/lists/*
{{- end }}

# Install LLM backend
{{ .BackendInstall }}

{{- if .InstallUV }}

# Install uv for Python package management
COPY --from=ghcr.io/astral-sh/uv:{{ .UVImageTag }} /uv /usr/local/bin/uv
RUN chmod +x /usr/local/bin/uv

# Create virtual environment
RUN /usr/local/bin/uv venv /opt/venv
{{- end }}

{{- if .PythonPackages }}

# Install Python packages
RUN /usr/local/bin/uv pip install{{ range .PythonPackages }} {{ . }}{{ end }}
{{- end }}

{{- if .RequirementsFile }}

# Install from requirements file
COPY {{ .RequirementsFile }} /tmp/requirements.txt
RUN /usr/local/bin/uv pip install -r /tmp/requirements.txt
{{- end }}

# kdeps assets (harness, tools, model registries, ...) from the build host,
# so the container needs no download at start
COPY kdeps-assets/ /app/.kdeps/assets/

# Copy workflow files
{{- if not .UsePrepackagedBinary }}
COPY workflow.yaml /app/workflow.yaml
{{- if .HasResources }}
COPY resources/ /app/resources/
{{- end }}
{{- if .HasData }}
COPY data/ /app/data/
{{- end }}
{{- end }}

# Copy entrypoint and supervisor config
COPY entrypoint.sh /entrypoint.sh
COPY supervisord.conf /etc/supervisord.conf
RUN chmod +x /entrypoint.sh

# Ensure log directory exists
RUN mkdir -p /var/log

{{- if and .OfflineMode .Models .InstallOllama }}

# Download models during build time for offline mode
RUN mkdir -p /llm

# Download Ollama models
RUN (OLLAMA_HOST=127.0.0.1 /usr/local/bin/ollama serve &) && \
    sleep 10 && \
    {{- range $i, $model := .Models }}{{ if $i }} && \{{ end }}
    OLLAMA_HOST=127.0.0.1 /usr/local/bin/ollama pull {{ $model }}{{ end }} && \
    pkill -f ollama && \
    sleep 2 && \
    # Copy to the image layer
    cp -r /root/.ollama/* /llm/
{{- end }}

{{- if .LlamafileModels }}

# Pre-bake llamafile models (file backend)
RUN mkdir -p /app/.kdeps/models && \
    {{- range .LlamafileModels }}
    curl -fL --retry 3 -o /app/.kdeps/models/{{ .File }} "{{ .URL }}" && \
    chmod +x /app/.kdeps/models/{{ .File }} && \
    {{- end }}
    true
{{- end }}

WORKDIR /app

# Run as non-root (supervisord + kdeps; Ollama models live under /app/.ollama).
RUN groupadd -r kdeps && useradd -r -g kdeps -d /app -s /usr/sbin/nologin kdeps && \
    {{- if .InstallOllama }}
    mkdir -p /app/.ollama/models && \
    {{- end }}
    chown -R kdeps:kdeps /app /var/log /entrypoint.sh /etc/supervisord.conf
USER kdeps

# Expose ports
{{- if .HasAPIServer }}
EXPOSE {{ .APIPort }}
{{- end }}
{{- if .HasWebServer }}
EXPOSE {{ .WebServerPort }}
{{- end }}
{{- if .InstallOllama }}
EXPOSE {{ .BackendPort }}
{{- end }}

{{- if .HasAPIServer }}
# Healthcheck (API server serves /health)
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
  CMD wget -qO- http://localhost:{{ .APIPort }}/health || exit 1
{{- else if .HasWebServer }}
# Healthcheck (web server has no /health endpoint; check the TCP socket)
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
  CMD bash -c 'exec 3<>/dev/tcp/127.0.0.1/{{ .WebServerPort }}' || exit 1
{{- end }}

# Use entrypoint for backend management
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]

Versions

VersionPublishedStatus
1.0.010/13/2026active

Details

Author
kdeps
License
Apache-2.0
Latest Version
1.0.0
Published
10/13/2026

Tags

kdepsdockerfile