Skip to main content
The New Service wizard walks you through five steps to register a service with Skyhook — either from a new repository (built from a template) or by importing an existing codebase. The wizard auto-detects as much as it can (Dockerfile, container port, env vars, framework, monorepo layout) so you can accept smart defaults and move on.
The same wizard is used for Jobs — just click New Job instead. The flow adds one extra step (Job Type) where you pick between Kubernetes Job, CronJob, Argo Workflow, or Argo CronWorkflow. Everything else on this page applies to jobs too.

Opening the wizard

Three entry points in the UI:
  • New Service / New Job buttons in the top-right of the Home dashboard
  • New Service button on the Services list page
  • Deploy… button on the Clusters list (if no services exist yet)
The wizard remembers your progress in the browser — if you navigate away or refresh, you can resume where you left off.

Or from the CLI

For importing an existing repo, the terminal path is usually faster:
cd path/to/your/service
skyhook init            # interactive — review detected values before creating
skyhook init --yes      # non-interactive — accept all detected defaults
skyhook init --dry-run  # preview what would be created without touching anything
skyhook init runs the same detection pipeline as the wizard (language, framework, container port, Dockerfile location, monorepo layout, env vars) and presents the results in a single form. skyhook detect runs detection only, so you can preview or script against the results (skyhook detect --json | jq .). The rest of this page walks through the UI wizard. Both paths produce the same service and open the same set of pull requests.

Step 1 — Service Info

Service wizard step 1 showing the 4-step progress stepper, Service Info heading, Repository dropdown, Service Name field, and Description field
The first step has a single decision: new repository or existing repository. Click the Repository dropdown to see both options:
Repository picker dropdown showing existing repositories (api-gateway, payment-service, notification-service, analytics-service, frontend) with a search box and a 'Select existing or type to create new' label

Create a new repository

Type a name that doesn’t match any existing repo — Skyhook creates a new repository from a template and registers the service in one shot. You’ll get to pick from managed templates like Go Server, Java Quarkus, Python Flask, Python FastAPI, Node.js Express, Node.js NestJS, Node.js Next.js, and a few others pulled from KoalaOps/koala-templates.

Import an existing repository

Pick an existing repo from the list. Skyhook immediately triggers repo detection in the background:
  • Description is auto-filled from the GitHub repo description
  • Service name is auto-derived from the repo name (lowercase, no spaces)
  • Path in Repository lets you point at a subfolder if the code isn’t at the repo root
  • Monorepo detection — if the repo is a monorepo with multiple services, an inline picker lists each service as a clickable chip (with name, path, language, and a Dockerfile indicator). Selecting a service auto-sets the path and service name; a Custom path… option lets you enter a path manually
Background detection prefetches env vars, Dockerfile location, and port at the moment you finish step 1, so later steps feel instantaneous instead of waiting on API calls.

Step 2 — Build Config

Build Config step showing a Dockerfile section ('No Dockerfile found. Skyhook will generate one based on your project.'), Container Port field, Registry Provider dropdown, Container Registry field, and Deployment Config section with 'Same repo as service' / 'Separate repo' radio buttons
Configure how the service is built, where images are stored, and where deployment manifests live.

Dockerfile

  • Dockerfile found — Skyhook uses the one it detected. You can override the path.
  • No Dockerfile — Skyhook offers to generate one based on the detected framework.

Container Port

The port your application listens on. Auto-filled from Dockerfile EXPOSE when present.
Port conflict handling. If the Dockerfile EXPOSE doesn’t match the port in your app config (e.g. a Node server listening on 3000 but EXPOSE 8080 in the Dockerfile), Skyhook shows a conflict alert in the network step and asks you to pick one — with a note that EXPOSE is informational in Kubernetes and the app-config port is usually the right choice.

Container Registry

  • Registry Provider — dropdown for GitHub Container Registry, Docker Hub, AWS ECR, GCP Artifact Registry, etc.
  • Container Registry — the specific registry URL (e.g. ghcr.io/acme). Defaults to the org setting.

Deployment Config

Where Skyhook should write the generated Kubernetes manifests:
  • Same repo as service — manifests go into a folder inside the service repo (monorepo-style)
  • Separate repo — manifests go into a dedicated GitOps/deployment repo (recommended for multiple services). Picks the org default repo automatically.
Folder Path defaults to the service name and is editable.

Step 3 — Environments

Environments step showing a table with environment name, cluster, namespace, provider, and region columns, with checkboxes on each row for dev, prod, staging, customer envs, and per-customer rows
Pick which environments to deploy the service to. The table shows every environment defined at the org level (from Settings → Environments) with its cluster, namespace, provider, and region so you can sanity-check target placement.
  • Check one or more rows
  • For new services without an org-level environment yet, Skyhook starts you with a default dev and prod pair you can accept and adjust later
  • Smart cluster defaults pull from other services in the org, so the first environment picks the most-used cluster automatically
  • When importing an existing service, environments are populated from the service’s actual configuration once it loads
