Skip to main content

Overview

TrailBase uses a combination of configuration files, environment variables, and CLI flags to manage settings. Configuration is stored in the data directory (default: ./traildepot/) using protobuf text format.

Configuration Files

config.textproto

The main configuration file located at <data-dir>/config.textproto. This file stores non-sensitive configuration in a human-readable protobuf text format.
If config.textproto doesn’t exist when TrailBase starts, it will be automatically created with default values.
Location: <data-dir>/config.textproto Example:
# Auto-generated config.Config textproto

server {
  application_name: "TrailBase"
  site_url: "https://example.com"
  logs_retention_sec: 604800  # 7 days
}

auth {
  auth_token_ttl_sec: 3600      # 1 hour
  refresh_token_ttl_sec: 2592000 # 30 days
  
  oauth_providers {
    key: "google"
    value {
      provider_id: OAUTH_PROVIDER_ID_GOOGLE
      client_id: "your-client-id"
      client_secret: "<REDACTED>"
    }
  }
}

email {
  smtp_host: "smtp.gmail.com"
  smtp_port: 587
  smtp_username: "[email protected]"
  smtp_password: "<REDACTED>"
  smtp_encryption: SMTP_ENCRYPTION_STARTTLS
  sender_address: "[email protected]"
  sender_name: "TrailBase"
}

record_apis {
  name: "posts"
  table_name: "posts"
  # ... additional API configuration
}

secrets.textproto

Sensitive configuration is automatically extracted and stored in <data-dir>/secrets/secrets.textproto. This file contains secrets that are referenced in config.textproto using the <REDACTED> placeholder. Location: <data-dir>/secrets/secrets.textproto Example:
# Auto-generated config.Vault textproto

secrets {
  key: "TRAIL_EMAIL_SMTP_PASSWORD"
  value: "actual-smtp-password"
}

secrets {
  key: "TRAIL_AUTH_OAUTH_PROVIDERS_GOOGLE_CLIENT_SECRET"
  value: "actual-oauth-secret"
}
Never commit secrets.textproto to version control. The data directory includes a .gitignore that excludes the secrets/ directory by default.

Configuration Hierarchy

Configuration is resolved in the following order (later sources override earlier ones):
  1. Base configuration - config.textproto
  2. Secrets - secrets.textproto (merged into fields marked as <REDACTED>)
  3. Environment variables - TRAIL_* prefixed variables
  4. CLI flags - Command-line arguments

Data Directory Structure

When TrailBase initializes, it creates the following directory structure:
traildepot/
├── data/
│   ├── main.db          # Main SQLite database
│   ├── logs.db          # Logs database
│   └── queue.db         # Job queue database
├── secrets/
│   ├── secrets.textproto # Secrets vault
│   └── keys/            # Encryption keys
├── migrations/
│   └── main/            # User migrations for main database
├── backups/             # Database backups
├── uploads/             # User-uploaded files
├── wasm/                # WASM components
├── config.textproto     # Main configuration
├── metadata.textproto   # Runtime metadata
└── .gitignore           # Excludes sensitive directories

Environment Variables

Configuration Environment Variables

All configuration fields can be overridden using environment variables with the TRAIL_ prefix. The naming convention follows the configuration structure: Format: TRAIL_<SECTION>_<FIELD>
# Server settings
export TRAIL_SERVER_APPLICATION_NAME="MyApp"
export TRAIL_SERVER_SITE_URL="https://example.com"
export TRAIL_SERVER_LOGS_RETENTION_SEC="604800"

CLI Environment Variables

CLI options can also be set via environment variables:
export DATA_DIR="/var/lib/trailbase"
export PUBLIC_URL="https://example.com"
export ADDRESS="0.0.0.0:4000"
export ADMIN_ADDRESS="localhost:4001"
export PUBLIC_DIR="/var/www/static"
export SPA="true"
export RUNTIME_ROOT_FS="/var/lib/trailbase/fs"
export GEOIP_DB_PATH="/var/lib/geoip/GeoLite2-City.mmdb"
export CORS_ALLOWED_ORIGINS="https://example.com,https://www.example.com"
export RUNTIME_THREADS="4"

Configuration Sections

Server Configuration

