Skip to content
Console →
Website →
Asking an AI? Paste this URL https://keelson.dev/llms.txt

Configuring keelson.yaml

keelson.yaml tells Keelson how to build, start, and publish an application.

This page explains why the file exists, what its main fields do, and how it is used. For the complete definition of every field, see the keelson.yaml reference.

When you use the Keelson Agent Skill, an AI agent can generate this file for you, so you usually do not need to write it from scratch.

keelson.yaml is an application-specific configuration file placed in the root directory of your project.

Keelson reads it to determine:

  • the app identifier used in its URL
  • the runtime used to execute the app
  • how the app starts
  • whether Keelson should provision Managed SQLite
  • whether the app has scheduled jobs
  • whether Keelson should serve static assets

The file is not application code. It is the description of how to run that application on Keelson. You do not need to memorize every option; start with a small configuration and add only the features the app needs.

Applications differ in language, startup command, database requirements, and the platform features they use. Keelson reads keelson.yaml to understand those differences and deploy each app correctly.

Without the file, Keelson cannot decide how to handle the project. An AI agent can inspect your code and generate the configuration, but the resulting file is still the explicit deployment contract.

Keelson reads keelson.yaml when a deployment starts. It then:

  1. Validates the configuration, including field values and cross-field rules
  2. Builds the app for the selected runtime
  3. Starts it with the configured command, when it has a web process
  4. Prepares features such as Managed SQLite and scheduled jobs
  5. Publishes it at the URL associated with its slug

If the configuration does not match the application, the build can fail or the built application may fail to start.

Fields are defined at the top level unless shown as part of a nested block.

FieldDescriptionExample
slugApp identifier used as part of its URLmy-app
runtimeExecution environmentpython-slim, node-slim, go-slim
db.modeDatabase strategy; Managed SQLite or no platform databaselibsql, none

For an application with a web process, add command. A cron-only app can omit it and define crons instead. A static site can omit it and configure assets.

command: "python app.py"
FieldDescription
commandWeb process startup command, as a string or argument list
envNon-secret environment variables as key-value pairs
dbManaged SQLite choice and database-related configuration
cronsTime-triggered scheduled jobs
assetsStatic asset serving configuration
typeApp type; web enables static-site behavior

See the keelson.yaml reference for field types, constraints, and all supported values.

The combination of command and assets determines how an app is served.

PatterncommandassetsBehavior
Regular appPresentAbsentRuns as an application process
Static site or SPAAbsentPresentServes static files
HybridPresentPresentServes static files and a backend API

Every mode still declares runtime and db.mode, even when it does not use a platform-managed database.

Do not put API keys, tokens, passwords, or other secret values directly in keelson.yaml.

The file normally lives in the same repository as your source code. Add secret values through the console and declare secret requirements using the supported secrets configuration when needed. Use env only for non-sensitive values. Do not set PORT in env: Keelson injects the platform-assigned PORT, and your web server must read it when starting.

# Wrong: a secret value is committed with the app.
env:
OPENAI_API_KEY: "replace-with-a-real-key"
# Correct: configure OPENAI_API_KEY as a secret in the console.
env:
NODE_ENV: "production"

For details, see Environment Variables and Secrets.

The smallest useful web-app configuration declares slug, runtime, command, and the required database strategy. Use db.mode: none when the app does not need Keelson Managed SQLite.

slug: my-app
runtime: python-slim
command: "python app.py"
db:
mode: none
slug: my-app
runtime: node-slim
command: "npm start"
db:
mode: none
slug: my-app
runtime: go-slim
command: "./app"
db:
mode: none

Keelson builds the Go binary for Linux as ./app during deployment. Runtimes come in -slim variants for general applications and -media variants that include image and video processing libraries. Start with -slim unless the app needs those media libraries. For every runtime, declare dependencies in the project-root manifest (requirements.txt or pyproject.toml, package.json, or go.mod). Keelson installs them during the image build, so command must only start the already-built application. Each web app must listen on the injected PORT value.

Different kinds of apps use different optional fields.

Set db.mode: libsql to provision a managed database. Keelson injects its connection details as KEELSON_DB_URL and KEELSON_DB_AUTH_TOKEN.

slug: my-app
runtime: python-slim
command: "python app.py"
db:
mode: libsql

Local /data storage is ephemeral. Put durable records in Managed SQLite.

Set type: web and point assets at the built asset directory. Static sites still declare db.mode: none because they do not use Managed SQLite.

The deploy archive normally excludes .git, .venv, __pycache__, .pytest_cache, node_modules, dist, build, .idea, .vscode, and .DS_Store. Keelson CLI v0.1.1 and later exempt the declared assets.dir and its ancestors, so the dist example below is included. Exclusions still apply inside that directory (dist/node_modules/** remains excluded), and .git, symlinks, other non-regular files, and a file selected by --secrets-from-env-file are never archived. Run keelson version and upgrade before using dist or build with an older CLI.

slug: my-site
type: web
runtime: node-slim
db:
mode: none
assets:
dir: dist
fallback: index.html

A cron-only app can run a script on a schedule without starting a web server.

slug: daily-report
runtime: python-slim
db:
mode: none
crons:
- name: generate
schedule: "0 9 * * *"
command: "python report.py"
timeout: 120

A hybrid app serves a frontend and a backend API from one deployment.

slug: my-app
runtime: node-slim
command: "node server.js"
db:
mode: none
assets:
dir: public
fallback: index.html
api: /api

See the configuration examples in the keelson.yaml reference for complete patterns.