A Fedora-based Docker setup for MakeMe, the AI-powered 3D object generator. It builds MakeMe and a hardware-accelerated llama.cpp runner from source, autodetects your GPU, and mounts your working directory so models and output persist across runs.
| File | Purpose |
|---|---|
Dockerfile |
Two-stage build: builder compiles MakeMe, t3d, and a backend-matched llama.cpp runner; runtime ships only those binaries plus their actual runtime libraries |
entrypoint.sh |
Sources a runtime env.conf from the mounted directory, then runs MakeMe |
arch.sh |
Host-side GPU/backend detection (sourced by run.sh) |
run.sh |
Builds the image if missing, detects hardware, runs the container |
.dockerignore |
Excludes .git, README.md, env.conf from the build context |
env.conf |
Optional — runtime overrides (model path, MAKEME_RUN, API keys) |
MakeMe normally downloads a prebuilt llama.cpp runner from Hugging Face at first launch — but only for the platforms its release pipeline targets, and never with a specific GPU backend in mind. This setup builds that runner from source instead, so you can pick the backend that matches your actual hardware (Vulkan, ROCm, Apple Silicon/Asahi, or CPU) and point MakeMe at it via MAKEME_RUN. The base image is fedora:44, since that's also what upstream llama.cpp's own accelerated builds (and the ramalama project this borrows build logic from) use as their reference platform for Vulkan/ROCm/Asahi packaging.
git clone <this-repo>
cd <this-repo>
chmod +x run.sh arch.sh entrypoint.sh
./run.shThat's it. run.sh will:
- Detect your GPU (Apple Silicon/Asahi, NVIDIA, AMD, generic Vulkan, or none)
- Build the image if it doesn't already exist, targeting that backend
- Mount your MakeMe working directory into the container at
/workspace - Pass through the right GPU devices
- Launch MakeMe
By default the mounted directory is $HOME/Documents/MakeMe (created if missing).
Override it with MAKEME_WORKDIR if you keep your models/output elsewhere:
MAKEME_WORKDIR=/data/makeme ./run.shAnything you pass to run.sh is forwarded to makeme itself:
./run.sh --input "a coffee mug"arch.sh mirrors the detection logic in ramalama's ramalama/common.py, so it checks for real signals rather than guessing from CPU architecture alone:
- Apple Silicon (Asahi Linux): reads
/proc/device-tree/compatibleforapple,arm-platform— this is the only reliable way to tell an Apple Silicon board apart from any other arm64 machine. - NVIDIA: runs
nvidia-smi --query-gpu=...and only counts it if the query actually succeeds. - AMD/ROCm: checks for
/sys/class/kfd, but only on x86_64 — ROCm doesn't support arm64, so arm64 boards fall through to Vulkan instead. - Generic Vulkan: falls back to this if
/dev/driexists and nothing more specific matched. - CPU: last resort if no GPU device is found.
The detected backend becomes both the Docker image tag (makeme:<backend>) and a --build-arg BACKEND=<backend> passed to the build, so a machine's first run automatically produces a matching image, and later runs reuse it without rebuilding.
You can also force a backend instead of autodetecting:
BACKEND=asahi ./run.sh
BACKEND=vulkan ./run.sh
BACKEND=cpu ./run.shAn unrecognized BACKEND value (e.g. a typo) is rejected by arch.sh before any build or run starts, rather than silently producing a mismatched image tag.
- Go toolchain (latest stable) →
makeme,stl2obj - Rust toolchain (stable) →
t3d, built from liam-ilan/terminal3d, cloned intodeps/terminal3dduring the build (MakeMe ships that path as an empty directory, not a git submodule — see comment inDockerfile) llama.cpp, built via ramalama's ownbuild_llama.sh/lib.shbuild scripts, vendored via a sparsegit clone(only those two files — they're self-contained and don't depend on the rest of the ramalama repo). This picks the right CMake flags and system packages per backend automatically, including the Vulkan target for Asahi and the required@asahi/fedora-remix-brandingCOPR.- OpenSCAD, required by MakeMe to render generated SCAD code to STL
The resulting llama-cli binary is installed as /usr/local/bin/run and pointed to via ENV MAKEME_RUN=/usr/local/bin/run, matching the CLI interface (-m <model> -p <prompt>) MakeMe's main.go expects from its runner.
BACKEND value |
What it does | Notes |
|---|---|---|
auto (default) |
Resolves to vulkan, unless arch is arm64 with no further signal — see caveat below |
Set explicitly if unsure |
vulkan |
Generic Mesa Vulkan — works on most Linux GPUs with a DRI device | |
asahi |
Apple Silicon via the Asahi Vulkan (Honeykrisp) driver | Requires fedora:44 on aarch64; enables the Asahi COPR |
rocm |
AMD GPUs via ROCm/HIP | x86_64 only |
cuda |
NVIDIA GPUs | Not supported by this Dockerfile — the build refuses with a clear error, since CUDA needs an nvidia/cuda base image, not fedora:44. Build a separate image if you need this. |
cpu |
No GPU acceleration |
Caveat on auto: Docker's build sandbox has no access to host hardware, so BACKEND=auto inside the Dockerfile cannot actually detect Apple Silicon — it can only avoid guessing wrong by warning and falling back to vulkan. Real autodetection happens on the host, in arch.sh, before the build even starts. If you build manually with docker build instead of ./run.sh, you lose that detection and must pass --build-arg BACKEND=... yourself.
There are two separate files that happen to share a name, used at two different times:
-
Build-time
env.conf, placed next to theDockerfilebefore building — read by the vendoredbuild_llama.shfor anything you want to override in thellama.cppbuild (e.g.GPU_TARGETSfor ROCm). -
Runtime
env.conf, placed inside your mounted MakeMe directory (/home/biasio/Documents/MakeMe/env.conf) — sourced byentrypoint.shon every container start, for things like:MAKEME_RUN=/usr/local/bin/run OPENAI_API_KEY=...
Neither file is required — MakeMe and the entrypoint both work fine without one.
run.sh picks the right docker run flags based on the detected backend:
- NVIDIA:
--gpus all(requires the NVIDIA Container Toolkit on the host) - ROCm:
--device /dev/kfd --device /dev/dri --group-add video - Vulkan / Asahi:
--device /dev/dri --group-add video - CPU: no device flags
The build is two-stage:
builder— Fedora, Go, Rust, cmake/gcc, thellama.cppbuild tree, and the MakeMe source checkout. This stage is large (multiple GB) but never ships.runtime— a freshfedora:44layer with only the four compiled binaries (makeme,stl2obj,t3d,run) and their actual runtime dependencies:-
OpenSCAD — required by MakeMe itself to render SCAD to STL; not needed at build time, so it now lives only in
runtime. -
ca-certificates— needed for MakeMe's own HTTPS model download on first launch. -
Backend-specific shared libraries, mirrored from ramalama's own
dnf_install_runtime_deps()(the same script this repo vendors for the build), minus its build/debug-only extras (vulkan-tools,gdb,strace) thatllama-clidoesn't need to run:BACKENDRuntime packages added vulkan(auto)mesa-vulkan-drivers,vulkan-loaderasahiasahi-repos,mesa-vulkan-drivers,vulkan-loaderrocmhipblas,rocblas,rocm-hip,rocm-runtime,rocsolvercpunone
-
None of git, cmake, gcc/gcc-c++, make, the Go toolchain, the Rust toolchain, or the llama.cpp/MakeMe source trees are present in the final image — they only exist in the discarded builder stage.
- No CUDA support in this Dockerfile. See the
cudarow above. env.conffor OpenSCAD nightly is not available on Fedora — there's no Fedora equivalent to the Ubuntu OpenSCAD nightly PPA, so this build uses Fedora's stable OpenSCAD package.llama-clibinary name. The vendoredbuild_llama.shpins a specific upstreamllama.cppcommit; if that pin moves and the built binary name changes fromllama-cli, the finalinstallstep in the Dockerfile will need updating accordingly.
run.sh only builds when the image tag for the detected backend doesn't already exist. To force a rebuild after changing the Dockerfile, env.conf, or switching backends:
docker rmi makeme:<backend>
./run.shThis repo wouldn't be possible without:
This project is licensed under the MIT License - see the LICENSE file for details.