Single container image running tinycode (web mode) for deployment to OpenShift and Kubernetes. tinycode is a single Go binary — no Node.js, Bun, or separate plugin process required.
This project packages the tinycode binary as a self-contained container image suitable for multi-tenant Kubernetes/OpenShift environments. The container runs tinycode's web mode, exposing an HTTP API and embedded web UI on port 4096.
The container interface (port, UID, health endpoints, volume mounts, environment variables) is documented in CONTAINER.md, which is the authoritative contract between this image and the tinycode-operator that deploys it.
Note: A bare container can only chat with the model — it has no project files to work on. To make tinycode useful on a cluster, give it context: clone a git repo (
TINYCODE_GIT_REPO), enable cluster-admin mode (TINYCODE_CLUSTER_ADMIN=true), or mount a host path with existing code. See Environment Variables for the full list.
curl -fsSL https://raw.githubusercontent.com/bobbyjohnstx/tinycode-container/main/install.sh | shThis installs a tinycode wrapper script that:
- Pulls the container image if not present
- Starts a named container with persistent volumes on first run
- Attaches to the existing container on subsequent runs (sub-second startup)
- Detects
podmanvsdockerautomatically
To uninstall: tinycode --uninstall
- podman or docker (for running and local builds)
- kubectl or oc (for Kubernetes/OpenShift deployment)
The container image is built for both linux/amd64 and linux/arm64. CI produces a multi-arch manifest, so podman pull or docker pull selects the correct architecture automatically.
# Build for the current architecture
podman build -f ContainerFile \
-t quay.io/bjohns/tinycode-container:latest .
# Build for a specific architecture
podman build -f ContainerFile \
--platform linux/arm64 \
-t quay.io/bjohns/tinycode-container:latest .The build downloads the tinycode release binary for the target platform and installs it into a UBI9 runtime image with a non-root user (UID 1001, GID 0).
# Run the container in detached mode
podman run -d -p 4096:4096 quay.io/bjohns/tinycode-container:latest
# Open the web UI
open http://localhost:4096For persistent storage during local testing:
podman run -d -p 4096:4096 \
--name tinycode \
-v tinycode-data:/home/tinycode/.local/share/tinycode \
-v tinycode-config:/home/tinycode/.config/tinycode \
quay.io/bjohns/tinycode-container:latestSet the TINYCODE_SESSION_ID environment variable to attach to an existing session on container start:
podman run -d -p 4096:4096 \
-e TINYCODE_SESSION_ID=my-session \
quay.io/bjohns/tinycode-container:latest# Deploy base resources (Deployment, Service, Route)
kubectl apply -k k8s/baseEphemeral (no PVC — testing only):
kubectl apply -k k8s/overlays/ephemeralGeneric Kubernetes (Ingress instead of Route):
kubectl apply -k k8s/overlays/ingressFor production OpenShift deployments, consider using the tinycode-operator, which manages TinycodeInstance CRs and handles storage, routing, and SCCs automatically.
The tinycode web UI requires authentication. To set the password:
-
Copy the secret template:
cp k8s/secrets/secret-template.yaml k8s/secrets/secret.yaml
-
Edit
k8s/secrets/secret.yamland set your desired password (base64-encoded). -
Apply the secret:
kubectl apply -f k8s/secrets/secret.yaml
Base Image: Red Hat UBI9 (OpenShift-compatible)
Port: 4096 (HTTP)
User: UID 1001 (non-root), GID 0 (OpenShift arbitrary UID support via g=u)
Health Probes: GET /global/health (unauthenticated, liveness + readiness)
Persistence: PVC mounts for:
/home/tinycode/.local/share/tinycode(SQLite DB, session history)/home/tinycode/.config/tinycode(user configuration)/projects(user workspace files, separate PVC)
Configuration Hierarchy:
User customizations should go in tinycode.jsonc (PVC-persisted) to survive image upgrades.
Load order (lowest to highest priority): config.json → tinycode.json → tinycode.jsonc
XDG Base Directories:
| Variable | Value |
|---|---|
XDG_DATA_HOME |
/home/tinycode/.local/share |
XDG_CONFIG_HOME |
/home/tinycode/.config |
XDG_STATE_HOME |
/home/tinycode/.local/state |
XDG_CACHE_HOME |
/home/tinycode/.cache |
Environment Variables:
For the complete environment variable reference, see CONTAINER.md.
The GitHub Actions workflow (.github/workflows/build-push.yaml) automatically builds and pushes multi-arch images to quay.io/bjohns/tinycode-container on every push to main:
- Platforms:
linux/amd64,linux/arm64 - Tags:
:latestand:<git-sha> - Smoke test: Runs
tinycode --versionon both architectures - Registries: Quay.io (primary), GitHub Container Registry (mirror)
- GitOps Mode: Clone a git repository on container startup via
TINYCODE_GIT_REPO, with optional auto-pull on restart - vLLM Auto-Configuration: Set
TINYCODE_VLLM_URLto auto-configure vLLM endpoint and model - RHOAI/OpenShift Auto-Detection: Automatically detects Kubernetes environment
- Cluster-Admin Mode: Enable
TINYCODE_CLUSTER_ADMIN=trueto download oc CLI and access cluster management capabilities - Swarm Tool:
/swarmdispatches parallel agents as goroutines (no tmux needed — Go's native concurrency) - Input Validation:
TINYCODE_VLLM_MODELis validated to prevent shell injection (alphanumeric,/,-,.only) - Read-Only Root: Container filesystem can be mounted read-only for additional security
- Security Headers: Server includes standard security headers (CSP, X-Frame-Options, X-Content-Type-Options, etc.)
- Health probes can use tcpSocket instead of
GET /global/healthif the health endpoint requires authentication in your deployment (seek8s/base/deployment.yamlcomments).
| Project | Description |
|---|---|
| tinycode | Core binary — server, TUI, web UI, 23 agents, 32 plugins, 7 skills |
| tinycode-container | This repo — OCI container image |
| tinycode-operator | Kubernetes Operator for OpenShift |
| homebrew-tap | Homebrew formula for macOS/Linux |
MIT — see LICENSE.