User Guide: Managing Custom Apps - EyevinnOSC/community GitHub Wiki

Managing Custom Apps

After deploying a custom application via My Apps, you can manage it with restart, rebuild, high-availability, and custom domain features. This guide covers the operational features available for deployed apps.

Restart vs Rebuild

When your application needs updating, you have two options. Restart is the default and recommended approach for deploying new code. It is faster because it reuses the build cache. Only use rebuild when you specifically need to clear caches.

Restart (default — use this for code updates)

A restart pulls the latest code from your git repository and restarts the application container. It reuses the existing build and dependency cache (e.g. node_modules) if the lockfile has not changed. This makes restarts significantly faster than rebuilds.

Use restart when:

  • You pushed new code to your repository (this is the most common case)
  • You changed configuration values in the parameter store
  • The application is stuck or unresponsive

Rebuild (only when caches need clearing)

A rebuild fully recreates the application instance from scratch. It deletes the running instance and creates a new one, clearing all caches and rebuilding from the latest source code and container image. This is slower than a restart because no caches are reused.

Note: When rebuilding via the restart-my-app MCP tool, any parameter store (ConfigService) binding is automatically preserved and re-applied to the new instance.

Only use rebuild when:

  • You changed package.json (or equivalent) dependencies and the cached node_modules are stale
  • You need to pick up a new base image or runtime version
  • A restart did not resolve your issue (rebuild as a last resort)
  • Your app with a parameter store (ConfigService) fails to load environment variables with an expired token error (apps created before 2026-02-25 used short-lived tokens — a rebuild migrates them to a long-lived refresh token). Note: you can also use the Config button or update-my-app-config MCP tool to re-bind the parameter store without a full rebuild.

How to Restart or Rebuild

Via the Web Console:

  1. Go to My Apps
  2. Click the update (refresh) icon on your application card
  3. Choose Restart or Rebuild in the dialog
  4. Click Confirm

Via MCP (AI Agent):

"Restart my app called myapp"

"Rebuild my app called myapp"

The MCP create-my-app tool and CLI support both operations.

High Availability (HA) Mode

HA mode provides zero-downtime deployments by running two instances of your application in a blue-green configuration.

How HA Works

When HA is enabled, OSC maintains two copies of your application:

  • Active (a-side) — the instance currently serving traffic
  • Standby (b-side) — a warm standby ready to take over

When you restart or rebuild with HA enabled, only the standby is updated first. Once the standby passes health checks, traffic is switched to it. This means your application stays available throughout the update process with no downtime.

The update flow:

  1. The standby instance is restarted (or rebuilt)
  2. OSC polls the standby's /healthz endpoint until it responds with HTTP 200
  3. The proxy switches traffic from the active to the standby
  4. The previously active instance becomes the new standby

Enabling HA

Via the Web Console:

  1. Go to My Apps
  2. Find your application card
  3. Toggle the HA switch to enable it
  4. The standby instance is created automatically with the same configuration as your active instance

Via MCP (AI Agent):

"Enable HA for my app called myapp"

Disabling HA

Via the Web Console:

  1. Go to My Apps
  2. Toggle the HA switch off
  3. The standby instance is removed

Via MCP (AI Agent):

"Disable HA for my app called myapp"

Requirements

  • Your application must expose a /healthz endpoint that returns HTTP 200 when the app is healthy. OSC uses this to determine when the standby is ready to receive traffic.
  • HA mode creates a second instance, which counts as an additional service instance for billing purposes.

What Gets Copied to the Standby?

When HA is enabled, the standby instance receives an exact copy of the active instance's configuration, including:

  • Git repository URL
  • Access token (for private repos)
  • Parameter store (ConfigService) configuration
  • OSC access token
  • Sub-path (for monorepo deployments)

Any future configuration changes should be applied by updating the active instance and then restarting (which triggers the blue-green update flow).

Monitoring App Status

The My Apps dashboard shows real-time build and runtime status for each deployed application in the URL column:

Status Description
Building... The application is currently being built or deployed
(URL link) The application is running and accessible
Build failed The last build failed — check logs for details

When a build fails, the URL column shows a red "Build failed" message with a "Check logs for details" hint. Use the Viewing Logs tools below to diagnose the issue.

After triggering a restart or rebuild, the dashboard shows a spinner with a "Restarting..." or "Rebuilding..." label. The status automatically refreshes every 5 seconds until the app reaches a terminal state (running or failed).

Via MCP (AI Agent):

The list-my-apps, get-my-app, and create-my-app MCP tools include a buildStatus field in their output (building, running, failed, or unknown). AI agents can check build status directly:

"What is the build status of my app called myapp?"

"List my apps and show me which ones have failed"

Analytics

You can attach a Umami web analytics instance to your app to track pageviews and user behavior without cookies. When analytics is configured, you can view your Umami dashboard credentials directly from the My Apps page.

Viewing Analytics Credentials

Via the Web Console:

  1. Go to My Apps
  2. Click the analytics icon on your application row
  3. The modal shows your Umami dashboard URL, username, and password (with a show/hide toggle)

Via MCP (AI Agent):

"Show me the analytics credentials for my app called myapp"

Setting Up Analytics

