Skip to main content
Unkey Deploy is currently in private beta. To get access, reach out on Discord or email support@unkey.com.
An app represents a single deployable service within a project. Each app has its own environments, build configuration, runtime settings, and deployment history. If you’re familiar with Railway, an app fills a similar role to a Railway service.

How apps fit in

Apps sit between projects and environments in the Unkey Deploy hierarchy:
Workspace
  └── Project (one per codebase)
        └── App (one per service)
              ├── Environments (production, preview)
              │     ├── Deployments
              │     ├── Variables
              │     └── Custom domains
              └── Settings (build, runtime, Sentinel)
A project can contain multiple apps. Each app has its own pair of default environments (production and preview), its own build and runtime settings, and its own Sentinel configuration.

Default app

When you create a project, Unkey creates a default app automatically. For projects with a single service, this is all you need. The dashboard manages the default app transparently, so you interact with it through your project’s Settings and Deployments tabs without selecting an app.

Multiple apps

A project can contain multiple apps when your codebase produces more than one deployable service. For example, a monorepo might have an API server and a background worker that share the same repository but build and deploy independently. Each app in a multi-app project has:
  • Its own Dockerfile and build context
  • Its own runtime settings (CPU, memory, port, health check)
  • Its own environments and deployment history
  • Its own Sentinel policies
The dashboard does not yet support creating or managing multiple apps within a project. You can deploy to a specific app using the CLI. Contact support@unkey.com if you need multi-app projects configured.

Deploy to an app

When deploying with the CLI, you can target a specific app using the --app flag:
unkey deploy ghcr.io/acme/api:v1.0.0 \
  --project=acme-platform \
  --app=api \
  --env=production
The --app flag defaults to default, so you can omit it for single-app projects. You can also set the UNKEY_APP environment variable instead of passing the flag each time.

Environments

Each app gets two environments when created:
EnvironmentPurpose
ProductionServes live traffic. Gets three Sentinel replicas for high availability.
PreviewFor testing branches before merging. Gets one Sentinel replica.
Environments are scoped to an app, not to the project. This means each app in a multi-app project has its own independent production and preview environments with separate variables and custom domains. See Environments for details on how environments work.

Current deployment and rollbacks

Each app tracks which deployment is live. When a deployment reaches the ready state, it becomes the current deployment, and sticky domains (live and environment-scoped) point to it automatically. You can roll back to a previous deployment, which atomically switches traffic to the older version. The app tracks its rollback state so the dashboard can show whether you’re running the latest deployment or a rolled-back version.

GitHub integration

Each app can connect to a GitHub repository. Pushes to the default branch trigger production deployments, and pushes to other branches trigger preview deployments. See GitHub integration for setup instructions. In a multi-app project, each app connects to the same repository but can use different Dockerfiles and watch paths to build independently.
Last modified on March 30, 2026