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.
What is keelson.yaml?
Section titled “What is keelson.yaml?”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.
Why is it required?
Section titled “Why is it required?”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.
How is it used during deployment?
Section titled “How is it used during deployment?”Keelson reads keelson.yaml when a deployment starts. It then:
- Validates the configuration, including field values and cross-field rules
- Builds the app for the selected runtime
- Starts it with the configured
command, when it has a web process - Prepares features such as Managed SQLite and scheduled jobs
- 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.
Main fields
Section titled “Main fields”Fields are defined at the top level unless shown as part of a nested block.
Required fields
Section titled “Required fields”| Field | Description | Example |
|---|---|---|
slug | App identifier used as part of its URL | my-app |
runtime | Execution environment | python-slim, node-slim, go-slim |
db.mode | Database strategy; Managed SQLite or no platform database | libsql, 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"Common fields
Section titled “Common fields”| Field | Description |
|---|---|
command | Web process startup command, as a string or argument list |
env | Non-secret environment variables as key-value pairs |
db | Managed SQLite choice and database-related configuration |
crons | Time-triggered scheduled jobs |
assets | Static asset serving configuration |
type | App type; web enables static-site behavior |
See the keelson.yaml reference for field types, constraints, and all supported values.
Deployment modes
Section titled “Deployment modes”The combination of command and assets determines how an app is served.
| Pattern | command | assets | Behavior |
|---|---|---|---|
| Regular app | Present | Absent | Runs as an application process |
| Static site or SPA | Absent | Present | Serves static files |
| Hybrid | Present | Present | Serves static files and a backend API |
Every mode still declares runtime and db.mode, even when it does not use a
platform-managed database.
What not to put in keelson.yaml
Section titled “What not to put in keelson.yaml”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.
Start with a minimal configuration
Section titled “Start with a minimal configuration”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.
Python
Section titled “Python”slug: my-appruntime: python-slimcommand: "python app.py"db: mode: noneNode.js
Section titled “Node.js”slug: my-appruntime: node-slimcommand: "npm start"db: mode: noneslug: my-appruntime: go-slimcommand: "./app"db: mode: noneKeelson 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.
Configurations by app type
Section titled “Configurations by app type”Different kinds of apps use different optional fields.
Web app with Managed SQLite (libSQL)
Section titled “Web app with Managed SQLite (libSQL)”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-appruntime: python-slimcommand: "python app.py"db: mode: libsqlLocal /data storage is ephemeral. Put durable records in Managed SQLite.
Static site or SPA
Section titled “Static site or SPA”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-sitetype: webruntime: node-slimdb: mode: noneassets: dir: dist fallback: index.htmlScheduled job
Section titled “Scheduled job”A cron-only app can run a script on a schedule without starting a web server.
slug: daily-reportruntime: python-slimdb: mode: nonecrons: - name: generate schedule: "0 9 * * *" command: "python report.py" timeout: 120Hybrid static files and API
Section titled “Hybrid static files and API”A hybrid app serves a frontend and a backend API from one deployment.
slug: my-appruntime: node-slimcommand: "node server.js"db: mode: noneassets: dir: public fallback: index.html api: /apiSee the configuration examples in the keelson.yaml reference for complete patterns.
Related pages
Section titled “Related pages”- keelson.yaml reference — field definitions, types, and constraints
- Supported App Types — examples of applications you can deploy
- Build and Runtime — build behavior and runtime details
- Storage and Data — durable data and Managed SQLite
- Scheduled Jobs — configuring cron jobs
- Environment Variables and Secrets — managing API keys and configuration values
- Deploy an App — the complete deployment flow