SPACEPORT DOCS

Spaceport Manifest Configuration File

The manifest file is Spaceport's central configuration file, defining how your application starts, where it finds resources, and how it connects to services like CouchDB. By convention, this file is named config.spaceport and lives in your project root.

The manifest can be written in either YAML or JSON format. Throughout this documentation, we use YAML for its human-readability—the format was chosen specifically to make configuration clear and maintainable. YAML's whitespace-based structure eliminates visual noise, making it easy to scan and understand your application's settings at a glance.

# Starting Without a Manifest

For rapid prototyping or simple scripts, you can skip the manifest file entirely using the --no-manifest flag:

java -jar spaceport.jar --start --no-manifest

When started this way, Spaceport uses its built-in defaults:

This mode is excellent for learning Spaceport or testing ideas quickly, but production applications should use an explicit manifest to control behavior precisely.

Note: With --no-manifest, debug mode is enabled by default. This means hot-reloading is active but also means your application isn't optimized for production. Always use a manifest file with debug: false for deployed applications.

# The Default Manifest

Here's what Spaceport's complete default configuration looks like:

# config.spaceport - Default Configuration

# Application identity (defaults to current directory name)
spaceport name: my-project

# Project root (defaults to current working directory)
spaceport root: /path/to/my-project

# Server binding
host:
  address: 127.0.0.1
  port: 10000

# Database connections
memory cores:
  main:
    type: couchdb
    address: http://127.0.0.1:5984

# Application logging
logging:
  enabled: false
  path: log/

