Skip to content

Apps

Apps are the core building blocks of your WebKit project. Each app represents a deployable service with its own build configuration, infrastructure settings, and environment variables.

Attributes

KeyDescriptionRequired
nameMachine-readable name (kebab-case)Yes
typeApplication typeYes
pathRelative path to the app directoryYes
descriptionHuman-readable descriptionNo
buildBuild configurationNo
infrastructureDeployment settingsNo
domainsDomain configurationNo
environmentPer-environment variablesNo
commandsCustom build/test/lint commandsNo
monitoringUptime monitoring settingsNo

App types

WebKit supports these application types:

TypeDescriptionDefault commands
svelte-kitSvelteKit applicationspnpm build, pnpm lint, pnpm test
payloadPayload CMS applicationspnpm build, pnpm lint
golangGo applicationsgo build, golangci-lint run, go test

Each type comes with sensible defaults for commands and configuration.

Basic example

A minimal app definition:

json
{
  "apps": [
    {
      "name": "web",
      "type": "svelte-kit",
      "path": "./apps/web"
    }
  ]
}

Build configuration

Configure how your app is built:

json
{
  "apps": [
    {
      "name": "api",
      "type": "golang",
      "path": "./apps/api",
      "build": {
        "dockerfile": true,
        "port": 8080,
        "health_check_path": "/api/health"
      }
    }
  ]
}
FieldDescriptionDefault
dockerfileGenerate Dockerfiletrue
portExposed port3000
health_check_pathPath for health check endpoint during deployment/

Infrastructure

Define where and how your app is deployed:

json
{
  "apps": [
    {
      "name": "web",
      "type": "svelte-kit",
      "path": "./apps/web",
      "infrastructure": {
        "provider": "digital_ocean",
        "type": "app",
        "config": {
          "instance_size": "basic-xs",
          "instance_count": 2,
          "region": "lon"
        }
      }
    }
  ]
}

Provider options

ProviderDescription
digital_oceanDigitalOcean (App Platform or Droplets)
hetznerHetzner Cloud VMs

Infrastructure types

TypeDescription
appManaged container platform (DigitalOcean App Platform)
vmVirtual machine (Droplet or Hetzner server)

Config options

Config varies by provider and type. See the infrastructure providers documentation for detailed options.

Domains

Configure domains for your app:

json
{
  "apps": [
    {
      "name": "web",
      "domains": {
        "primary": "example.com",
        "aliases": ["www.example.com", "app.example.com"],
        "managed": true
      }
    }
  ]
}
FieldDescription
primaryMain domain for the app
aliasesAdditional domains pointing to the app
managedWhether WebKit manages DNS records
unmanagedDomains managed externally

Unmanaged domains

For domains not managed by your infrastructure provider:

json
{
  "domains": {
    "primary": "example.com",
    "unmanaged": ["legacy.example.com"]
  }
}

Unmanaged domains are configured in the app but DNS must be set up manually.

Environment variables

Define per-environment variables using the object format:

json
{
  "apps": [
    {
      "name": "cms",
      "environment": {
        "dev": {
          "DATABASE_URL": {
            "source": "value",
            "value": "postgres://localhost:5432/cms_dev"
          }
        },
        "staging": {
          "DATABASE_URL": {
            "source": "resource",
            "value": "postgres-staging.connection_url"
          }
        },
        "production": {
          "DATABASE_URL": {
            "source": "resource",
            "value": "postgres.connection_url"
          },
          "PAYLOAD_SECRET": {
            "source": "sops",
            "value": "payload_secret"
          }
        }
      }
    }
  ]
}

Variable sources

SourceDescriptionExample value
valueStatic string"https://api.example.com"
resourceTerraform output"postgres.connection_url"
sopsEncrypted secret"api_key"

See Environment variables for detailed documentation.

Commands

Customise commands for build, test, lint, and format. Commands can be specified in three formats:

Boolean format

Enable or disable a command:

json
{
  "commands": {
    "test": false,
    "build": true
  }
}

String format

Override the command with a simple string:

json
{
  "commands": {
    "build": "go build -o bin/api ./cmd/api",
    "test": "go test -race ./..."
  }
}

Object format

Full control with additional options:

