---
title: Apps
url: https://www.tines.com/stories/docs/self-hosted/apps/
updated: 2026-07-29T08:24:44+00:00
---

*[tines.com](https://www.tines.com/llms.txt) › [Docs](https://www.tines.com/stories/docs/llms.txt) › [Self-Hosted](https://www.tines.com/llm/stories/docs/self-hosted.md)*

# Apps

*[View on tines.com](https://www.tines.com/stories/docs/self-hosted/apps/)*

Apps are a customizable, interactive front end for your Tines workflows, and are fully supported on both cloud and self-hosted environments. This page focuses on the latter, so if you wish to learn more about Apps in general, see [this page](https://www.tines.com/stories/docs/apps/).

In self-hosted environments, the build process differs from Tines Cloud and introduces a small number of infrastructure requirements, most importantly an up-to-date `tines-command-runner` image and outbound access to an npm registry.

# How app builds work on self-hosted

Every time an app's source files change, Tines bundles the app on the server: it resolves the app's npm dependencies, compiles the TypeScript and React source with esbuild, and stores the resulting JavaScript bundle for the app to render.

On Tines Cloud, that bundling runs in AWS Lambda. On self-hosted there is no Lambda, so bundling runs in `tines-command-runner`, the same container that already powers Run Script actions. The web server and background workers call tines-command-runner over HTTP on port `4400`, the same connection already required for Run Script.

Each app gets its own build workspace on the `tines-command-runner` container's disk, holding its `node_modules` directory. The first build for an app is a cold build and runs a full `npm install`, which can take up to two minutes. Later builds reuse the cached dependencies and typically complete in a few seconds. When an app is deleted, Tines removes its workspace.

# Requirements

## Keep tines-command-runner aligned with your Tines version

The app build toolchain, Node and esbuild, ships inside the `tines-command-runner` image. The Tines UI exposes the app builder as soon as apps are enabled for your tenant, based on the entitlement alone. It does not check whether your tines-command-runner image can actually build. If you enable apps or upgrade `tines-app` without also re-pulling `tines-command-runner`, users will see the app builder and every build will fail.

Always upgrade `tines-command-runner` to the same version as `tines-app`. This is the same guidance that already applies to other command runner features, see [Upgrading Tines](https://www.tines.com/stories/docs/upgrade-tines/).

No configuration is needed to turn the toolchain on; it is present in all official Tines images. If you build your own custom tines-command-runner images, you must pass the `ENABLE_APPS_BUILD=1` Docker build argument, which defaults to off.

## Connectivity

App builds add one outbound requirement to tines-command-runner.

| **Source** | **Destination** | **Port** | **Notes** |
| --- | --- | --- | --- |
| Command runner | registry.npmjs.org | 443 | Required to build apps. Can be replaced with an internal npm mirror. |

No other connectivity changes are needed. Builds travel over the existing web server and background worker connection to the command runner on port `4400`, and published apps are served from your existing tenant domain through your load balancer. For the full picture, see [Connectivity requirements](https://www.tines.com/stories/docs/network-and-connectivity/).

## Resources

Plan for:

- **Disk headroom on the command runner.** Each app keeps its own `node_modules` directory, plus a shared npm cache. Budget a few hundred megabytes per actively built app.
- **Ephemeral storage.** Build workspaces live on the container's local disk and are not persisted across restarts. Losing them is safe, the next build simply repeats the cold `npm install`.
- **Cold builds after a restart or scale-out.** If you run more than one tines-command-runner container, each keeps its own dependency cache, so the same app may build cold more than once. No session stickiness configuration is required for Apps.

# Setting up Apps on self-hosted

1. **Ask Tines to enable the apps entitlement for your tenant.** Contact your Account Executive or Customer Success Manager, see [Before you begin](https://www.tines.com/stories/docs/before-you-begin/). Apps are gated by a tenant entitlement that cannot be self-enabled.
2. **Confirm your tines-command-runner image matches your Tines version.** See "Keep tines-command-runner aligned with your Tines version" above.
3. **Confirm the command runner can reach an npm registry**, either the public registry or an internal mirror.
4. **Turn apps on for your tenant.** As a tenant owner, go to `https://your-tenant-domain/settings/apps`. You can enable apps tenant-wide or for specific teams. See [Admin settings for Apps](https://www.tines.com/stories/docs/admin-settings-for-apps/).

# Configuring the npm registry

By default, app builds fetch dependencies from the public npm registry. To use an internal mirror or private registry instead, set these environment variables on the tines-command-runner container. These sit alongside the Python package index settings documented in [Run Script (tines-command-runner)](https://www.tines.com/stories/docs/run-script-tines-command-runner/).

- `NPM_CONFIG_REGISTRY` - URL of the npm registry used when building apps, for example an internal mirror. When unset, the public npm registry is used. Example: `https://npm.your-company.com/`
- `NPM_TOKEN` - Auth token for a private npm registry. Has no effect unless `NPM_CONFIG_REGISTRY` is also set. The token is resolved from the environment at install time and is never written to disk.
- `NPM_CONFIG_STRICT_SSL` - Set to `false` to disable TLS certificate verification for the npm registry. Prefer adding your registry's CA to the container using `NODE_EXTRA_CA_CERTS`; use this only as a last resort when the registry is behind a self-signed certificate you cannot otherwise trust.

You can also tune build behavior, though the defaults suit most deployments.

- `TCR_APPS_BUILD_TIMEOUT_SECONDS` - Wall-clock limit for a single app build, in seconds. Default: `120`
- `TCR_APPS_WORKSPACE_DIR` - Directory holding per-app build workspaces. Default: `/run/tcr/apps`
- `TCR_APPS_NPM_CACHE_DIR` - Shared npm cache directory. Default: `/run/tcr/apps-npm-cache`

## Air-gapped and restricted-egress deployments

> **NOTE:** App builds require access to an npm registry. Air-gapped deployments must point tines-command-runner at an internal npm mirror, or app builds will not complete.

Because every build resolves dependencies at build time, apps cannot be built in an air-gapped deployment without an npm mirror. If your command runner has no route to a registry, point it at an internal mirror using `NPM_CONFIG_REGISTRY`. This is a current limitation of Apps on self-hosted.

# How published apps are served

On Tines Cloud, published apps are served from a dedicated `*.tines.app` domain. On self-hosted they are served from your own tenant domain, at `https://your-tenant-domain/apps/<app>`.

Nothing extra is needed to support this. Apps reach your users over the same load balancer, TLS certificate, and hostname as the rest of Tines, so no additional DNS records or certificates are required. Viewers must be signed in to your Tines tenant, and access follows the app's visibility setting.

# Troubleshooting

| **Symptom** | **Likely cause** |
| --- | --- |
| The build fails with a message that the Node build toolchain is not installed | The tines-command-runner image predates app build support, or was custom-built without the toolchain. Re-pull it at the same version as tines-app. |
| Builds fail with npm network or 404 errors | The command runner cannot reach the npm registry. Check egress to registry.npmjs.org on port 443, or configure NPM\_CONFIG\_REGISTRY. |
| Builds fail with a TLS or certificate error | Your registry uses a certificate the container does not trust. Add its CA to the container using NODE\_EXTRA\_CA\_CERTS. |
| Builds time out | Cold builds can take up to two minutes. If builds consistently time out, check command runner CPU and disk, and consider raising TCR\_APPS\_BUILD\_TIMEOUT\_SECONDS. |
| The app builder is visible but every build fails | Apps were enabled before tines-command-runner was upgraded. Align the image version with tines-app. |
