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-appMCP 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:
- Go to My Apps
- Click the update (refresh) icon on your application card
- Choose Restart or Rebuild in the dialog
- 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.
Pinning to a Specific Git Ref
By default, restarts and rebuilds pull the latest commits from your repository's default branch. You can pin your app to a specific branch, tag, or commit SHA to lock deployments to a known-good version or to deploy from a feature branch.
How to Pin
Via the Web Console:
- Go to My Apps
- Click on your application to open the detail page
- Click the Settings tab
- Scroll to the Git ref section
- Enter a branch name, tag, or commit SHA in the input field (e.g.
v1.2.3,feature/my-branch,abc1234) - Click Pin to ref
The Settings tab shows "Pinned to <ref>" once saved. Future restarts and rebuilds pull from that ref instead of the default branch head.
How to Unpin
- Open the Settings tab for your app
- Clear the Git ref input field
- Click Unpin
The app returns to following the latest commits on the default branch.
Supported Ref Formats
| Type | Examples |
|---|---|
| Branch | main, develop, feature/my-feature |
| Tag | v1.2.3, release-2025-01 |
| Commit SHA | abc1234, full 40-character SHA |
The field accepts letters, numbers, dots, hyphens, underscores, and slashes. Spaces and special characters are not allowed.
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:
- Go to My Apps
- Find your application card
- Toggle the HA switch to enable it
- 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:
- Go to My Apps
- Toggle the HA switch off
- The standby instance is removed
Via MCP (AI Agent):
"Disable HA for my app called myapp"
Requirements
- Your application must expose a
/healthzendpoint that returns HTTP 200 when the app is healthy. OSC uses this to determine when the standby is ready to receive traffic. - HA mode requires a paid plan (Personal, Professional, Business, or Enterprise). The HA toggle is disabled for FREE plan accounts with a tooltip explaining the requirement.
- 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).
Collaborators
You can invite external collaborators to your app. Collaborators get their own Gitea account scoped to your repository — they can clone, browse, and open issues without sharing your admin credentials. They also have access to the Collaborator Portal, a lightweight web interface where they can submit feature requests and bug reports and track the status of their submissions.
Inviting a Collaborator
Via the Web Console:
- Go to My Apps and open the detail page for your app.
- Click the Collaborators tab (last tab on the detail page).
- Click Invite collaborator.
- Enter the collaborator's email address and click Invite.
- The modal shows a copyable invite URL. Send this URL to the collaborator — it includes their email address so the portal login form is pre-filled when they follow the link.
After an invite is sent, the collaborator appears in the table with status Pending until they accept. Once accepted the status changes to Active.
Collaborator Portal
The Collaborator Portal is a self-contained web UI at https://app.osaas.io/collab/{appId} that lets external contributors interact with your app's SDLC without an OSC account.
Collaborators log in with the email address their invite was sent to. Once logged in they can:
- Submit new feature requests and bug reports
- View a live list of their submitted tickets with status labels (Queued, Planning, Working on it, In review, Shipped, Needs your input)
The ticket list polls for updates every 5 seconds while the tab is visible, so collaborators see progress in real time without refreshing. Submissions also appear in your app's Requests tab (in the Agentic SDLC view) alongside requests created by the agent, labelled as sdlc/source:collaborator.
Resetting or Resending Access
The icon button next to each collaborator in the table adapts based on their status:
- Pending collaborators show a Resend invite button (envelope icon). Use this if the collaborator never received or lost their original invite link. A new invite URL is generated and shown — copy it and send it to them.
- Active collaborators show a Reset access link button (key icon). Use this to rotate the collaborator's portal access link, for example after a suspected compromise. A fresh URL is generated; the old one is invalidated immediately.
In both cases the new URL is displayed in a modal after the action completes.
Collaborator Statuses
| Status | Meaning |
|---|---|
| Active | Collaborator has accepted the invite and their Gitea account is active |
| Pending | Invite sent but not yet accepted |
| Revoked | Access has been removed |
Revoking a Collaborator
Click the Revoke button next to an active or pending collaborator. Confirming the revocation deactivates their Gitea account and removes their repository access immediately.
Note: Collaborator access requires Agentic SDLC to be enabled for the app, which provisions the managed Gitea repository that collaborators access.
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:
- Go to My Apps
- Click the analytics icon on your application row
- 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.
Accessing Gitea Credentials
When Agentic SDLC is enabled for an app, OSC provisions a private Gitea instance where SDLC tickets and activity are stored. You can retrieve the admin credentials to log into the Gitea web UI directly.
Via the Web Console:
- Go to My Apps
- Click the app row to expand it, then click the app name or the settings icon to open the app detail page
- Click the Git access tab (only visible for apps with a managed Gitea repository)
- The tab shows the git repository URL with a copy button and an Open in Gitea link
- Click Show login credentials to reveal the admin username and password. A confirmation dialog warns that this resets the existing password. Click Continue to proceed.
- Copy and save the displayed credentials immediately. The password is shown only once.
Via MCP (AI Agent):
"Get the Gitea credentials for my app called myapp"
The get-myapp-git-credentials tool returns the Gitea URL, admin username (oscadmin), password, and a direct link to the login page.
To rotate the admin password:
"Rotate the Gitea credentials for my app called myapp"
The rotate-myapp-git-credentials tool generates a new password, updates it in Gitea, and returns the new credentials.
Note: Gitea credentials are only available for apps with a managed Gitea repository (apps not using a GitHub URL as the source). Apps provisioned before the credential-storage feature was introduced may return a "credentials not available" response. Use "Show login credentials" in the web console or the
rotate-myapp-git-credentialsMCP tool once to generate and store a fresh password.
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:
- Go to My Apps
- Click the Config button on your application row
- Select a parameter store from the dropdown, or choose None to remove the current binding
- 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 or remove the token in place; the app is rolling-restarted so there is no downtime and no recreation of the app.
Via the Web Console:
- Go to My Apps
- Click the Config button on your application row
- Scroll to the GitHub Personal Access Token field at the bottom of the Config modal
- Enter your new Personal Access Token (format:
ghp_...) and click Save - A rolling restart is triggered automatically. The app stays available throughout.
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 and triggers a rolling restart. The app remains available during the update.
Import an Existing App
If you already have a GitHub repository you want to host on OSC, you can import it directly rather than starting from scratch. The import flow provisions the app in OSC and sets up a managed Gitea repository for it.
Prerequisites
- An OSC account
- A GitHub repository URL (public or private)
- GitHub credentials (Personal Access Token) configured in your OSC profile. If they are not set up yet, OSC will prompt you during the import flow.
How to Import
- Go to My Apps
- Click the Import button
- Enter your GitHub repository URL in the import dialog
- If GitHub credentials are not configured in your profile, a credential setup prompt appears. Add your Personal Access Token there, then continue.
- OSC provisions the app and sets up a Gitea repository. A progress indicator is shown during this process.
- When the import completes, the app appears in your My Apps list.
What Happens During Import
- OSC creates a service instance for your app
- A managed Gitea repository is provisioned and linked to the app
- If GitHub credentials were missing, OSC stores them in your Profile settings (Profile > Git credentials) for future use
What to Do Next
After importing, the app is provisioned but not yet deployed. Your next steps are:
- Deploy the app — see the Deploy or Publish Your Application guide
- Enable Agentic SDLC — set up automated CI/CD and AI-assisted development via the Agentic SDLC guide
- Add backend services — connect databases, caches, and other services from the OSC catalog
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 (requires paid plan), then restart | No |
| Use a custom domain | See Custom Domains guide | N/A |
| Deploy from a specific branch, tag, or commit SHA | Pin to the ref via Settings tab | No |
| 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 via Config button → GitHub Personal Access Token field (web) 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 |
| Access Gitea web UI for SDLC tickets | Ask AI agent (get-myapp-git-credentials) or see Accessing Gitea Credentials |
N/A |
| Rotate Gitea admin password | Ask AI agent (rotate-myapp-git-credentials) |
N/A |
| Invite a collaborator to the Gitea repo | Open app detail → Collaborators tab → Invite collaborator | N/A |
| Revoke collaborator access | Open app detail → Collaborators tab → Revoke | 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
- AI-Assisted App Management — Deploy, configure, and troubleshoot apps using natural language
- Deploy or Publish Your Application — How to deploy apps on OSC
- Custom Domains — Setting up custom domain names
- Parameter Store — Managing application configuration
- Service: Web Runner — Web Runner service documentation