# Source module loading
source modules:
  paths:
    - modules/*

# Static file serving
static assets:
  paths:
    /assets/ : assets/*

# JAR dependencies
stowaways:
  enabled: true
  paths:
    - stowaways/*

# Development mode
debug: true

## Configuration Merging

Your config.spaceport file merges into the default configuration rather than replacing it. This means you only need to specify what you want to change—everything else inherits from the defaults.

For example, if you only want to change the port and enable logging:

# Minimal config.spaceport
host:
  port: 3000

logging:
  enabled: true

The result is your values merged over the defaults—you get port 3000 with logging enabled, while host.address remains 127.0.0.1, memory cores keeps its default CouchDB connection, and all other settings stay intact.

This merge behavior applies at every level of nesting. If you specify host.port, you don't lose host.address. If you add a username to your memory core, the existing type and address remain:

memory cores:
  main:
    username: admin
    password: my-secure-password

This merges with the default main core, resulting in a complete configuration with type, address, username, and password all present.

# Core Configuration Sections

Each section of the manifest controls a specific aspect of your Spaceport application.

## Application Identity

spaceport name: my-application
spaceport root: /var/www/my-application

## Host Settings

Control how Spaceport binds to the network:

host:
  address: 127.0.0.1
  port: 10000

## Debug Mode

Toggle development features:

debug: true

When debug is true:

For production, always set debug: false.

## Memory Cores

Configure database connections. Spaceport uses the term "memory cores" for its data storage backends:

memory cores:
  main:
    type: couchdb
    address: http://127.0.0.1:5984
    username: admin
    password: password

The main memory core is Spaceport's primary database connection, used by the Documents system. You can define additional named cores for different databases or purposes.

Security Tip: Use environment variable substitution to keep sensitive credentials out of your configuration files.

## Source Modules

Define where Spaceport loads your Groovy code:

source modules:
  paths:
    - modules/*
    - lib/shared/*

Each path can include a wildcard (*) to recursively scan subdirectories. Without the wildcard, only files directly in that folder are loaded.

# Only loads .groovy files directly in modules/
source modules:
  paths:
    - modules/

# Loads .groovy files in modules/ and all subdirectories
source modules:
  paths:
    - modules/*

See Source Modules for details on writing and organizing modules.

## Static Assets

Map URL paths to filesystem directories:

static assets:
  paths:
    /assets/ : assets/*
    /public/ : public/*
    /downloads/ : files/downloads/

The wildcard (*) in the filesystem path enables serving subdirectories. Without it, only files directly in the mapped folder are accessible.

# Serves assets/ but NOT assets/css/ or assets/img/
static assets:
  paths:
    /assets/ : assets/

# Serves assets/ AND all subdirectories
static assets:
  paths:
    /assets/ : assets/*

See Static Assets for advanced configuration options.

## Stowaways

Configure external JAR dependencies:

stowaways:
  enabled: true
  paths:
    - stowaways/*
    - lib/jars/*

Stowaways are JAR files that Spaceport loads into the classpath at startup. Place third-party libraries or compiled Java code in these directories to make them available to your source modules.

## Logging

Control application logging behavior:

logging:
  enabled: true
  path: log/

When enabled, Spaceport automatically creates daily log files (YYYY-MM-DD.log) in the specified directory.

# Additional Configuration Sections

Beyond the defaults, Spaceport recognizes additional configuration sections for specific features.

## Migrations

Specify the location of migration scripts:

migrations:
  path: migrations/

Migration scripts handle database setup, data transformations, and other administrative tasks run via --migrate.

See Migrations for writing and running migrations.

## Ignition Scripts

Configure pre-launch initialization:

ignition:
  path: ignition/

Ignition scripts run before source modules load, useful for environment validation, dependency setup, or loading shared libraries.

See Ignition Scripts for patterns and use cases.

# Custom Configuration Values

One of the manifest's most powerful features is the ability to define your own configuration values. Any key you add to the manifest becomes accessible in your Groovy code through Spaceport.config.

# config.spaceport
app name: My Application
version: 1.0.0
max upload size: 10485760

api keys:
  stripe: sk_test_abc123
  sendgrid: SG.xyz789

feature flags:
  enable beta features: true
  maintenance mode: false

Access these values in your source modules:

// Simple values
def appName = Spaceport.config.'app name'
def version = Spaceport.config.version
def maxSize = Spaceport.config.'max upload size'

// Nested values
def stripeKey = Spaceport.config.'api keys'.stripe
def betaEnabled = Spaceport.config.'feature flags'.'enable beta features'

// Use in your application logic
if (Spaceport.config.'feature flags'.'maintenance mode') {
    r.writeToClient('<h1>Site Under Maintenance</h1>')
    return
}

Notice how configuration keys with spaces use Groovy's quoted property syntax: Spaceport.config.'my key'. This allows you to write configuration that reads naturally—prioritizing human readability over code convenience.

## Why Spaces in Config Keys?

The manifest file is meant to be read and edited by humans. Configuration like:

enable beta features: true
max upload size: 10485760
database connection timeout: 30000

...reads more naturally than:

enableBetaFeatures: true
maxUploadSize: 10485760
databaseConnectionTimeout: 30000

Groovy's flexible property access makes this possible without sacrificing functionality. The pattern Spaceport.config.'my readable key' keeps your configuration human-friendly while remaining fully accessible in code.

## Organizing Custom Configuration

For larger applications, group related settings under descriptive parent keys:

email:
  smtp host: smtp.example.com
  smtp port: 587
  from address: noreply@example.com
  
storage:
  upload directory: uploads/
  max file size: 52428800
  allowed extensions:
    - jpg
    - png
    - pdf

rate limiting:
  requests per minute: 60
  burst allowance: 10

Access nested configuration cleanly:

def smtpHost = Spaceport.config.email.'smtp host'
def maxFileSize = Spaceport.config.storage.'max file size'
def allowedExts = Spaceport.config.storage.'allowed extensions'

// Lists work as expected
if (fileExtension in allowedExts) {
    // Process upload
}

# YAML vs JSON

While Spaceport accepts both formats, YAML offers advantages for configuration files:

YAML (recommended):

host:
  address: 0.0.0.0
  port: 8080

source modules:
  paths:
    - modules/*
    - lib/*

JSON equivalent:

{
  "host": {
    "address": "0.0.0.0",
    "port": 8080
  },
  "source modules": {
    "paths": ["modules/", "lib/"]
  }
}

YAML eliminates brackets, braces, and quotation marks, reducing visual clutter. It also supports comments (lines starting with #), which JSON does not—making YAML better suited for configuration that needs inline documentation.

# Environment Variables

Spaceport supports environment variable substitution in your manifest using the ${ VAR } syntax. When Spaceport loads your configuration, it replaces these placeholders with the corresponding environment variable values.

memory cores:
  main:
    address: ${ COUCHDB_URL }
    username: ${ COUCHDB_USER }
    password: ${ COUCHDB_PASSWORD }

api keys:
  stripe: ${ STRIPE_SECRET_KEY }
  sendgrid: ${ SENDGRID_API_KEY }

This keeps sensitive values out of your configuration files and version control. Set the variables in your environment before starting Spaceport:

export COUCHDB_PASSWORD=my-secret-password
export STRIPE_SECRET_KEY=sk_live_abc123
java -jar spaceport.jar --start config.spaceport

Environment variable substitution works anywhere in your manifest—connection strings, API keys, file paths, or even custom configuration values.

# Environment-Specific Configuration

A common pattern is maintaining separate manifests for different environments:

config.spaceport              # Development defaults
config.production.spaceport   # Production overrides
config.staging.spaceport      # Staging environment

Start Spaceport with the appropriate manifest:

# Development
java -jar spaceport.jar --start config.spaceport

# Production
java -jar spaceport.jar --start config.production.spaceport

Your production manifest might use environment variables to avoid hardcoding sensitive values:

# config.production.spaceport
host:
  address: 0.0.0.0
  port: 80

debug: false

memory cores:
  main:
    type: couchdb
    address: ${ COUCHDB_URL }
    username: ${ COUCHDB_USER }
    password: ${ COUCHDB_PASSWORD }

logging:
  enabled: true
  path: /var/log/myapp/

# See Also