server.application_name
string
default:"TrailBase"
Application name displayed in UI and emails. Must contain only alphanumeric characters, spaces, or _, -, ..Environment variable: TRAIL_SERVER_APPLICATION_NAME
server.site_url
string
Public site URL. Required for OAuth redirects and email links.Environment variable: TRAIL_SERVER_SITE_URL
server.logs_retention_sec
integer
default:"604800"
Logs retention period in seconds. Default is 7 days (604800 seconds).Environment variable: TRAIL_SERVER_LOGS_RETENTION_SEC

Auth Configuration

auth.auth_token_ttl_sec
integer
default:"3600"
Authentication token time-to-live in seconds. Default is 1 hour (3600 seconds) in production, 2 minutes in debug builds.Environment variable: TRAIL_AUTH_AUTH_TOKEN_TTL_SEC
auth.refresh_token_ttl_sec
integer
default:"2592000"
Refresh token time-to-live in seconds. Default is 30 days (2592000 seconds).Environment variable: TRAIL_AUTH_REFRESH_TOKEN_TTL_SEC
auth.oauth_providers
map<string, OAuthProviderConfig>
Map of OAuth provider configurations. Keys are provider names, values are provider configurations.
OAuth Provider Configuration:
provider_id
enum
required
OAuth provider type:
  • OAUTH_PROVIDER_ID_GOOGLE - Google OAuth
  • OAUTH_PROVIDER_ID_GITHUB - GitHub OAuth
  • OIDC0 - Generic OpenID Connect
client_id
string
required
OAuth client ID from the provider.Environment variable: TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_CLIENT_ID
client_secret
string
required
OAuth client secret from the provider. Automatically moved to secrets vault.Environment variable: TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_CLIENT_SECRET
auth_url
string
Authorization URL (required for OIDC0 provider).Environment variable: TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_AUTH_URL
token_url
string
Token exchange URL (required for OIDC0 provider).Environment variable: TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_TOKEN_URL
user_api_url
string
User info API URL (required for OIDC0 provider).Environment variable: TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_USER_API_URL

Email Configuration

email.smtp_host
string
SMTP server hostname. If not provided, TrailBase falls back to system’s sendmail.Environment variable: TRAIL_EMAIL_SMTP_HOST
email.smtp_port
integer
SMTP server port (typically 587 for STARTTLS, 465 for SSL).Environment variable: TRAIL_EMAIL_SMTP_PORT
email.smtp_username
string
SMTP authentication username.Environment variable: TRAIL_EMAIL_SMTP_USERNAME
email.smtp_password
string
SMTP authentication password. Automatically moved to secrets vault.Environment variable: TRAIL_EMAIL_SMTP_PASSWORD
email.smtp_encryption
enum
SMTP encryption method:
  • SMTP_ENCRYPTION_NONE (0) - No encryption
  • SMTP_ENCRYPTION_STARTTLS (1) - STARTTLS
  • SMTP_ENCRYPTION_SSL (2) - SSL/TLS
Environment variable: TRAIL_EMAIL_SMTP_ENCRYPTION
email.sender_address
string
Email address to use as sender. If not set, defaults to noreply@<host>.Environment variable: TRAIL_EMAIL_SENDER_ADDRESS
email.sender_name
string
Display name for the sender.Environment variable: TRAIL_EMAIL_SENDER_NAME

Email Templates

Email templates support variable substitution:
  • {{ VERIFICATION_URL }} - Full verification link
  • {{ CODE }} - Verification code only
email.user_verification_template
EmailTemplate
Template for user email verification emails.
email.change_email_template
EmailTemplate
Template for email change confirmation emails.
email.password_reset_template
EmailTemplate
Template for password reset emails.
EmailTemplate structure:
email {
  user_verification_template {
    subject: "Verify your email"
    body: "Click here to verify: {{ VERIFICATION_URL }}"
  }
}

Database Configuration

databases
repeated DatabaseConfig
Additional databases to attach. Main and logs databases are always attached.
DatabaseConfig structure:
name
string
required
Database name. Must be alphanumeric with _ or -. Cannot be “main”, “logs”, or empty.Environment variable: TRAIL_DATABASES_<INDEX>_NAME

Record APIs Configuration

record_apis
repeated RecordApiConfig
Configuration for table-based REST APIs.
RecordApiConfig structure:
name
string
required
API endpoint name.
table_name
string
required
Database table name.

JSON Schema Configuration

schemas
repeated JsonSchemaConfig
Custom JSON schemas for validation.
JsonSchemaConfig structure:
name
string
required
Schema identifier.
schema
string
required
JSON Schema definition (as string).

Job Configuration

