Skip to content

About

LM Studio headless container

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

lmstudio

Containerized LM Studio, in two flavors, built from a single unified Dockerfile:

  • lmstudio — the full desktop app, streamed to your browser via Selkies, on top of the linuxserver.io Selkies base image.
  • llmster — the headless daemon (LM Studio's lms CLI), serving the OpenAI-compatible API with no GUI. Built in cpu and vulkan (GPU offload) variants.

The lmstudio (webui) image also runs llmster internally as a second background service — once a model backend is present, it automatically starts serving the API alongside the desktop app.

Layout

.
├── LMStudio/
│   ├── Dockerfile                           # unified, multi-stage: webui / cpu / vulkan targets
│   ├── Headless/
│   │   └── start.sh                         # llmster (cpu/vulkan) entrypoint
│   └── WebUI/
│       └── services/s6-overlay/             # s6 service definitions for process supervision
│           ├── lmstudio/                    # desktop app service
│           │   ├── run                      # s6 service: launches the LM Studio desktop app as `abc`
│           │   └── dependencies.d/selkies
│           └── llmster/                     # headless API service
│               ├── run                      # s6 service: waits for `lms`, then starts the API server too
│               └── dependencies.d/lmstudio
├── bake.sh                                  # wrapper: injects git SHA/ref and runs buildx bake
├── docker-bake.hcl                          # build definitions: multi-target, OCI labels, base pinning
├── docker-compose.yml                       # runtime: ports, volumes, GPU passthrough anchors
├── .github/workflows/
│   └── docker-build-push.yml                # CI: multi-registry build and push workflow
└── data/                                    # gitignored — bind-mounted model storage

Build

Images are built with docker buildx bake, not docker compose build:

./bake.sh                      # builds all three images (default group)
./bake.sh --load               # ...and loads into local Docker engine
./bake.sh lmstudio             # just the desktop/WebUI image
./bake.sh llmster              # just the headless CPU image
./bake.sh llmster-vulkan       # headless image with Vulkan libs for GPU offload
./bake.sh --push               # build and push to registry
./bake.sh --print              # resolve and print build config without building

The bake.sh wrapper automatically injects:

  • GIT_SHA: current commit hash (for OCI image revision label)
  • GIT_REF: current branch or tag name (for OCI ref.name label)

Build-time variables

See docker-bake.hcl for the complete variable list:

Variable Default Purpose
REGISTRY ghcr.io/arasemco Image registry/namespace prefix
SOURCE_URL https://github.com/arasemco/lmstudio Source code URL (for OCI labels)
LMSTUDIO_VERSION 0.4.23-1 LM Studio desktop AppImage version
LLMSTER_VERSION 0.0.23-1 llmster/lms CLI version
PLATFORMS linux/amd64 Comma-separated platforms (e.g., linux/amd64,linux/arm64)

To override:

REGISTRY=git.example.com/org PLATFORMS=linux/amd64,linux/arm64 ./bake.sh --push

Base image pinning

Base images are pinned by digest for reproducible builds:

  • Debian: docker.io/library/debian:bookworm-slim@sha256:88200866dfff7ea7f5cbcb6ec7c8a701889efe6fe859fe64d6990e4b07ea4171
  • Selkies: ghcr.io/linuxserver/baseimage-selkies:ubuntunoble@sha256:7cab02f9222937ad1e704cd904534d69a2300b2406af466241817be0ce1d0493

Update the digest in docker-bake.hcl if you need to refresh the base.

Run

docker-compose.yml only runs the images bake already built — it has no build: section:

docker compose up lmstudio   # desktop app — browser UI on :3000, API on :1234
docker compose up llmster    # headless daemon — API on :1234 only (uses :vulkan tag by default)
  • lmstudio: open http://<host>:3000 for the streamed desktop.
  • llmster: OpenAI-compatible API at http://<host>:1234/v1.

Both services mount ./data/models to /config/.lmstudio/models for persistent model storage.

Identity

Everything runs as user abc, UID/GID 911, home /config — the linuxserver.io base image's own built-in default. The headless (llmster) targets are built from scratch to match this identity exactly, rather than using a different user and reconciling the two later.

The s6 init system handles PUID/PGID remapping at container start if you set these environment variables:

environment:
  - PUID=1000
  - PGID=1000

Add these to the docker-compose.yml service definition if you need to match host permissions.

GPU passthrough

docker-compose.yml defines two reusable YAML anchors, commented out by default on each service:

# Nvidia (requires NVIDIA Container Toolkit):
#<<: *gpu-nvidia

# AMD/Intel (passthrough /dev/kfd + /dev/dri):
#<<: *gpu-amd

Uncomment whichever applies:

  • Nvidia: uses deploy.resources.reservations.devices (requires the NVIDIA Container Toolkit on the host)
  • AMD/Intel: uses /dev/kfd + /dev/dri render-node passthrough with the video group and unconfined seccomp

For GPU offload on the headless image, use the llmster-vulkan target. The compose file already points llmster at the :vulkan tag by default.

CI/CD

The GitHub Actions workflow (.github/workflows/docker-build-push.yml) automatically:

  1. Builds all three targets on pushes to master and tags
  2. Pushes to configured registries (GHCR and/or self-hosted)
  3. Cancels in-progress runs on the same branch/ref
  4. Runs on pull requests (build-only, no push)
  5. Injects GIT_SHA, GIT_REF, SOURCE_URL, and REGISTRY variables

The workflow supports both GitHub-hosted and self-hosted Gitea instances without hardcoded assumptions.

Requirements

  • Docker with the buildx plugin (v0.10+)
  • ~4 GB+ free disk for the desktop image, less for headless-only
  • A registry (GHCR, Docker Hub, or self-hosted) if pushing images
  • NVIDIA Container Toolkit (optional, for Nvidia GPU passthrough)

About

LM Studio headless container

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages