> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instapods.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 1-Click Apps

> Deploy ready-to-run self-hosted apps like n8n, AutoMem, and Vaultwarden in seconds, then configure them with environment variables.

1-Click Apps are popular open-source applications pre-packaged for InstaPods. Instead of writing code, you pick an app from the catalog and deploy it - the app is baked into a ready-to-run image, so it boots in seconds with sensible defaults and per-pod credentials already generated.

<Note>
  1-Click Apps run as a managed service inside your pod (their own systemd units), not from `/home/instapod/app`. You still get a Web Terminal, SSH, custom domains, and backups like any other pod.
</Note>

## Deploying an app

<Tabs>
  <Tab title="Dashboard">
    1. Click **Create Pod** and choose the **1-Click App** tab.
    2. Pick an app (n8n, AutoMem, Vaultwarden, Uptime Kuma, and more).
    3. Choose a plan. Each app has a minimum plan based on the resources it needs - the wizard preselects it for you.
    4. Fill in any optional setup fields the app exposes (for example, an API key), then click **Deploy**.

    When the pod is ready, the dashboard shows a **setup card** with the app URL and any generated credentials.
  </Tab>

  <Tab title="API">
    Pass `app_type` (and optional `app_config` for the app's setup variables) when creating a pod:

    ```bash theme={null}
    curl -X POST https://app.instapods.com/api/pods \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "my-memory",
        "plan_slug": "grow",
        "app_type": "automem",
        "app_config": {
          "EMBEDDING_PROVIDER": "openai",
          "OPENAI_API_KEY": "sk-your-key"
        }
      }'
    ```

    The keys allowed in `app_config` are the app's setup variables (see the app's deploy form for the list).
  </Tab>
</Tabs>

<Warning>
  Each app declares a **minimum plan**. If you pick a plan below it, the deploy is rejected - choose at least the app's minimum (for example, AutoMem requires **Grow**).
</Warning>

Apps also declare which presets they can run on. Pairing one with a preset it doesn't support is
refused up front with a `400` naming the presets it does run on, rather than creating a pod that
would serve a 502 forever. You can leave the preset out entirely and the app's own is used.

## Where the app's login is

Apps that generate their own credentials at first boot show them on the pod page, under **App
credentials** - the username, the password or admin token, and any setup notes the app ships with,
with your pod's URL filled in.

They're also emailed to you when the pod is ready, but the panel is the copy that can't be lost: it
reads from what was captured at install time, so it still works when the pod is stopped, and a
deleted or spam-filtered email is no longer a lockout.

```bash theme={null}
curl https://app.instapods.com/api/pods/my-app/apps/vaultwarden/credentials \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<Note>
  Only the pod's owner can read them. Apps that generate no credentials of their own - Memos,
  Excalidraw - show setup notes instead, or nothing at all. If capture failed, the panel says so and
  points you at the file on the pod where the app wrote them.
</Note>

**OpenMausBot has no password at all.** Each browser, phone or desktop app signs in by pairing with
a one-time code, and the app answers `403` to everything until a device has paired. Open the pod's
Web Terminal and run `openmausbot-pair`, then open the link it prints on the device you want to use.
Codes are single-use and expire after a few minutes - run the command again for a fresh one. The
panel's setup notes walk through this, including how to connect Claude Code or Codex as the engine.

## Finishing setup after deploy

Some apps can't be fully configured before they exist. An app that talks to a third party usually needs a callback URL - and that URL contains the pod's own domain, which isn't known until the pod is created.

For those apps, the pod page shows a **setup card** listing exactly what the app is asking for: each variable's name, what it's for, whether it's required, and whether it already has a value. Where a variable needs your pod's address, the description spells the URL out in full so you can paste it straight into the other service.

Fill the fields in and save. InstaPods writes the values to the app's own env file and restarts the app. The card keeps prompting until every **required** variable has a value.

<Note>
  "Required" means required before the app is usable - not required to deploy. You can always create the pod first and finish setup afterwards.
</Note>

Over the API:

```bash theme={null}
# What is this app still asking for?
curl https://app.instapods.com/api/pods/my-app/apps/crm/setup \
  -H "Authorization: Bearer YOUR_TOKEN"

# Answer it
curl -X POST https://app.instapods.com/api/pods/my-app/apps/crm/setup \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"vars": {"GOOGLE_CLIENT_ID": "...", "GOOGLE_CLIENT_SECRET": "..."}}'
```

The `GET` response includes `complete: true` once every required variable is set. Only variables the app declares are accepted - this is a guided form, not a general env editor, and for that you want [`instapods env set`](/guides/environment-variables). A variable marked secret is never echoed back; the response only tells you whether it has a value.

Leaving a field blank keeps whatever value is already there, so you can update one variable without resupplying the rest.

## Updating an app

When a new version of an app is released, the pod shows an **Update Available** badge. Updating is one click, and it's guarded.

Before touching anything, InstaPods snapshots the pod. If the update fails, or the app doesn't come back healthy afterwards, the snapshot is rolled back automatically and the pod is marked **Update Rolled Back** - you're left on the version that was working, not on a broken half-upgrade.

<Tabs>
  <Tab title="Dashboard">
    Open the pod and click **Update** on the app card. The status moves through **Updating** to either the new version or **Update Rolled Back**, which turns the button into **Retry Update**. The reason is shown on the card - it quotes the last thing the update printed, so it usually says what went wrong.

    If you stop or restart the pod in the few seconds after clicking **Update**, the update doesn't start at all: the card says so, nothing on the pod was changed, and you can start the pod and click **Retry Update**.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    curl -X POST https://app.instapods.com/api/pods/my-app/apps/n8n/update \
      -H "Authorization: Bearer YOUR_TOKEN"
    ```

    Returns `202 Accepted`; the update runs in the background. Watch the pod's **Events** tab, or poll `GET /api/pods/my-app/apps`.
  </Tab>
</Tabs>

<Note>
  Some apps need more memory to update than to run - a build step during the upgrade can exceed a small plan. If the pod is too small, the update is refused up front, before the running app is stopped, and tells you which plan it needs.
</Note>

**n8n** updates follow n8n's own release line but stay on **2.x** for now: n8n 3.0 (due October
2026\) changes how self-hosted n8n is installed, so InstaPods offers the newest stable 2.x
release until the 3.x path is verified, and the **Update Available** badge never points at 3.0
before then. Updating an n8n pod also needs about **3 GB of free disk** - the new version is
downloaded and checked next to the running one before anything is stopped, and the update is
refused (with n8n left running) if the space isn't there. The `n8n` command still works from the
pod's shell, for example `n8n export:workflow --all --output=/home/instapod/workflows.json`.

You can also stop and start a 1-Click App without stopping the whole pod, with `POST /api/pods/{name}/apps/{appType}/stop` and `.../start`.

## Configuring an app with environment variables

Most 1-Click Apps read their configuration from their own env file (not the preset's `/home/instapod/app/.env`). The CLI handles this for you - `instapods env set` writes to the right file **and restarts the app** so the change takes effect immediately. No separate `reload` is needed.

A few apps (n8n, Beszel, Memos, Uptime Kuma, Stirling PDF, Cloud Commander) have no config file of their own. For those the values go to `/home/instapod/app/.env`, InstaPods puts them in the app's process environment, and the app itself is restarted - so an n8n setting like `N8N_BLOCK_ENV_ACCESS_IN_NODE` takes effect the same way.

Two things a save can tell you, in its `warnings`:

* **A variable the app sets itself is not applied.** If the app's own service already fixes a value (n8n's `N8N_PORT`, say), yours is written to the file but not applied, and the save names the key. Overriding it would move the app off the port InstaPods routes to.
* **Excalidraw does not take environment variables.** It is a static bundle served by nginx, with no process to hold an environment. The save still writes the file, and warns that the values will not reach the app.

```bash theme={null}
# Set one or more variables (the app restarts automatically)
instapods env set my-memory EMBEDDING_PROVIDER=openai OPENAI_API_KEY=sk-your-key

# List current variables (values masked by default)
instapods env list my-memory
instapods env list my-memory --show-values

# Remove variables
instapods env unset my-memory OLD_KEY
```

<Note>
  For custom-code pods (Static, PHP, Node.js, Python, Go), `instapods env set` writes to `/home/instapod/app/.env`, puts the values in your app's process environment and restarts the app service for you - see [Environment Variables](/guides/environment-variables) for the details and the cases where your app should still load the file itself.
</Note>

## Example: AutoMem embeddings and MCP

[AutoMem](https://github.com/verygoodplugins/automem) gives your AI assistant persistent memory over MCP, backed by a knowledge graph and a vector database.

### Choosing an embedding provider

By default AutoMem uses **local embeddings** (384-dimensional) - no API key required, fully self-contained. For higher-quality semantic search, point it at a remote provider:

| Provider | `EMBEDDING_PROVIDER` | Key variable | Dimensions |
| - | - | - | - |
| Local (default) | *(blank)* | none | 384 |
| OpenAI | `openai` | `OPENAI_API_KEY` | 1024 |
| Voyage AI | `voyage` | `VOYAGE_API_KEY` | 1024 |

Set these at deploy time (in the app's setup fields or `app_config`) and AutoMem provisions its vector store at the matching dimension automatically.

<Tip>
  To switch providers **after** deploy, run `instapods env set my-memory EMBEDDING_PROVIDER=openai OPENAI_API_KEY=sk-your-key`. Because the vector dimension changes, also reset the existing vector store so it is recreated at the new size:

  ```bash theme={null}
  instapods exec my-memory -- bash -c \
    "curl -fsS -X DELETE http://127.0.0.1:6333/collections/memories && systemctl restart automem.target"
  ```
</Tip>

### Connecting an MCP client

After deploy, AutoMem's setup card shows an MCP config snippet with your pod URL and API key pre-filled. Add it to your MCP client (for example, Claude Desktop under **Settings → Developer → Edit Config**):

```json theme={null}
{
  "mcpServers": {
    "automem": {
      "command": "npx",
      "args": ["-y", "@verygoodplugins/mcp-automem"],
      "env": {
        "AUTOMEM_API_URL": "https://your-pod.instapods.app",
        "AUTOMEM_API_KEY": "your-api-key"
      }
    }
  }
}
```

<Warning>
  Use `AUTOMEM_API_URL` and `AUTOMEM_API_KEY` exactly. Older variable names (`AUTOMEM_URL`, `AUTOMEM_API_TOKEN`) are not read by the bridge and will leave it connecting to nothing.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.