json
{
  "apps": [
    {
      "name": "api",
      "type": "golang",
      "commands": {
        "build": {
          "command": "go build -o bin/api ./cmd/api",
          "working_directory": "./cmd/api",
          "timeout": "10m"
        },
        "test": {
          "command": "go test -race ./...",
          "skip_ci": false
        },
        "lint": {
          "command": "golangci-lint run"
        }
      }
    }
  ]
}
FieldDescriptionDefault
commandShell command to executeRequired
working_directoryDirectory to run the command inApp's path
skip_ciSkip this command in CI/CD workflowsfalse
timeoutMaximum execution time (e.g., 5m, 1h)None

Working directory

By default, commands run in the app's path directory. Use working_directory to run commands in a different location:

json
{
  "name": "web",
  "path": "apps/web",
  "commands": {
    "build": "pnpm build",
    "test": {
      "command": "pnpm test",
      "working_directory": "apps/web/src"
    }
  }
}

Commands are used in generated CI/CD workflows.

Monitoring

Enable uptime monitoring for your app:

json
{
  "apps": [
    {
      "name": "web",
      "monitoring": {
        "http": true
      }
    }
  ]
}

Basic HTTP monitoring

Setting http: true creates an HTTP monitor for your primary domain.

Custom monitors

Add additional monitors:

json
{
  "monitoring": {
    "http": true,
    "custom": [
      {
        "type": "http_keyword",
        "name": "API Health",
        "url": "https://api.example.com/health",
        "keyword": "\"status\":\"ok\"",
        "interval": 60
      },
      {
        "type": "dns",
        "name": "DNS Check",
        "hostname": "example.com",
        "dns_server": "8.8.8.8"
      }
    ]
  }
}

See Monitoring for all monitor types.

Complete example

A fully configured app:

json
{
  "apps": [
    {
      "name": "cms",
      "type": "payload",
      "description": "Headless CMS for content management",
      "path": "./apps/cms",
      "build": {
        "dockerfile": true,
        "port": 3000
      },
      "infrastructure": {
        "provider": "digital_ocean",
        "type": "app",
        "config": {
          "instance_size": "basic-s",
          "instance_count": 1,
          "region": "lon"
        }
      },
      "domains": {
        "primary": "cms.example.com"
      },
      "environment": {
        "dev": {
          "DATABASE_URL": {
            "source": "value",
            "value": "postgres://localhost:5432/cms_dev"
          },
          "PAYLOAD_SECRET": {
            "source": "value",
            "value": "dev-secret-change-me"
          }
        },
        "production": {
          "DATABASE_URL": {
            "source": "resource",
            "value": "postgres.connection_url"
          },
          "PAYLOAD_SECRET": {
            "source": "sops",
            "value": "payload_secret"
          },
          "S3_BUCKET": {
            "source": "resource",
            "value": "storage.bucket_name"
          },
          "S3_ENDPOINT": {
            "source": "resource",
            "value": "storage.endpoint"
          }
        }
      },
      "commands": {
        "build": "pnpm build",
        "lint": "pnpm lint"
      },
      "monitoring": {
        "http": true,
        "custom": [
          {
            "type": "http_keyword",
            "name": "CMS Health Check",
            "url": "https://cms.example.com/api/health",
            "keyword": "ok",
            "interval": 60
          }
        ]
      }
    }
  ]
}

Multiple apps

WebKit supports multiple apps in a monorepo:

json
{
  "apps": [
    {
      "name": "web",
      "type": "svelte-kit",
      "path": "./apps/web",
      "infrastructure": {
        "provider": "digital_ocean",
        "type": "app"
      },
      "domains": {
        "primary": "example.com"
      }
    },
    {
      "name": "cms",
      "type": "payload",
      "path": "./apps/cms",
      "infrastructure": {
        "provider": "digital_ocean",
        "type": "app"
      },
      "domains": {
        "primary": "cms.example.com"
      }
    },
    {
      "name": "api",
      "type": "golang",
      "path": "./apps/api",
      "infrastructure": {
        "provider": "hetzner",
        "type": "vm"
      },
      "domains": {
        "primary": "api.example.com"
      }
    }
  ]
}

Each app:

  • Has its own build and deployment pipeline
  • Can use different infrastructure providers
  • Shares resources defined in the manifest

Next steps

Released under the MIT Licence.