{"id":43922734,"url":"https://github.com/frak-id/atelier","last_synced_at":"2026-05-06T00:03:43.779Z","repository":{"id":336865874,"uuid":"1135008133","full_name":"frak-id/atelier","owner":"frak-id","description":"Self-hosted kata container sandboxes — instant dev environments with opencode, VS Code, AI agents, and browser, accessible from anywhere.","archived":false,"fork":false,"pushed_at":"2026-05-05T00:30:07.000Z","size":8023,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T01:26:22.866Z","etag":null,"topics":["code-server","dev-env","devtools","infrastructure","microvm","opencode","remote-development","sandbox","self-hosted"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/frak-id.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-15T14:11:57.000Z","updated_at":"2026-05-05T01:08:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/frak-id/atelier","commit_stats":null,"previous_names":["frak-id/atelier"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/frak-id/atelier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frak-id%2Fatelier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frak-id%2Fatelier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frak-id%2Fatelier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frak-id%2Fatelier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frak-id","download_url":"https://codeload.github.com/frak-id/atelier/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frak-id%2Fatelier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32672685,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-server","dev-env","devtools","infrastructure","microvm","opencode","remote-development","sandbox","self-hosted"],"created_at":"2026-02-06T22:35:21.362Z","updated_at":"2026-05-06T00:03:43.768Z","avatar_url":"https://github.com/frak-id.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Atelier\n\nIsolated dev environments that boot in seconds, not minutes.\n\n**Self-hosted Kata Containers sandboxes with K8s orchestration.**\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)\n\n![demo](https://raw.githubusercontent.com/frak-id/atelier/main/docs/assets/demo.gif)\n\n## Batteries Included\n\nEach sandbox is a complete development environment — VS Code, AI agent, and browser, accessible from any device.\n\n- **[code-server](https://github.com/coder/code-server)** — VS Code in the browser, zero local setup\n- **[OpenCode](https://github.com/anomalyco/opencode)** — AI coding agent, launch tasks and review results from anywhere\n- **Chromium via [KasmVNC](https://kasmweb.com/kasmvnc)** — full browser inside your sandbox for previewing, testing, debugging\n- **[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** — multi-provider AI model proxy (Claude, Gemini, Codex) with management UI\n- **[Verdaccio](https://github.com/verdaccio/verdaccio)** — private npm registry shared across all sandboxes\n\nSpawn a sandbox, push a task to OpenCode, close your laptop.\nReview the results from your phone on the ski lift — or wherever you happen to be.\n\n## Features\n\n- **Task dispatch** — create coding tasks from the dashboard or Slack. Atelier spawns a sandbox, creates a git branch, launches OpenCode with your prompt, and tracks progress. An AI task queue for your team\n- **Session templates** — 4 built-in AI workflows (Implementation, Best Practices Review, Security Review, Simplification) with customizable models, effort levels, and prompt templates per workspace\n- **Dashboard** — mission control for all your sandboxes: real-time task progress, running dev servers, and an attention feed aggregating OpenCode permission and question requests across every session\n- **Prebuilds** — run expensive setup (git clone, dependency install, build) once and snapshot it. Subsequent sandboxes clone from the snapshot instantly via copy-on-write\n- **Dev commands with auto HTTPS** — define dev commands in your workspace config (e.g. `npm run dev` on port 3000) and get a public `https://dev-{name}-{id}.your-domain.com` URL with streaming logs\n- **Two base images out of the box** — `dev-base` ships with Node 22 and Bun; `dev-cloud` extends it with AWS CLI, Google Cloud SDK, kubectl, and Pulumi\n- **Base image builds from dashboard** — build and publish base images via Kaniko directly from the UI, no local Docker needed\n- **Workspace definitions** — configure git repos to clone, init commands, dev commands, exposed ports, secrets, and resource limits per workspace\n- **OpenCode config replication** — define OpenCode configuration globally or per workspace, automatically replicated to every sandbox\n- **Auth synchronization** — OAuth tokens are synced across all running sandboxes so you authenticate once and every instance just works\n- **Package cache** — [Verdaccio](https://github.com/verdaccio/verdaccio) runs as a shared npm registry, caching packages for npm, bun, pnpm, and yarn across all sandboxes\n- **SSH access** — use your regular workflow: SSH, VS Code Remote SSH, JetBrains remote. [sshpiper](https://github.com/tg123/sshpiper) provides username-based routing so `ssh sandbox-{id}@host -p 2222` just works\n- **MCP server** — AI agents can orchestrate sandboxes, tasks, workspaces, and dev commands programmatically via the Model Context Protocol\n- **Slack integration** — dispatch tasks and receive attention alerts (permission requests, agent questions) directly in Slack\n- **GitHub App integration** — connect your GitHub account for repository discovery and branch listing\n- **Multi-dev per sandbox** — nothing stops multiple developers from working in the same sandbox simultaneously\n- **Config file sync** — manage global and per-workspace config files, automatically synced to sandboxes\n\n## Why Atelier?\n\nAtelier runs isolated development sandboxes on Kubernetes with Kata Containers.\n\n- **VM isolation** — each sandbox is a real virtual machine, not a container namespace\n- **Instant cloning** — CSI VolumeSnapshots via TopoLVM clone a full environment in under a second via copy-on-write\n- **Prebuilds** — run expensive setup once, snapshot the filesystem, spawn instantly from there\n- **Simple operations** — Kubernetes-native workflows with Helm deployment\n\n## Requirements\n\n### Hardware\n\n- x86_64 CPU with virtualization enabled\n- Bare-metal server with KVM (`/dev/kvm` present)\n- apt-based Linux distro (Debian, Ubuntu) with systemd\n\n### Software\n\n| Dependency | Purpose |\n|------------|---------|\n| **[k3s](https://k3s.io)** | Lightweight Kubernetes distribution |\n| **[Helm](https://helm.sh)** | Chart-based deployment |\n| **[cert-manager](https://cert-manager.io)** | Automated TLS certificates |\n| **[kata-deploy](https://github.com/kata-containers/kata-containers)** | Kata Containers runtime (Cloud Hypervisor) |\n| **Docker** | Building manager and agent images |\n| **TopoLVM** *(optional)* | CSI driver for PVC snapshots — required for prebuilds |\n\n### Networking\n\n- A domain with wildcard DNS (`*.your-domain.com` → server IP)\n- Ports `80` and `443` open for HTTPS\n- Port `2222` open for SSH proxy access\n\n## Quickstart\n\n### 1. Install prerequisites on your server\n\n```bash\n# k3s\ncurl -sfL https://get.k3s.io | sh -\n\n# Helm\ncurl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash\n\n# cert-manager\nhelm repo add jetstack https://charts.jetstack.io\nhelm install cert-manager jetstack/cert-manager \\\n  --namespace cert-manager --create-namespace --set crds.enabled=true\n\n# Kata Containers\ngit clone --depth 1 https://github.com/kata-containers/kata-containers.git /tmp/kata-src\nhelm install kata-deploy /tmp/kata-src/tools/packaging/kata-deploy/helm-chart/kata-deploy \\\n  --set k8sDistribution=k3s \\\n  --set env.createRuntimeClasses=true \\\n  --set env.createDefaultRuntimeClass=true\n```\n\n### 2. Create a values file\n\n```yaml\n# values.production.yaml\ndomain:\n  baseDomain: \"example.com\"\n  tls:\n    email: \"admin@example.com\"\n\nauth:\n  github:\n    clientId: \"your-github-client-id\"\n    clientSecret: \"your-github-client-secret\"\n  allowedOrg: \"your-github-org\"  # optional\n\ncertManager:\n  enabled: true\n  cloudflare:\n    apiToken: \"your-cloudflare-api-token\"\n```\n\nSet the Authorization callback URL in your GitHub OAuth App to `https://sandbox.example.com/auth/callback`.\n\n### 3. Deploy with Helm\n\n```bash\nhelm install atelier charts/atelier/ \\\n  --namespace atelier-system --create-namespace \\\n  --values values.production.yaml\n```\n\nOr use the deploy script (builds images, pushes to GHCR, deploys via SSH):\n\n```bash\nVALUES_FILE=./values.production.yaml ./scripts/deploy-k8s.sh\n```\n\n### 4. Verify\n\n```bash\nkubectl -n atelier-system get pods\nkubectl -n atelier-system logs -f deploy/atelier-manager -c manager\n```\n\nYour dashboard is at `https://sandbox.example.com`.\n\n## Helm Chart Overview\n\nThe chart deploys these components into your cluster:\n\n| Component | Purpose |\n|-----------|---------|\n| **Manager** | Sandbox orchestration API (ElysiaJS/Bun) |\n| **Dashboard** | Admin web interface (React SPA via nginx sidecar) |\n| **Zot** | Lightweight OCI registry for base images |\n| **Verdaccio** | npm package cache shared across sandboxes |\n| **CLIProxyAPI** | AI model proxy with multi-provider OAuth |\n| **sshpiper** | SSH proxy with username-based routing to sandboxes |\n| **Shared binaries** | Job that downloads code-server + OpenCode into a shared PVC |\n\nSandbox pods are created dynamically in the `atelier-sandboxes` namespace with the `kata-clh` runtime class.\n\n### Key configuration\n\n```yaml\n# Domain \u0026 TLS\ndomain:\n  baseDomain: \"\"           # REQUIRED — e.g. \"example.com\"\n  dashboard: \"\"            # defaults to \"sandbox.{baseDomain}\"\n\n# Authentication (required for production)\nauth:\n  github:\n    clientId: \"\"\n    clientSecret: \"\"\n  jwtSecret: \"\"            # auto-generated if empty\n  allowedOrg: \"\"           # restrict to a GitHub org\n  allowedUsers: []         # or specific usernames\n\n# Server\nserver:\n  port: 4000\n  maxSandboxes: 20\n  maxActiveTasks: 10\n  mcpToken: \"\"             # bearer token for MCP server auth\n\n# Kubernetes\nkubernetes:\n  namespace: atelier-sandboxes\n  runtimeClass: kata-clh\n  storageClass: \"\"         # cluster default\n  volumeSnapshotClass: \"\"  # for prebuilds\n  defaultVolumeSize: \"10Gi\"\n\n# Integrations\nintegrations:\n  slack:\n    enabled: false\n    botToken: \"\"\n    signingSecret: \"\"\n\n# Sub-components (each can be disabled)\nzot:\n  enabled: true\n  persistence:\n    size: 20Gi\n\nverdaccio:\n  enabled: true\n  persistence:\n    size: 10Gi\n\ncliproxy:\n  enabled: true\n\nsshpiper:\n  enabled: true\n  nodePort: 30022          # external SSH port\n\ncertManager:\n  enabled: true\n```\n\nSee [`charts/atelier/values.yaml`](charts/atelier/values.yaml) for all options.\n\n## Local Development\n\nNo server or KVM needed — the manager runs in mock mode:\n\n```bash\nbun install\nATELIER_SERVER_MODE=mock bun run dev\n# API:       http://localhost:4000\n# Swagger:   http://localhost:4000/swagger\n# Dashboard: http://localhost:5173\n```\n\n## Documentation\n\n- [Setup Guide](docs/setup.md) — installation and configuration\n- [Architecture](docs/architecture.md) — system design, components, and diagrams\n- [Infrastructure](docs/infrastructure.md) — networking, storage, domains, and deployment\n- [Constraints](docs/constraints.md) — critical gotchas that will save you hours\n- [Code Patterns](docs/patterns.md) — conventions for contributors\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.\n\n## Security\n\nSee [SECURITY.md](SECURITY.md) for vulnerability reporting.\n\n## License\n\n[MIT](LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrak-id%2Fatelier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrak-id%2Fatelier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrak-id%2Fatelier/lists"}