Labels and AutoDeploy toggles on the org-level environments (see Environments overview) carry through to the service when it’s created.

Step 4 — Environment Variables (import only)

Env Variables step showing 13 detected variables from koala-backend with checkboxes for selection, secret toggle indicators, 'found in N files' annotations, value columns, and auto-populated defaults like 'Env.Cluster', 'http://cluster-agent-controller-service:8080', 'Debug', and '8080'
This step only appears when importing an existing repository — new services don’t have code to analyze yet. Skyhook walks your codebase looking for patterns like process.env.X, os.Getenv("X"), System.getenv("X"), Helm chart values, and Kubernetes manifests, then shows every variable it found with:
  • Variable name
  • Source location — “found in N files” (click to expand). When the same variable has different values in different files, Skyhook tells you “N different values” so you can pick the right one.
  • Secret toggle — promote a variable to a Kubernetes secret (secret values aren’t checked into Git; you’re prompted to set after creation)
  • Value — auto-filled from what Skyhook found in code, or editable per-environment

Header controls

  • Select All / Deselect All — bulk toggle inclusion
  • N detected · N selected · N secrets — running counts so you can see what’s in

Defaults

  • Well-known secret-shaped names (*_TOKEN, *_KEY, *_PASSWORD, credentials paths) are auto-flagged as secrets
  • Variables found in only one file are auto-selected with the found value
  • Variables found in multiple files with different values are auto-selected but left unset so you can pick a value intentionally

AI-powered discovery

For codebases where pattern-matching misses references (indirect environment access, dynamic lookups), click Discover to run an AI-powered analyzer that identifies likely environment variables and secrets. Results are filterable by type (Variables, Secrets, or All), confidence level, and source file. The same Discover action is also available on the Env Vars & Secrets tab of existing services.

Add manually

If detection missed something, use Add variable manually at the bottom to enter a name, value, and secret flag. All selections from this step become the service’s base env vars + per-environment overrides. You can refine them later on the service’s Env Vars & Secrets tab.

Step 5 — Review & Import

Review step showing Service Info, Build Config, Environments (with prod and nonprod chips), and Environment Variables (13 variables with detected framework chips like go, health, routes) sections, each with an edit icon, and an Import Service button at the bottom
Final summary before creation. Each section (Service Info, Build Config, Environments, Environment Variables) has an Edit icon that jumps back to the relevant step. The Environment Variables row shows a count of selected variables plus detection badges (framework and features inferred from the codebase, e.g. go, health, routes).

Adaptations

For imported services, a dedicated Adaptations section shows any warnings or info messages from the detection pipeline along with the auto-fix Skyhook will apply:
  • “Dockerfile EXPOSE 8080 mismatches detected app port 3000 — will use 3000”
  • “Missing Helm chart — one will be generated from the service name”
  • “No Kubernetes manifests found — base manifests will be generated”
Each adaptation has a short description so nothing is applied silently.

Submit

Clicking Import Service (or Create Service) kicks off the setup process in three phases:
  1. Setup — Skyhook creates the required files and opens the pull requests needed to register the service
  2. Review and merge — a status panel shows every pull request Skyhook opened, waiting for you to review and merge them. Each one has a Review PR button that opens the in-app pull request review
  3. Done — once every pull request is merged and the repository files are in place, Skyhook takes you to the new service page
A single service creation can open up to 3 PRs — one against the service repo (Dockerfile, workflows, koala-config), one against the deployment/GitOps repo (Kubernetes manifests), and one against the GitOps registration repo (service discovery). The PR gate keeps all of them visible in one place so you’re never guessing which one is left.

After creation

Once the service page loads, a Pending PRs banner at the top shows any migration or setup PRs that are still in flight. Each row has a Review PR button; rows disappear automatically as PRs are merged. From there, use the service tabs (General, Runtime, API, Logs, Deployments, Production Readiness, Env Vars & Secrets, Settings) to configure and operate the service.

Troubleshooting

Analysis timed out or couldn’t reach your repository. You can still proceed — you’ll just need to fill in Dockerfile path, container port, and environment variables manually. The service will work fine; you only lose the convenience of auto-fill.
Monorepo detection looks for common layouts (services/, apps/, packages/, cmd/) with a Dockerfile or package manifest. If your service lives outside those paths, click Custom path… and enter the subdirectory manually.
In Kubernetes, EXPOSE in a Dockerfile is purely informational — the actual port is what your app listens on. If your Node server calls app.listen(3000) but the Dockerfile has EXPOSE 8080, pick 3000. The recommended button on the alert corresponds to the port your app actually binds to.
Re-select the repository in step 1 and the smart defaults will re-apply.
Skyhook checks GitHub for merge status every few seconds. If a pull request shows as merged on GitHub but the setup panel doesn’t update, click Refresh. Skyhook also verifies that the expected files are actually in place, so a partial merge (only some of the pull requests) will still show as pending.