jobs.system_jobs
repeated JobConfig
Scheduled system jobs using cron syntax.
JobConfig structure:
id
string
required
Unique job identifier.
schedule
string
required
Cron expression (e.g., 0 0 * * * for daily at midnight).

Runtime Options

These options are set via CLI flags and cannot be changed via configuration files:
--data-dir
string
default:"./traildepot"
Base directory for all TrailBase data. Requires server restart to change.
--public-url
string
Public URL for external access. Requires server restart to change.
--address
string
default:"localhost:4000"
Server bind address. Requires server restart to change.
--admin-address
string
Separate admin interface address. Requires server restart to change.
--runtime-threads
integer
WASM runtime thread pool size. Requires server restart to change.
A good rule of thumb: if a setting requires a server restart, it should be a CLI option. Otherwise, it should be in the config file.

Configuration Validation

TrailBase validates configuration on startup and when updating via the admin API. Validation checks:
  • Application name: Alphanumeric characters, spaces, _, -, . only
  • URLs: Valid URL format for site_url, OAuth URLs
  • Email addresses: Valid email format for sender addresses
  • Database names: Alphanumeric with _ or -, not reserved names
  • API names: Unique across all configured APIs
  • OAuth providers: Required fields present, valid provider IDs
  • Cron schedules: Valid cron syntax
  • JSON schemas: Valid JSON Schema format

Editing Configuration

Via Admin UI

The admin interface provides a configuration editor:
  1. Navigate to Admin → Configuration
  2. Edit the configuration in the text editor
  3. Save changes
  4. Configuration is validated before saving

Via Text Editor

  1. Stop the TrailBase server
  2. Edit <data-dir>/config.textproto
  3. For secrets, edit <data-dir>/secrets/secrets.textproto
  4. Start the server (configuration is validated on startup)

Via Environment Variables

Set environment variables before starting the server:
export TRAIL_SERVER_APPLICATION_NAME="MyApp"
export TRAIL_EMAIL_SMTP_PASSWORD="secret-password"
trail run

Secrets Management

How Secrets Work

  1. Writing: When you set a secret field in config.textproto, TrailBase extracts it to secrets.textproto and replaces it with <REDACTED>
  2. Reading: On startup, TrailBase merges secrets back into the configuration
  3. Environment override: Environment variables override both config and secrets

Secret Fields

The following fields are automatically treated as secrets:
  • email.smtp_password
  • auth.oauth_providers.*.client_secret
  • Any field marked with [(secret) = true] in the protobuf definition

Rotating Secrets

# Option 1: Edit secrets file
vim ./traildepot/secrets/secrets.textproto
# Update TRAIL_EMAIL_SMTP_PASSWORD value

# Option 2: Use environment variable
export TRAIL_EMAIL_SMTP_PASSWORD="new-password"
trail run
# Edit secrets file
vim ./traildepot/secrets/secrets.textproto
# Update TRAIL_AUTH_OAUTH_PROVIDERS_<PROVIDER>_CLIENT_SECRET

# Or use environment variable
export TRAIL_AUTH_OAUTH_PROVIDERS_GOOGLE_CLIENT_SECRET="new-secret"
trail run

Configuration Examples

Minimal Configuration

server {
  application_name: "MyApp"
}

Production Configuration

server {
  application_name: "Production App"
  site_url: "https://app.example.com"
  logs_retention_sec: 2592000  # 30 days
}

auth {
  auth_token_ttl_sec: 3600
  refresh_token_ttl_sec: 2592000
  
  oauth_providers {
    key: "google"
    value {
      provider_id: OAUTH_PROVIDER_ID_GOOGLE
      client_id: "123456789-abcdefghijklmnop.apps.googleusercontent.com"
      client_secret: "<REDACTED>"
    }
  }
}

email {
  smtp_host: "smtp.sendgrid.net"
  smtp_port: 587
  smtp_username: "apikey"
  smtp_password: "<REDACTED>"
  smtp_encryption: SMTP_ENCRYPTION_STARTTLS
  sender_address: "[email protected]"
  sender_name: "My App"
}

Development Configuration

# Use environment variables for development
export TRAIL_SERVER_APPLICATION_NAME="Dev Server"
export TRAIL_EMAIL_SMTP_HOST="localhost"
export TRAIL_EMAIL_SMTP_PORT="1025"
export TRAIL_EMAIL_SMTP_ENCRYPTION="0"

trail run --dev --address localhost:3000

Build docs developers (and LLMs) love