See the AI-Assisted App Management guide for how to provision and bind an analytics instance using the AI assistant or MCP tools.

Custom Domains

By default, when you deploy an app via My Apps it receives a URL like https://<hash>.apps.osaas.io — a stable but random-looking address. If you want a friendlier URL such as mycoolapp.apps.osaas.io, you can set up a managed domain (subject to availability at no extra cost) or bring your own custom domain (requires a paid plan). See Custom Domains for the full setup guide.

Viewing Logs

Application logs can be viewed via the MCP tools:

"Show me the logs for my app called myapp"

"Show me the last 50 lines of logs for myapp"

"Show me errors in the logs for myapp since 2026-02-24T10:00:00Z"

The get-my-app-logs MCP tool is the dedicated way to retrieve logs from custom apps deployed via My Apps. You only need the app name — the tool automatically determines the runtime type. You can narrow results with optional filter parameters:

Parameter Description Example
tail Return only the last N lines tail=50
since Return only logs after this ISO 8601 timestamp since="2026-02-24T10:00:00Z"
level Filter to a specific log level (error, warn, or info) level=error

Or via CLI:

npx @osaas/cli logs eyevinn-web-runner myapp

Configuration with Parameter Store

To manage environment variables for your application, use a Parameter Store. Values in the parameter store are injected as environment variables when your application starts.

Changes to the parameter store take effect on the next restart or rebuild.

Changing or Removing the Parameter Store Binding

You can add, change, or remove a parameter store binding on an existing app without deleting and recreating it. The app is rolling-restarted automatically to pick up the new configuration.

Via the Web Console:

  1. Go to My Apps
  2. Click the Config button on your application row
  3. Select a parameter store from the dropdown, or choose None to remove the current binding
  4. Click Save

Via MCP (AI Agent):

"Bind the parameter store called myconfig to my app called myapp"

"Remove the parameter store binding from my app called myapp"

The AI agent uses the update-my-app-config MCP tool, which accepts the app ID and the name of the parameter store to bind (or null to remove the binding).

Monorepo Apps with subPath and configService

When deploying a monorepo application using both subPath and configService, be aware that parameter store environment variables are loaded by the Web Runner's root-level startup script. If your workspace defines its own start command (e.g., npm run start --workspace=backend), the workspace script runs directly and may bypass the root-level config loading step.

Symptoms: Your app starts but all parameter store values (DATABASE_URL, SMTP_HOST, etc.) are missing. Logs may show [CONFIG] Loaded 0 environment variable(s).

Solution: Ensure your workspace's entry point handles APP_CONFIG_URL loading. You can do this by adding a start script in your workspace that fetches parameters before starting the app:

// backend/start.js
const { loadConfig } = require('./config-loader');

async function main() {
  if (process.env.APP_CONFIG_URL) {
    await loadConfig(process.env.APP_CONFIG_URL);
  }
  // Start your actual application
  require('./index.js');
}

main();

Or reference the root-level start script if your project structure allows it. The key requirement is that APP_CONFIG_URL must be fetched and its values injected into process.env before your application code runs.

Updating the GitHub Token

If your app was built from a private repository and the access token expires, builds will fail with a "Source repository is not reachable (404)" error. You can update the token without losing your app configuration.

Via MCP (AI Agent):

"Update the GitHub token for my app called myapp"

The agent uses the update-my-app-github-token tool. It preserves all existing settings (git URL, runtime type, parameter store binding, analytics) and recreates the app with the new token. The app will be briefly offline during the update.

Note: Because the app is deleted and recreated, it will be temporarily unavailable. The URL remains the same.

Decision Matrix for AI Agents

When a user asks about managing their app, use this guide. The default action for deploying new code is always restart (without rebuild). Restart uses the build cache and is significantly faster. Only use rebuild when caches are explicitly the problem.

User wants to... Recommended action Use rebuild?
Deploy latest code changes Restart No
Update after pushing new commits Restart No
Fix a bug by pushing a code fix Restart No
Fix dependency or cache issues Rebuild Yes
Pick up new base image / runtime Rebuild Yes
Restart did not fix the issue Rebuild (as last resort) Yes
Achieve zero-downtime updates Enable HA, then restart No
Use a custom domain See Custom Domains guide N/A
Change environment variables Update parameter store, then restart No
Add, change, or remove parameter store binding Use Config button (web) or update-my-app-config (MCP) No
Check if app built/deployed successfully Check build status in My Apps dashboard or ask AI agent N/A
App shows "Build failed" Check logs, fix the issue, push fix, then restart No
App fails with "Source repository is not reachable (404)" Update GitHub token using update-my-app-github-token MCP tool or ask AI agent N/A
Set up web analytics Ask AI agent or see AI-Assisted App Management N/A
View Umami analytics credentials Click analytics icon in My Apps (web) or ask AI agent N/A

Important for AI agents: When using the restart-my-app MCP tool, do NOT set rebuild=true unless the user specifically asks for a rebuild or the situation matches one of the "Yes" cases above. Omitting the rebuild parameter (or setting it to false) triggers a fast restart that reuses the build cache.

Related Resources

⚠️ **GitHub.com Fallback** ⚠️