# Loco docs > Deploy and operate applications on Kubernetes with Loco. Go infrastructure documentation describes the unreleased Go authoring workflow. Check the release notice before using those commands. # Overview # Deploy with Loco Loco builds, deploys, and scales containerized applications on Kubernetes. Use the CLI to work with your applications and the dashboard to inspect their state. From your terminal. Onto Kubernetes. Loco handles application orchestration across regions, with HTTPS routing, resource controls, and observability. [Install the CLI]() [Choose a deployment mode]() ## Where to start | Your task | Read | | --- | --- | | Connect to a Loco instance | [Install]() and [connect]() | | Choose who operates the platform | [Multi-tenant SaaS, dedicated, and self-hosted]() | | Define infrastructure in Go | [Go infrastructure]() | | Inspect running applications | [Application operations]() | | Run Loco yourself | [Self-hosting]() | | Contribute to the platform | [Local development]() | ## One platform, three deployment modes Loco's deployment model covers multi-tenant SaaS, dedicated, and self-hosted installations. The [deployment modes]() guide separates platform operation from application deployment and records current availability. ## Documentation and releases The Go infrastructure pages describe the unreleased authoring workflow under review in the [infrastructure stack](). Check the notice on those pages before running their commands. The installation and operations pages use commands available on the main branch. For AI tools, use [Markdown exports and the documentation index](). # Get started # Connect to Loco A CLI session belongs to a Loco API host. Sign in to the instance that operates your applications: ``` loco login ``` The default API host is `https://api.loco.build`; the default dashboard is `https://loco.build`. Follow the sign-in instructions printed by the installed CLI. ## Staging ``` loco login --host https://api.staging.loco.build loco config set webHost https://staging.loco.build loco web ``` The CLI saves the host used for login. Later commands use that host. Sign in again when switching instances; a staging session does not sign you into production. ## Dedicated and self-hosted instances Use `loco login --host` with the API URL supplied by the instance operator, and set `webHost` to that instance's dashboard URL. [Deployment modes]() explains who operates each instance. ## Return to production ``` loco login --host https://api.loco.build loco config set webHost https://loco.build ``` For commands supported by your installed release, run `loco help`. The [Go infrastructure workflow]() requires a CLI release containing the infrastructure cutover. # Install the CLI The Loco CLI deploys and manages applications from your terminal. Install the released binary for Linux or macOS on amd64 or arm64: ``` curl -fsSL https://loco.build/install.sh | sh ``` The installer verifies the release checksum and places the binary in `~/.local/bin`. Add that directory to your shell's `PATH` if the installer reports it is missing. ``` loco version loco help ``` ## Select a release Set `LOCO_VERSION` to an existing release tag to install a specific version. Set `LOCO_INSTALL_DIR` or pass `--bin-dir` to change the destination. See the [published releases]() for available versions. ``` loco update ``` `loco update` replaces the installed binary with the latest release. ## Shell completions ``` loco completion zsh loco completion bash ``` Save the output using your shell's completion installation instructions. Continue with [connecting to Loco](). # Deployment # Environments An environment separates an application's staging and production targets. Select the API instance first, then the workspace and environment within that instance. ## Loco's hosted endpoints | Surface | Production | Staging | | --- | --- | --- | | Dashboard | `https://loco.build` | `https://staging.loco.build` | | API | `https://api.loco.build` | `https://api.staging.loco.build` | | Documentation (canonical) | `https://docs.loco.build` | `https://docs.staging.loco.build` | | Documentation on the dashboard | `https://loco.build/docs/` | `https://staging.loco.build/docs/` | The staging docs display a banner and tell search engines not to index them. These endpoints describe Loco's own hosted services; self-hosted installations choose their own domains. ## Application environments in Go definitions > [!WARNING] > > **Unreleased workflow** > > Workspace and environment selection here follows the [Go infrastructure cutover](), which requires a CLI release containing that workflow. ``` loco infra context --workspace WORKSPACE_ID --environment ENVIRONMENT_ID ``` A definition receives the workspace name, environment name, and environment type (`dev`, `staging`, or `production`). Use that context to choose capacity and domains. Staging and production can share service keys while keeping separate resources and deployment history. Explicit `--workspace` and `--environment` flags override environment variables and a saved link. Prefer IDs for restricted CI credentials. ## Promote the dashboard and documentation The UI image includes its documentation build. Repository merges build production and staging UI images for the same commit. The existing staging workflow deploys that commit automatically. The production workflow promotes the selected commit's production UI image, including the docs, after staging verification. See [documentation maintenance](). # Go infrastructure A Go infrastructure definition describes an application stack in a standalone `.loco/` module. Loco evaluates the definition locally and sends declarative data to the API. > [!WARNING] > > **Unreleased workflow** > > This page describes the Go infrastructure cutover under review in [PR \#316](). It requires a released CLI containing those commands and published Go SDK dependencies. Check `loco infra --help` before using this workflow. ## Create a definition ``` loco init cd .loco go mod tidy ``` The Go workflow writes `.loco/main.go` and `.loco/go.mod`. Commit the definition, `go.mod`, and `go.sum`. Definitions compile with `-mod=readonly`. The SDK entrypoint is `loco.Run`, imported from `github.com/team-loco/loco/sdk/go`. A stack contains services with stable keys. Each service declares one Docker build or image source, resource settings, and environment variables. Omit a hostname to keep a service private. See the [source definition and SDK example]() for the exact authoring API under review. ## Select a target ``` loco infra link --workspace WORKSPACE_ID --environment ENVIRONMENT_ID --stack storefront loco infra context --workspace WORKSPACE_ID --environment ENVIRONMENT_ID ``` `infra link` saves a local default in `.loco/link.json`; ignore that file in Git. Explicit flags and `LOCO_WORKSPACE` / `LOCO_ENVIRONMENT` override the link. An environment is required. ## Validate, plan, and apply ``` loco validate --workspace my-team --environment staging --environment-type staging --json loco deploy --workspace my-team --environment staging --plan-only --out release.json loco infra apply --plan release.json --yes --wait ``` `validate` runs offline. `deploy --plan-only` builds and publishes images, then saves a plan covering infrastructure and releases. Review the plan before applying it. `infra apply` uses the saved plan; it does not reevaluate the definition or rebuild images. A full-stack apply removes services absent from the owned stack. Deletions require admin permission and `--confirm-destructive`. Applying desired state and rolling out Kubernetes workloads are separate steps; a failed rollout does not undo committed desired state. ## Variables and secrets Use `loco.Literal` for declared values, `loco.SecretRef` for named secrets, and `loco.Preserve` to retain an existing value. Preserve cannot initialize a new environment. ``` printf '%s' "$DATABASE_URL" | loco secret set database-url --workspace WORKSPACE_ID --environment ENVIRONMENT_ID ``` Stack definitions own their declared variable maps. Dashboard edits create drift for the next plan. Supply secrets separately for each environment. # Deployment modes A deployment mode determines who operates Loco and whether the platform serves one customer or multiple customers. Application environments such as staging and production exist within that platform. Loco's product direction includes three modes. Dedicated provisioning and a packaged self-hosting release are not documented as generally available in this repository. Confirm availability with the project maintainers before selecting a managed installation. | Mode | Platform operator | Platform tenancy | Application operator | | --- | --- | --- | --- | | Multi-tenant SaaS | Loco | Multiple customers share the platform | Your team | | Dedicated | Loco | A platform installation for one customer | Your team | | Self-hosted | Your team | Your team controls the installation and tenancy | Your team | ## Multi-tenant SaaS Connect to Loco's managed API and dashboard. Your team works with organizations, workspaces, and applications. Loco operates the platform's control plane and Kubernetes infrastructure. ``` loco login loco web ``` See [architecture]() for how the control plane and regional components fit together. ## Dedicated A dedicated installation gives one customer a Loco-operated platform. Use the installation's API and dashboard URLs. Instance provisioning, capacity, and operational responsibilities need an agreement with the operator; these docs do not define pricing or service guarantees. ## Self-hosted Your team operates the control plane, Kubernetes clusters, networking, certificates, registry, database, and observability. Your team also owns upgrades, backups, capacity, and incident response. Start with the [self-hosting guide](). The repository contains Helm charts, environment configuration, and a local development setup; it does not provide a complete production installation command. ## Environments within a mode Staging and production are application targets, independent of deployment mode. A dedicated or self-hosted installation can also have staging and production environments. Keep each instance's credentials and endpoints separate. See [environments](). # Operations # Application operations The CLI reads application status and manages application resources through the selected Loco API. Check command help for the arguments supported by your release: ``` loco resource --help loco resource status --help loco resource logs --help loco resource events --help ``` `loco resource` also includes `env`, `scale`, and `destroy`. Inspect an operation's help before changing resources or removing an application. ## Container requirements Applications run under Kubernetes' `restricted` Pod Security profile. Images must run as a numeric non-root user, such as `USER 10001`, and use an unprivileged application port. Configure the routing port to match the port the application listens on. ## Investigate a rollout Use application status to find whether a deployment is progressing or ready. Read events for scheduling and reconciliation failures, then inspect logs for application startup failures. The dashboard provides another view of the same applications. ``` loco web ``` For deployment authoring, see [Go infrastructure]() and its release notice. # Self-hosting A self-hosted Loco installation puts platform operation under your team's control. The repository contains the platform components and Helm charts; production operation requires instance-specific configuration. Start by running the [local development environment]() to exercise the components together: ``` mise run setup mise run tilt ``` The local environment is a development installation. Review the repository's environment configuration before adapting it to a production cluster. ## Platform components | Component | Repository location | Responsibility | | --- | --- | --- | | API | `api/` | ConnectRPC services and PostgreSQL state | | Dashboard | `web/` | Browser access to the API | | Regional agent | `agent/` | Connect the region to the control plane | | Application controller | `controller/` | Reconcile Application custom resources | | Custom resource definitions | `k8sapi/` | Kubernetes API types | | Platform charts | `charts/` | Kubernetes platform configuration | | Regional observability proxy | `observability-proxy/` | Access to regional observability | ## Installation inputs Configure the API's database, cache, authentication, registry, and API/dashboard endpoints using the repository's [environment template](). Check the template and deployed release together; authentication and registry changes are under active review. The cluster needs Cilium, Envoy Gateway, cert-manager, and the Loco controller. Observability uses OpenTelemetry, ClickHouse, and Grafana. The charts and environment values define their configuration. Your team supplies DNS records, certificate issuance, persistent storage, backups, and capacity. Keep credentials separate across installations and environments. Use [architecture]() to identify the control-plane and regional boundaries. ## Upgrades Use images and charts from a consistent release. Regenerate CRDs through `mise run controller:gen` when developing schema changes. Review database migrations and infrastructure changes before upgrading a running installation. A supported production packaging and upgrade procedure is not established by these docs. Inspect the chart values and the release's configuration before deployment. # Reference # Use with AI Loco's documentation includes Markdown exports for AI assistants and tools that ingest text. The exports come from the same pages as the rendered documentation. ``` curl -fsSL https://docs.loco.build/llms.txt curl -fsSL https://docs.loco.build/llms-full.txt ``` ## Choose an export | Export | Use | | --- | --- | | [`llms.txt`]() | Find pages by section and follow their Markdown links | | [`llms-full.txt`]() | Load the complete published documentation as text | | Copy as Markdown | Copy the current page into an assistant | Use the page action beside the title to copy Markdown. Page-specific Markdown URLs appear in `llms.txt`. ## Match the release Ask the assistant to check release notices and the installed CLI's help before generating commands. Go infrastructure documentation describes an unreleased workflow; Markdown exports retain those notices. These helpers use [Zensical's native `llmstxt` support](). They do not require an AI account or an API key. Copying a page uses your browser's clipboard; these docs do not send it to an AI provider. # Architecture Loco separates its control plane from the regional components that run applications. The CLI and dashboard call the API, and the regional agent connects the cluster to the control plane. ## Control plane The Go API exposes ConnectRPC services and stores platform state in PostgreSQL. The CLI uses Cobra and Charm libraries; the dashboard lives in `web/`. Protocol definitions live in `proto/`, with generated clients in `gen/`. ## Regional runtime The in-cluster agent exchanges state with the API. The controller reconciles Application custom resources into Kubernetes workloads and routing resources. Cilium provides networking; Envoy Gateway handles ingress and TLS termination; cert-manager provisions certificates. ## Observability OpenTelemetry collects telemetry, ClickHouse stores observability data, and Grafana displays it. The regional observability proxy provides access to the regional data. ## Deployment boundaries [Deployment modes]() determine the operator and tenancy of the platform. Application workspaces, environments, and regions determine where a team's workloads run within the installation. For the protobuf service definitions and client generation, see [CLI and API reference](). # CLI and API Loco's command help and protobuf definitions are the reference for the installed release's interface. Use the CLI's own help to see current arguments and defaults: ``` loco help loco resource --help loco config --help ``` ## CLI commands | Command | Purpose | | --- | --- | | `loco login` | Sign in to a Loco instance | | `loco web` | Open the configured dashboard | | `loco resource` | Inspect and manage applications | | `loco config` | Manage local CLI settings | | `loco update` | Update the installed CLI | | `loco completion` | Generate shell completions | The [Go infrastructure]() page covers the unreleased `infra` workflow separately. ## API schema Browse [Loco on the Buf Schema Registry]() for service definitions and generated client options. The repository's `proto/` directory owns the schema. ``` mise run gen ``` That task regenerates Go and TypeScript clients and SQL query bindings. Do not hand-edit generated files. # Contributing # Local development The local environment runs Loco's control plane and cluster components for development. Install mise and Docker or OrbStack, then use the pinned repository tools: ``` mise run setup ``` Copy `.env.example` to `.env` and supply the credentials required by that revision. Tool versions live in `mise.toml` and `mise.lock`. ``` mise run tilt ``` Tilt starts the local cluster and services. The API listens at `http://localhost:8000`, and the dashboard at `http://localhost:5173`. ## Connect the CLI ``` mise run build ./bin/loco login --host http://localhost:8000 ./bin/loco config set webHost http://localhost:5173 ``` ## Tasks ``` mise tasks mise run test:cli mise run lint:go mise run docs:serve ``` Use the repository's tasks for builds, tests, code generation, and linting so local tools match CI. See [documentation maintenance]() to edit this site. # Documentation maintenance The documentation site is a Zensical project contained in `docs/`. Published Markdown lives in `docs/content/`; older notes and design documents outside that directory stay outside the site. ``` mise run docs:serve ``` The preview listens at `http://127.0.0.1:8001`. Zensical rebuilds when content changes. Restart the preview after changing the theme configuration. ## Edit and verify Add pages under `docs/content/` and register them in `docs/zensical.toml`. Keep page names and headings consistent with the CLI and API. Describe released behavior, and label unreleased workflows with a release notice. ``` mise run docs:build mise run docs:build:staging mise run test:docs uv run --frozen --project docs playwright install chromium mise run docs:check:browser mise run docs:check:container ``` Builds run in strict mode and fail on warnings. Generated output goes in `docs/site/` and stays out of Git. Python dependencies are pinned in `docs/uv.lock`; the runner and Python versions are pinned by mise. ## Theme and navigation `docs/content/assets/loco.css` owns the documentation tokens and theme. `docs/overrides/main.html` adds staging metadata and its banner. `docs/DESIGN.md` records the visual contract. The build copies the favicon from `web/public/favicon.svg` and generates the wordmark from `web/src/components/design/logo-strokes.ts`. The generated favicon and `docs/overrides/partials/logo.html` stay ignored; edit the web sources to update both surfaces. Desktop navigation remains visible as you scroll, with every section expanded. The table of contents also remains visible on wide screens. Narrow viewports use Zensical's navigation drawer. Do not enable navigation pruning, navigation tabs, header auto-hide, or page metadata that hides navigation. ## Hosting The `web/Dockerfile` image packages the dashboard and documentation together. One Static Web Server process serves the dashboard, docs at `/docs/`, and the docs hostname through a virtual host. The existing Railway `loco::cp-ui` service owns both domains; documentation adds no service or image publication job. Production serves `docs.loco.build` and `loco.build/docs/`. Staging serves `docs.staging.loco.build` and `staging.loco.build/docs/`. The docs hostname is canonical; links inside the rendered site are relative so navigation also works under `/docs/`. Main merges build production and staging UI images containing their matching docs builds. The staging workflow deploys automatically; the production workflow promotes the selected commit's UI image, including its docs. `web/sws.toml` defines static roots and dashboard route rewrites. Existing dashboard routes resolve to the UI entrypoint; missing documentation URLs return HTTP 404. Add a rewrite when introducing a new dashboard route prefix. The container tests check the routes declared in `web/src/App.tsx`. `docs/scripts/package.py` generates the server configuration with exact CSP hashes for Zensical's inline scripts. The dashboard keeps its existing script restrictions. Generated `.sws.toml` stays outside the public site and out of Git. Register each docs hostname on `loco::cp-ui` with `railway domain docs.loco.build --service loco::cp-ui --environment production --port 8080` and the staging equivalent, then add the CNAME and verification records Railway supplies. Railway configuration can manage registered domains but cannot create new custom domains. Railway must verify both custom domains and provision HTTPS before treating them as live. The `/docs/` path works through the existing dashboard domain without another DNS record. Inspect a [Railway configuration plan]() for each environment before merging infrastructure changes.