Get started
A single installer stands up the whole stack, either as a self-contained appliance or onto a Kubernetes cluster you already run. This page covers what you provide, the two install modes, configuring a Git target, the deployment flow, supported runtimes, and the technical detail behind it.
Before you start
The installer stands up Portainer Business, Portainer-Run, and the Kubernetes components a governed deployment target needs, so the list of things you provide is short.
The storage class, the authenticating ingress controller, the centralized user directory, the network security policies, and the namespaces and quotas are stood up by the installer, so they are not prerequisites you configure by hand.
Step 1
An IT administrator runs a single terminal installer on the target host. It fetches and runs a bootstrap script, then walks the rest interactively, standing up the full stack and the Kubernetes components a governed deployment target needs, so there is no manual assembly of ingress, identity, storage, and policy.
curl -sfL https://get.portainer-run.portainer.ai/get.sh | sudo sh -
The installer then asks which of the two modes below to use. The full reference is in the documentation.
The installer turns a single virtual machine into a self-contained appliance for hosting vibe-coded apps. It installs KubeSolo, Portainer Business, and Portainer-Run, and deploys the required Kubernetes components: an authenticating ingress controller, a centralized user directory, a storage class, network security policies, and the namespaces and quotas.
The installer targets a Kubernetes cluster you already operate. It installs Portainer Business and Portainer-Run, and deploys the same components: an authenticating ingress controller, a centralized user directory, a storage class, network security policies, and the namespaces and quotas. The isolation model is identical to the appliance.
Step 2
Portainer-Run has no user database and no login of its own. Access is your Portainer RBAC, and a browser user rides their existing Portainer session; there is no separate token to paste.
Users switch into Run from the product switcher in Portainer, or browse to it through the Portainer host. The environments and namespaces someone can see and act on are exactly what their Portainer role grants. Administrators additionally see Cluster Readiness and environment enable and disable controls. A personal access token is only needed for non-browser clients, which is the MCP path in Step 5.
Step 3
A Git target is an encrypted, stored connection to the repository Portainer-Run commits to. It is the system of record for every deployment.
Under Git Targets, add the provider (GitHub, GitLab, Gitea, or other), the repository in owner/repo form, a personal access token, a default branch, and an optional path prefix. Credentials are encrypted at rest (AES-256-GCM). The Test button reports read and write access separately; a read-only token will fail at the commit step.
repo scope.Step 4
Drop the files an AI tool produced. No Dockerfile, no image, no CI. Portainer-Run detects the runtime, installs dependencies, commits to Git, and lets Portainer deploy it.
Upload the folder of files directly, or point Portainer-Run at an existing repository with a target, branch, and optional subfolder.
Pick the environment, namespace, and Git target from the options your token can reach, and the exposure type. If a .env.example is present, its keys appear as an editable environment-variable list, with secret-looking keys masked.
Portainer-Run commits and triggers the deployment. When it is live, the running status and access address (IP:port or FQDN) surface back to you.
Optional
An AI coding tool such as Claude can deploy without opening Portainer-Run at all. Run exposes an MCP endpoint through the same authenticated Portainer gateway, and the same governed Git and GitOps pipeline runs underneath, scoped by the caller's Portainer RBAC.
Node.js must be installed on the developer's machine, since the connection runs through npx.
In Claude Desktop, go to File, then Settings, then Developer, then Edit Config.
Add the block below, pointing it at your Portainer-Run MCP endpoint and using a Portainer personal access token as the Bearer token. Your RBAC applies exactly as it does in the UI.
The Portainer-Run tools become available. Ask Claude to deploy an app and it runs through the same pipeline as the UI: committed to Git, deployed as a GitOps stack, governed by your rules.
"mcpServers": {
"portainer-run": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"https://<portainer-host>/addons/portainer-run/mcp",
"--header",
"X-API-Key: <your-portainer-access-token>"
]
}
}
/addons/portainer-run/mcp. The gateway authenticates and authorizes the request the same way as the UI before forwarding it to the add-on.X-API-Key. The same RBAC applies as in the UI.npx is not found, set command to its full path, for example C:\\PROGRA~1\\nodejs\\npx.cmd.Under the hood
Everything is committed to Git and reconciled by Portainer, so each deployment is governed and fully repeatable.
Portainer-Run inspects the file structure and matches a runtime in priority order, first match wins. A package.json means Node.js, requirements.txt or .py means Python, .php means PHP, a Gemfile or .rb means Ruby. If everything is static assets it defaults to nginx.
Portainer-Run generates a Kubernetes Deployment manifest for the detected runtime, with three init containers that run in sequence before the app starts:
npm install --production, pip install -r requirements.txt, bundle install, or composer install) inside the runtime image so native modules build correctly..env file from the values entered at deploy time. These values are never committed to Git.Once the init containers complete, the main container starts against the pre-populated volume using a stock public runtime image. Git credentials are held in a Kubernetes Secret and injected by reference, so the token never appears in the pod spec.
Source files are committed to {environment}/{namespace}/{app}/src/ and the manifest to {environment}/{namespace}/{app}.yaml, keeping environments and namespaces cleanly separated in one repo. Portainer-Run then calls the Portainer API to create a GitOps stack pointed at that manifest. Portainer polls the repository on a set interval (five minutes by default) and applies any change.
An update takes the same path. Drop the revised files, Portainer-Run commits the change, and Portainer reconciles it on the next poll. The PersistentVolume keeps its state across restarts, so uploaded files and anything the app wrote to disk survive the update.
Reference
Detection is automatic and runs in priority order. If nothing matches, Portainer-Run falls back to nginx.
Runs on node:22. Start command from the start script, else node server.js / index.js / npm start.
Runs on python:3.13-slim. Targets main.py, app.py, server.py, or run.py, else python app.py.
Served with Apache on php:8.4-apache.
Runs on ruby:3.4-slim. Rack apps use bundle exec rackup, else app.rb or server.rb.
HTML, CSS, JS, images, and so on, on nginxinc/nginx-unprivileged:alpine running as UID 101. A single non-index.html file is renamed on commit.
Know before you go
Reference
Configuration is collected by the installer and held by Portainer, rather than hand-set as container environment variables. The values that matter are the optional AI provider key (Anthropic or OpenAI) that enables the Assistant, the base domain used to build app URLs, and the Git targets you add in the UI.
An administrator changes the AI keys and base domain later from the Settings page inside Portainer-Run, over their own session, and the change takes effect without a restart. The full configuration reference is in the documentation.
Go deeper
The documentation has the complete reference: the deployment form, the application catalogue and template format, the Assistant, the aggregated status architecture, and configuration.