Settings reference
Every LAKANA_* environment variable of the server and the workers. A nested setting
joins its group and its name with two underscores: LAKANA_RUN__LEASE_SECONDS is the
lease_seconds of the run group. "Read by" names the component that reads the
variable; set a variable both read in the x-lakana-env block of the Compose file, which
the server and every worker share. How to set them: Deploy with
Compose.
LAKANA_DATABASE__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_DATABASE__URL |
text | required | server, worker | Address of the metadata database, for example postgresql+psycopg://lakana:PASSWORD@postgres/lakana. A password in it is hidden in logs and error messages. Required. |
LAKANA_DATABASE__ECHO |
true or false | false |
server, worker | Whether every SQL statement sent to the metadata database is written to the log. Off by default; turn it on only while you look for a problem, because it is very verbose. |
General
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_BOOTSTRAP_ADMIN |
text | admin |
server, worker | Name of the administrator created the first time the server starts, if no principal of that name exists. Its credential is supplied (LAKANA_BOOTSTRAP_PAT_KEY_ID) or written to LAKANA_BOOTSTRAP_TOKEN_FILE, never logged. Change it only before the first start. |
LAKANA_BOOTSTRAP_PAT_KEY_ID |
text | not set | server | The key id half of a fixed credential for the bootstrap administrator, for tests and local development; set it together with LAKANA_BOOTSTRAP_PAT_SECRET. Unset (the default), a random credential is created at the first start and written to LAKANA_BOOTSTRAP_TOKEN_FILE. A key id an earlier token already used stops the start-up. The Compose bundle sets both in its .env file. |
LAKANA_BOOTSTRAP_PAT_SECRET |
text | not set | server | The secret half of a fixed credential for the bootstrap administrator; set it together with LAKANA_BOOTSTRAP_PAT_KEY_ID. Unset (the default), a random credential is created at the first start and written to LAKANA_BOOTSTRAP_TOKEN_FILE. Treat it like a password. |
LAKANA_BOOTSTRAP_TOKEN_FILE |
path | not set | server | Where the server writes the token of a first administrator it had to create without a supplied credential: a new file, mode 0600, never overwritten (an existing file stops the start-up; remove it after use). The server logs this path, never the token. No default, because the server has no data directory of its own; required only in that case, where start-up fails naming this setting if it is unset. Not used when LAKANA_BOOTSTRAP_PAT_KEY_ID is set. |
LAKANA_HOST |
text | 127.0.0.1 |
server | Address the server listens on. 127.0.0.1 (the default) accepts connections from this machine only; the Compose bundle publishes the port through LAKANA_BIND. |
LAKANA_PORT |
whole number | 8000 |
server | Port the server listens on (default 8000). |
LAKANA_REPO_ROOTS |
list | empty | server, worker | Absolute directories that local repositories must lie under, as a JSON list, for example ["/repos"]. Empty (the default) refuses every local repository. |
LAKANA_SECRETS__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_SECRETS__MASTER_KEY |
text | not set | server, worker | The key that protects every stored secret: 32 random bytes, base64-encoded. Unset (the default), the instance starts but no secret can be created or read. The Compose bundle generates one. Keep it safe: a lost key makes every stored secret unrecoverable. Set the same value on the server and on every worker. |
LAKANA_SECRETS__ACCEPT_FORMAT_1 |
true or false | false |
server, worker | Whether to read secrets stored in the old format, written by a release before a secret was bound to its row. false (the default) refuses such a secret with a message that says how to set it again. true reads them, and the server and the worker log a warning at start while it is on. Turn it on, on the server and on every worker, only while you set old secrets again, and remove it afterwards. |
LAKANA_TASK_TOKENS__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_TASK_TOKENS__MAX_TTL_SECONDS |
whole number, above 0 | 86400 |
server, worker | Longest lifetime, in seconds, that can be requested for a task token. A task token is the temporary credential a Python task uses to call Lakana. The default is one day. Lower it to shorten the time a leaked token would work. The server and the worker both read it; set the same value on both. |
LAKANA_ARTIFACTS__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_ARTIFACTS__MAX_FILE_BYTES |
whole number, above 0 | 2147483648 |
server, worker | Largest single file of an artifact version (default 2 GiB). |
LAKANA_ARTIFACTS__MAX_BYTES |
whole number, above 0 | 10737418240 |
server, worker | Largest total size of one artifact version (default 10 GiB). |
LAKANA_ARTIFACTS__MAX_FILES |
whole number, above 0 | 10000 |
server, worker | Most files in one artifact version (default 10,000). |
LAKANA_ARTIFACTS__UPLOAD_TTL_SECONDS |
whole number, above 0 | 3600 |
server, worker | How long an open upload may stay uncommitted, and how long a commit of it can be repeated (default one hour). |
LAKANA_TABLES__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_TABLES__UNDO_DAYS |
whole number, 0 or more, 365 or less | 7 |
server, worker | Days a dropped managed table keeps its files and can be restored with lakana table undrop (default 7; 0 to 365). After that the worker's sweep deletes its files, at the latest one sweep (LAKANA_RUN__SWEEP_INTERVAL) later. 0 deletes them at the next sweep and allows no undrop. A drop with --purge ignores it. Each drop records its own end of the period, so a change applies to later drops only. The workers read it too, for the tables they drop because their retention has passed, which keep at least one day; set the same value for the server and every worker. |
LAKANA_TABLES__EXPIRY_WARNING_DAYS |
whole number, 0 or more, 3650 or less | 7 |
server | Days ahead lakana table list and lakana table get warn that a table expires because of its retention, and the default window of lakana table expiring (default 7; 0 to 3,650). 0 turns the warning off. |
LAKANA_TABLES__ABANDONED_GRACE_HOURS |
whole number, 1 or more, 8760 or less | 24 |
worker | Hours a create that did not finish, and was not made by a pipeline run, keeps its storage location before the worker's sweep removes the files it left (default 24; 1 to 8,760). A create made by a run keeps it until that run has ended. The sweep runs every LAKANA_RUN__SWEEP_INTERVAL seconds and never removes a table that exists. Raise it if a create can take longer than a day. |
LAKANA_TABLES__MAX_EXPIRIES_PER_SWEEP |
whole number, 1 or more, 10000 or less | 100 |
worker | The most tables one sweep drops because their retention has passed (default 100; 1 to 10,000), the most overdue first; the rest follow at the next sweep. It bounds what one mistaken retention can remove at once, so lower it if that worries you. |
LAKANA_TABLE_READS__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_TABLE_READS__KEEP_DAYS |
whole number, 1 or more | 90 |
server, worker | Days of read counts kept for each table (default 90). A worker deletes older counts, and the health of a table can look back at most this many days. |
LAKANA_TABLE_READS__DEFAULT_DAYS |
whole number, 1 or more | 30 |
server, worker | Days of reads that the health of a table shows when the request names none (default 30); at most LAKANA_TABLE_READS__KEEP_DAYS. |
LAKANA_APPEND__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_APPEND__MAX_BYTES |
whole number, above 0 | 268435456 |
server | Largest body, in bytes, of one table append (default 256 MiB). A larger request is refused with 413 before the rest of the body is read, and nothing is written. |
LAKANA_APPEND__MAX_CONCURRENT |
whole number, above 0 | 4 |
server | Most appends and artifact uploads one server process receives at once (default 4). A request past the limit is refused at once with 503 and a hint to retry; the SDK asks again. |
LAKANA_APPEND__READ_TIMEOUT_SECONDS |
number, above 0 | 300 |
server | How long the server waits for the body of a request, in seconds (default 300). For a table append, the whole body; for an artifact upload, the next piece of a file and the whole manifest request. A request past the limit is refused with 408 and nothing is written. It stops a slow or stalled client from holding a slot. |
LAKANA_APPEND__MAX_ARRAYS |
whole number, above 0 | 100000 |
server | Most columns, summed over all batches, that the data of one append may hold (default 100,000). Many tiny batches use much memory and processor time even in a small body. A request over the limit is refused with 413; send fewer, larger batches. |
LAKANA_REQUEST_BODY__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_REQUEST_BODY__MAX_BYTES |
whole number, above 0 | 1048576 |
server | Largest body, in bytes, the server accepts on a route whose body is JSON; a larger one is answered 413 before anything is parsed, and before the caller is authenticated. The default (1 MiB) is far above any ordinary request: a 100,000-character SQL statement of ASCII characters is under 0.6 MiB as JSON even with every character escaped. A character outside the Basic Multilingual Plane takes up to 12 bytes escaped, so a statement made of those can pass 1 MiB (raise this setting if you send such SQL). Routes that stream a body on purpose (table data, artifact files and manifests) are not counted: they have their own limits. |
LAKANA_AUTH_AUDIT__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_AUTH_AUDIT__PER_IP_PER_MINUTE |
whole number, above 0 | 10 |
server | Failed sign-ins that the audit log records per client per minute (default 10). Requests past the rate are still refused with 401, but not each recorded, so repeated attempts cannot flood the log. |
LAKANA_DENIAL_AUDIT__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_DENIAL_AUDIT__PER_PRINCIPAL_PER_MINUTE |
whole number, above 0 | 30 |
server, worker | Most refusals the audit log records for one principal per minute, in each server and each worker. A refusal past the limit is still refused, but not recorded; the next row recorded for that principal says how many were left out, and each one is written to the process log. The first refusal of each action by a principal is always recorded. Raise it if you need every refusal in the table. |
LAKANA_VIEW_AUDIT__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_VIEW_AUDIT__ENABLED |
true or false | true |
server | Record an ACTIVITY_VIEWED event when someone sees other people's activity: a manager's listing of other people's queries (lakana query list), the readers of a table (lakana table health) and a page of the audit log with other people's events (lakana audit list) (default true). If the event cannot be written, the read is refused with 503. Turn it off only if you do not need to know who looked at whose activity. |
LAKANA_VIEW_AUDIT__WINDOW_MINUTES |
whole number, 1 or more, 1440 or less | 60 |
server | Minutes during which the same view by the same person writes no second event (default 60; 1 to 1,440). The next page, another status filter and a screen that refreshes itself are the same view; another environment, another table, another --submitter or another --principal-id is another view. |
LAKANA_AUDIT__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_AUDIT__QUERY_TEXT |
text | full |
server, worker | What a new QUERY_COMPLETED event stores of the query's SQL text: full (the default) the text; hash only its SHA-256 and length, so that the same query can still be recognised; off neither. In any letter case. Set the same value on the server and on every worker, since both record queries. Events already written are not changed. The query's own record keeps its text either way, for its submitter. |
LAKANA_AUDIT__SIGN_IN_WINDOW_MINUTES |
whole number, 0 or more, 1440 or less | 15 |
server | Minutes during which a token that signed in successfully writes no second sign-in event (default 15; 0 to 1,440). The next event of that token says how many sign-ins were left out. Each token counts on its own, and its first use always writes an event, as does its first use after it was refused. 0 writes an event for every request. Each server process counts on its own. Failed sign-ins are not affected (LAKANA_AUTH_AUDIT__PER_IP_PER_MINUTE). |
LAKANA_QUERY_LIMITS__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_QUERY_LIMITS__MAX_RESULT_ROWS |
whole number, above 0 | 1000000 |
server, worker | Most rows a query may return. Exceeding it fails the query; the result is never truncated. |
LAKANA_QUERY_LIMITS__MAX_RESULT_BYTES |
whole number, above 0 | 268435456 |
server, worker | Most bytes a query result may take in memory. A result over the limit fails the query. It protects the worker from running out of memory; the check happens between batches of rows, so a result can pass the limit by a little before it is stopped. |
LAKANA_QUERY_LIMITS__MEMORY_LIMIT |
text | 1GB |
server, worker | Memory one query may use, written as DuckDB writes sizes, for example 1GB or 512MiB. Some operations go beyond it. Keep it well below the memory limit of the worker. |
LAKANA_QUERY_LIMITS__MAX_WRITE_ROWS |
whole number, above 0 | 100000000 |
server, worker | Most rows one write run may write. A run that passes it fails and removes every file it wrote. |
LAKANA_QUERY_LIMITS__TIMEOUT_SECONDS |
number, above 0 | 900 |
server, worker | Longest one query may run, in seconds. For a write it includes the time to store the result, so a slow object store can fail a write with the time-limit message. At the limit the worker asks the query to stop and, after the grace period of LAKANA_QUERY_LIMITS__KILL_GRACE_SECONDS, ends it. |
LAKANA_QUERY_LIMITS__KILL_GRACE_SECONDS |
number, 0 or more | 10 |
server, worker | Seconds between asking a query to stop (its time limit, a cancel, the worker's drain) and killing its process. 0 kills at once; it must be a finite number. A query that stops when asked ends with DuckDB's own clean error; one that had to be killed after its time limit or a cancel request says so in its message (a task's cancel and the worker's drain only log it). |
LAKANA_QUERY_LIMITS__THREADS |
whole number, above 0 | 4 |
server, worker | Processor threads one query may use, so that one query cannot take every core of the worker. |
LAKANA_QUERY_LIMITS__MAX_TEMP_DIRECTORY_SIZE |
text | 10GB |
server, worker | Disk a query may use for temporary files when it needs more than its memory limit, written as DuckDB writes sizes, for example 10GB. Only local file storage allows it; with every other storage a query over its memory limit fails instead of using disk. |
LAKANA_QUERY_LIMITS__MAX_STATEMENT_CHARS |
whole number, above 0 | 100000 |
server, worker | Longest SQL text, in characters, that is accepted: a submitted query or write, a row filter or column mask expression, and a SQL asset at deploy. A longer text is refused with a message that names this setting. The default is far above any statement written by hand. |
LAKANA_QUERY_LIMITS__RUNNING_PER_PRINCIPAL |
whole number or auto |
auto |
server, worker | The most ad-hoc queries one user or service account runs at once, over every environment: auto or a whole number of 1 or more. A further query waits and is not refused. With auto, one principal may run ad-hoc queries on every worker that takes interactive work while there are one or two such workers, and on all of them but one from three on. Pipeline work is never counted. The server reads it too, for the reason a query waits. |
LAKANA_RUN__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_RUN__MAX_RETRIES |
whole number, 0 or more | 5 |
server, worker | Most retries a project may configure for one asset; deploy validation refuses more. |
LAKANA_RUN__SCHEDULER_INTERVAL_SECONDS |
number, above 0 | 1 |
server, worker | How often, in seconds, the worker that holds the scheduler role checks for work that is ready, retries that are due, lost workers and cancellations. |
LAKANA_RUN__LEASE_SECONDS |
whole number, above 0 | 60 |
server, worker | How long, in seconds, a claimed task stays with its worker without the worker renewing the claim; after that another worker may take it. |
LAKANA_RUN__RENEW_SECONDS |
whole number, above 0 | 20 |
server, worker | How often, in seconds, a worker renews its claim on a task. It must be below LAKANA_RUN__LEASE_SECONDS. |
LAKANA_RUN__DRAIN_GRACE_SECONDS |
number, 0 or more | 20 |
server, worker | When a worker is asked to stop, how many seconds a running task may take to finish before the task is handed to another worker. |
LAKANA_RUN__SERVER_URL |
text | not set | server, worker | Base URL of the Lakana server as a Python task's subprocess reaches it. Unset, this worker cannot run Python assets. |
LAKANA_RUN__VENV_CACHE |
path | not set | server, worker | Absolute path of the directory that keeps the Python environments of projects. Unset, the worker uses its own cache directory. |
LAKANA_RUN__VENV_KEEP |
whole number, 1 or more | 10 |
server, worker | How many venvs to keep, most recently used first. |
LAKANA_RUN__VENV_BUILD_TIMEOUT |
number, above 0 | 600 |
server, worker | Longest, in seconds, that building the Python environment of a project may take. |
LAKANA_RUN__VENV_MAX_BYTES |
whole number, above 0 | 5368709120 |
server, worker | Largest on-disk size of one venv while it is built. |
LAKANA_RUN__KILL_GRACE |
number, 0 or more | 10 |
server, worker | Seconds between asking a Python task to stop and ending its process by force. |
LAKANA_RUN__SWEEP_INTERVAL |
number, 0 or more | 3600 |
server, worker | Seconds between the worker's sweeps of attempt directories a dead worker left behind (also at worker start), and between the sweeps that the worker holding the scheduler role runs of the artifact store (expired uploads, files and manifest objects no version names) and of table locations (the files of creates that never finished); 0 turns them off, and then nothing collects those leftovers. |
LAKANA_RUN__MAINTENANCE_TIMEOUT |
number, above 0 | 1800 |
server, worker | Seconds one lakana table maintain run may take. The worker checks the time between steps and between files, stops at the first safe point, and fails the run with the timeout cause; running maintenance again continues where it stopped. |
LAKANA_RUN__INDEX_URL |
secret text | not set | server, worker | An extra package index for building the environment of a Python project, as a URL. It may carry a password, which is hidden in logs and error messages. |
LAKANA_RUN__HTTPS_PROXY |
secret text | not set | server, worker | Proxy that the environment build uses, as a URL. It may carry a password, which is hidden in logs and error messages. |
LAKANA_RUN__NO_PROXY |
text | not set | server, worker | Comma-separated hosts that bypass the proxy. |
LAKANA_RUN__CA_BUNDLE |
path | not set | server, worker | Absolute path of a PEM file of certificate authorities that the environment build trusts, for an internal package index. The file must exist and be readable on the worker. |
LAKANA_LOG__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_LOG__LEVEL |
text | INFO |
server, worker | DEBUG, INFO, WARNING or ERROR, in any letter case. Lakana's own log lines and the server's are printed from this level up; other libraries only from WARNING. Above INFO, refusals past the audit rate leave no line in the log, only the summary row in the audit log. The request log, one line per request, is printed at INFO and DEBUG only. |
LAKANA_LOG__ACCESS |
true or false | true |
server, worker | Whether the server logs every request, one line each. On by default; lakana server start --local turns it off unless you pass --log-requests. Nothing else in the log changes. |
LAKANA_CI_OIDC__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_CI_OIDC__ISSUERS |
list | empty | server | The CI providers whose ID tokens the server accepts, as a comma-separated list or a JSON list: github (GitHub Actions), gitlab (GitLab.com) or the https URL of a self-hosted GitLab, exactly as its tokens name it (no trailing slash). Empty (the default) turns CI OIDC off. |
LAKANA_CI_OIDC__AUDIENCE |
text | not set | server | The audience the CI ID tokens must be issued for, usually this server's public URL, for example https://lakana.example; request the token for the same value in CI. Required when LAKANA_CI_OIDC__ISSUERS is set. |
LAKANA_CI_OIDC__ALGORITHMS |
list | ['RS256'] |
server | The signature algorithms accepted, as a list; RS256 (the default) is what GitHub and GitLab use. Only RS256, RS384, RS512, PS256, PS384 and PS512 are supported; none and the HMAC algorithms (HS256 and the like) are refused. |
LAKANA_CI_OIDC__MAX_TOKEN_AGE_SECONDS |
whole number, 60 or more, 3600 or less | 900 |
server | The oldest ID token accepted, counted from its issue time (default 900, 15 minutes). |
LAKANA_CI_OIDC__ALLOW_HOSTS |
list | empty | server | Host names, comma-separated, exact names only. A listed host may serve an issuer's keys when its discovery document names another host than the issuer's own, and a listed host may resolve to a private address (10.x, 172.16.x to 172.31.x, 192.168.x, fd00::/8); every other host must be public. A self-hosted GitLab on an internal network therefore needs its URL in LAKANA_CI_OIDC__ISSUERS and its host name here. Loopback, link-local and cloud metadata addresses are refused even for a listed host. List only names whose DNS you control. |
LAKANA_CI_OIDC__PROXY |
secret text | not set | server | URL of the proxy that the discovery and key requests go through, for example http://user:password@host:3128. The server checks the destination name, but the proxy looks it up again, so the proxy must refuse internal addresses itself. A password is hidden in logs and error messages. |
LAKANA_CI_OIDC__CA_BUNDLE |
path | not set | server | Absolute path of a PEM file of certificate authorities that the discovery and key requests trust; it replaces the built-in store and never turns verification off. |
LAKANA_GIT__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_GIT__HTTPS_PROXY |
secret text | not set | worker | URL of the proxy that git uses for HTTPS repositories, for example http://user:password@host:3128; a username needs a password, and both are percent- encoded. A password is hidden in logs and error messages. |
LAKANA_GIT__NO_PROXY |
text | not set | worker | Comma-separated hosts, domains or CIDRs that bypass the proxy. |
LAKANA_GIT__CA_BUNDLE |
path | not set | worker | Absolute path of a PEM file of certificate authorities that git trusts for HTTPS; it replaces the system store. The file must exist and be readable on the worker. |
LAKANA_WEBHOOK__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_WEBHOOK__ALLOW_HOSTS |
text | not set | worker | Comma-separated host names, or *.domain for every subdomain of a domain (not the domain itself), that skip the address check and may use http and any port. Matching ignores case and a trailing dot. For an internal chat server. |
LAKANA_WEBHOOK__PROXY |
secret text | not set | worker | URL of the proxy that webhooks go through, for example http://user:password@host:3128. The worker checks the destination name, but the proxy looks it up again, so the proxy must refuse internal addresses itself. A password is hidden in logs and error messages. |
LAKANA_WEBHOOK__CA_BUNDLE |
path | not set | worker | Absolute path of a PEM file of certificate authorities that webhooks trust; it replaces the built-in store and never turns verification off. The file must exist and be readable on the worker. |
LAKANA_WORKER__*
| Variable | Type | Default | Read by | Description |
|---|---|---|---|---|
LAKANA_WORKER__MEMORY_LIMIT |
text | not set | worker | The most memory the worker may use in all, with the Python tasks and uv it started, for example 4GB (at least 512MB; off or 0 for none). Units are binary: GB and g mean 1024 MB, unlike LAKANA_QUERY_LIMITS__MEMORY_LIMIT, where GB is decimal. A worker over the limit ends its tasks, records why and stops; Docker or the local-mode supervisor restarts it. Unset, the worker uses 90 percent of its container's memory limit, or 4GB without one. Linux measures the worker and what it started; macOS only the worker; Windows nothing. |
LAKANA_WORKER__NOTIFICATIONS |
true or false | true |
worker | Whether this worker delivers job notifications (LAKANA_WORKER__NOTIFICATIONS, on by default). Set to false on a worker that must not reach the webhook hosts (a worker in a network without outbound access); another worker delivers them. With no worker delivering, queued notifications wait. |
LAKANA_WORKER__TAKES |
text | all |
worker | The work this worker takes (LAKANA_WORKER__TAKES): "all" (the default), "interactive" (ad-hoc queries) or "pipeline" (deploys, pipeline tasks and table maintenance), in any letter case. The worker says it when it registers. |