Deployment
Let's get Adama running somewhere real. I'll cover system requirements, configuration, the Solo server for simple deployments, and the workflow for pushing code changes without blowing things up.
System Requirements
Java Runtime
Adama needs Java 17 or later. That's the only hard dependency:
java -version
# openjdk version "17.0.7" or higher
Memory
How much RAM you need depends on what you're doing:
| Deployment Size | Recommended RAM | Concurrent Documents |
|---|---|---|
| Development | 512 MB | 10-50 |
| Small Production | 2 GB | 100-500 |
| Medium Production | 8 GB | 1,000-5,000 |
| Large Production | 32+ GB | 10,000+ |
Documents live in memory when active. Inactive documents get persisted and unloaded, so your actual memory footprint depends on how many documents are hot at any given moment.
Storage
For persistent deployments:
- SSD storage is recommended for data directories
- Plan for 10x your expected data size to accommodate redo logs and snapshots (yes, 10x -- redo logs are not small)
- Network-attached storage works but adds latency
Network
Adama uses these ports by default:
| Port | Purpose | Configurable |
|---|---|---|
| 8080 | HTTP/WebSocket | Yes (http-port) |
| 8085 | HTTP Redirect | Yes (http-redirect-port) |
Make sure your firewall allows incoming connections on the configured HTTP port.
Configuration
Adama is configured through JSON files. The web server configuration controls network behavior, timeouts, and resource limits.
Web Configuration Options
Create a JSON file with your configuration:
{
"http-port": 8080,
"http-redirect-port": 8085,
"http-max-content-length-size": 12582912,
"http-health-check-path": "/~health_check_lb",
"http-deep-health-check-path": "/~deep_health_check_status_page",
"websocket-handshake-timeout-ms": 2500,
"websocket-max-frame-size": 4194304,
"websocket-heart-beat-ms": 1000,
"http-read-idle-sec": 60,
"http-boss-threads": 2,
"http-worker-threads": 16,
"cache-root": "cache",
"transform-root": "transform-cache"
}
Configuration Reference
| Option | Default | Description |
|---|---|---|
http-port |
8080 | Main HTTP and WebSocket port |
http-redirect-port |
8085 | Port for HTTP redirects |
http-max-content-length-size |
12582912 | Maximum request body size (12 MB) |
websocket-handshake-timeout-ms |
2500 | WebSocket handshake timeout |
websocket-max-frame-size |
4194304 | Maximum WebSocket frame (4 MB) |
websocket-heart-beat-ms |
1000 | WebSocket heartbeat interval |
http-read-idle-sec |
60 | Idle connection timeout |
http-boss-threads |
2 | Netty boss threads |
http-worker-threads |
16 | Netty worker threads |
cache-root |
cache | Directory for cache files |
transform-root |
transform-cache | Directory for transform cache |
Environment-Specific Configuration
I'd recommend separate config files for each environment:
config/
development.json
staging.json
production.json
Pass the appropriate one when starting the server:
java -jar solo.jar --web config/production.json --scan /app/adama
The Solo Server
Solo is a single-process Adama server. Web server, document runtime, and in-memory storage -- all in one executable. It's the simplest way to run Adama, and honestly, for a lot of use cases, it's all you need.
Starting Solo
Solo scans a directory for Adama files and serves them:
java -jar solo.jar --scan /path/to/adama/files
With a custom web configuration:
java -jar solo.jar --scan /path/to/adama/files --web /path/to/config.json
Directory Structure
Solo expects Adama files in the scan directory:
/app/adama/
game.adama
chat.adama
dashboard.adama
Each .adama file becomes a deployable space. The filename (without extension) becomes the space name. Simple.
Solo Capabilities
Solo gives you:
- HTTP and WebSocket serving: Full API access via HTTP and WebSocket
- Document compilation: Adama files are compiled on startup
- In-memory storage: Documents persist in memory during runtime
- Asset uploads: Support for file uploads via
/~upload - Real-time connections: WebSocket connections at
/~adama
Solo Limitations
Here's the tradeoff. Solo is designed for simplicity, not high availability:
- No persistence: Documents are lost when the process stops
- Single node: No clustering or horizontal scaling
- No hot reload: Restart required to pick up code changes
For production workloads where you need durability, you'll want the full Adama platform or an external persistence layer. But for development, testing, and simple deployments? Solo is great.
Solo API Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/~adama |
WebSocket | Real-time document connections |
/~adama/once |
POST | One-shot API calls |
/~upload |
POST | Asset uploads |
/~health_check_lb |
GET | Load balancer health check |
Space Management
In Adama, a space is a container for related documents that share the same code. Managing spaces is a core operational task.
Creating a Space
Using the CLI:
java -jar adama.jar space create --space myapp
This creates an empty space. You need to deploy code before documents can be created.
Listing Spaces
View all spaces in your account:
java -jar adama.jar space list
Space Configuration
Each space has configuration options that control behavior:
java -jar adama.jar space set --space myapp --key maximum_history --value 100
Common configuration options:
| Option | Description |
|---|---|
maximum_history |
Maximum redo log entries to keep |
delete_on_close |
Delete document when all clients disconnect |
Document Deployment Workflow
Deploying code changes to production requires some care. Adama supports gradual rollouts through deployment plans, which is the kind of safety net you want when you're pushing changes to live documents.
The Deployment Plan
A deployment plan is a JSON document that maps version identifiers to code and defines rollout rules:
{
"versions": {
"v1": "public int count = 0;",
"v2": "public int count = 0; public string name = \"\";"
},
"default": "v1",
"plan": [
{
"version": "v2",
"prefix": "beta-",
"percent": 100
},
{
"version": "v2",
"keys": ["test-doc-1", "test-doc-2"]
}
]
}
Version Definition
Versions can be simple strings or full configuration objects:
{
"versions": {
"simple": "public int x;",
"complex": {
"main": "public int x; @include utils;",
"includes": {
"utils": "function helper() { return 42; }"
},
"rxhtml": "<forest>...</forest>"
}
},
"default": "simple",
"plan": []
}
Rollout Rules
The plan array contains rules evaluated in order. The first matching rule determines the version:
| Rule Field | Description |
|---|---|
version |
Version identifier to use if rule matches |
keys |
Specific document keys that match this rule |
prefix |
Document key prefix that matches this rule |
percent |
Percentage of matching documents (0-100) |
seed |
Hash seed for deterministic percentage-based routing |
Deployment Strategy Examples
Canary Deployment
Test new code on specific documents first:
{
"versions": {
"stable": "...",
"canary": "..."
},
"default": "stable",
"plan": [
{
"version": "canary",
"keys": ["canary-test-1", "canary-test-2"]
}
]
}
Percentage-Based Rollout
Gradually increase traffic to the new version:
{
"versions": {
"v1": "...",
"v2": "..."
},
"default": "v1",
"plan": [
{
"version": "v2",
"percent": 10,
"seed": "rollout-2024"
}
]
}
The seed ensures the same documents consistently route to v2 as you increase the percentage. Without it, you'd get different documents each time, which defeats the purpose.
Blue-Green Deployment
Switch all traffic at once:
{
"versions": {
"blue": "...",
"green": "..."
},
"default": "green",
"plan": []
}
Just change default from "blue" to "green" to switch. That's it.
Deploying Code
Deploy a plan to a space:
java -jar adama.jar space deploy --space myapp --plan deployment.json
The deployment is atomic -- all documents see the new configuration simultaneously.
Rollback
To rollback, deploy a plan with the previous version as default:
{
"versions": {
"v1": "...",
"v2": "..."
},
"default": "v1",
"plan": []
}
Keep previous versions in your deployment plan until you're confident in the new code. You'll thank yourself later.
Production Checklist
Before going live, verify:
Infrastructure
- [ ] Java 17+ installed and tested
- [ ] Sufficient memory allocated
- [ ] SSD storage for data directories
- [ ] Firewall rules configured
- [ ] SSL/TLS termination configured (via reverse proxy)
Configuration
- [ ] Production configuration file created
- [ ] Timeouts tuned for expected workload
- [ ] Worker threads scaled for hardware
- [ ] Health check paths verified
Monitoring
- [ ] Health check endpoint accessible
- [ ] Log aggregation configured
- [ ] Alerting configured for health check failures
Deployment
- [ ] Deployment plan tested in staging
- [ ] Rollback procedure documented
- [ ] Previous versions retained in deployment plan
Security
- [ ] No secrets in Adama code
- [ ] Privacy policies reviewed
- [ ]
@connectedhandler restricts access appropriately - [ ] Static create/invent policies configured
Start simple with Solo. Graduate to more sophisticated deployment strategies as your needs grow. The deployment plan system gives you safe, incremental rollouts that minimize risk -- and more importantly, it gives you the confidence to actually push changes.