Overview
Hadoken hosts Rails applications. You point it at a Rails app, and it
handles everything else: building a container, running migrations,
provisioning TLS, and giving you a live URL. There are no config files
to write.
The CLI is a standalone binary (not a Ruby gem). It reads your
Gemfile.lock to detect your Ruby version, database adapter, and which
parts of the Rails stack you're using. Then it packages your source,
builds an image, deploys it, and prints the URL.
After deploy, you get logs, environment variables, a Rails console,
and the ability to run one-off commands -- all through the same CLI.
Quickstart
1. Install
$ curl -fsSL https://hadoken.dev/install.sh | sh
2. Get a Rails app
$ git clone https://github.com/hadoken-paas/rails-hello.git && cd rails-hello
Or use any existing Rails app with committed files.
3. Deploy
$ hadoken
The CLI handles account creation and login interactively on first
run. It detects your app, builds, deploys, and prints the URL.
Deploy pipeline
Every deploy runs through these steps:
-
Package -- The CLI creates a tarball from
git ls-files. Only committed files are included.
Use --include-untracked to add untracked files.
-
Upload -- The tarball goes to the Hadoken API.
-
Build -- A build job produces a container image
from your source using Cloud Native Buildpacks. No Dockerfile
needed.
-
Migrate --
rails db:prepare runs
automatically.
-
Deploy -- Your container is deployed. A health
check on
/up confirms the app is ready.
-
TLS -- A Let's Encrypt certificate is
provisioned for your subdomain.
Deploy statuses
building --> deploying --> live
\-> failed
\-> build_failed
The CLI polls and waits by default. You can also check manually
with hadoken status --watch.
Rollbacks
If the health check fails, the previous working version stays live.
The deploy status shows failed.
CLI reference
Global flags
| Flag | Description |
--api, -a | API base URL (default: https://api.hadoken.dev) |
--project, -p | Project name override |
--json | Machine-readable JSON output |
--quiet, -q | Minimal output |
--debug | Diagnostic output |
--no-color | Disable ANSI colors |
hadoken signup
Create an account. Prompts for email, username, and password (min
8 characters). Sends a verification email and waits for
confirmation, then logs you in.
$ hadoken signup
hadoken login
Log in to an existing account.
| Flag | Description |
--username, -u | Username |
--password-stdin | Read password from stdin |
--token | API token (instead of username/password) |
$ hadoken login
$ echo "$PASS" | hadoken login -u myuser --password-stdin
hadoken logout
Remove stored credentials. Use --all to clear all profiles.
hadoken whoami
Show current identity.
$ hadoken whoami
User: myuser
Status: active
API: https://api.hadoken.dev
hadoken init
Detect your Rails app and create a project. You can also skip this
-- the first hadoken deploy auto-initializes.
| Flag | Description |
--name | Project name (default: directory basename) |
--database | Override database: auto, sqlite, postgresql, mysql |
--force | Overwrite existing config |
--yes, -y | Accept defaults |
What init detects
| Property | Source |
| Rails version | Gemfile.lock |
| Ruby version | .ruby-version or Gemfile |
| Database | sqlite3, pg, or mysql2 gem |
hadoken / hadoken deploy
Deploy the current app. Bare hadoken is an alias for
hadoken deploy.
| Flag | Description |
--message, -m | Deploy annotation |
--wait | Wait for completion (default: true) |
--timeout | Timeout (default: 20m) |
--verbose, -v | Show build logs |
--include-untracked | Include untracked files |
--dry-run | Validate only, don't deploy |
--yes, -y | Accept defaults |
--confirm-dirty | Proceed with uncommitted changes |
$ hadoken
$ hadoken deploy -v
$ hadoken deploy --dry-run
$ hadoken deploy -m "fix login bug"
hadoken status
Check deploy status.
| Flag | Description |
--deploy | Deploy ID (default: latest) |
--watch | Poll until done |
--interval | Poll interval (default: 3s) |
$ hadoken status
Project: myapp
Deploy: d-abc123
Status: live
URL: https://myapp.hadoken.app
hadoken logs
View app logs.
| Flag | Description |
--follow, -f | Stream in real-time |
--since | Since duration or timestamp (default: 15m) |
--tail | Number of lines (default: 200) |
$ hadoken logs
$ hadoken logs -f
$ hadoken logs --since 1h
hadoken env
Manage environment variables. See
Environment variables.
$ hadoken env
$ hadoken env --unmask
$ hadoken env set KEY=VALUE
$ hadoken env get KEY
$ hadoken env unset KEY
hadoken console
Open a Rails console on the running app. Requires
kubectl in your PATH.
$ hadoken console
hadoken run
Run a one-off command on the running app.
| Flag | Description |
--interactive, -i | Allocate TTY |
$ hadoken run -- rails db:migrate
$ hadoken run -- rails db:seed
$ hadoken run -i -- bash
hadoken open
Open the app in your browser.
$ hadoken open
hadoken destroy
Tear down all resources. You must type the project name to confirm
(or use --yes).
$ hadoken destroy
Type project name to confirm: myapp
Destroying myapp... done
hadoken completion
Generate shell completions for bash, zsh, fish, or powershell.
$ hadoken completion bash >> ~/.bashrc
$ hadoken completion zsh >> ~/.zshrc
Environment variables
Setting variables
$ hadoken env set SECRET_KEY_BASE=abc123 STRIPE_KEY=sk_live_xxx
$ hadoken env get SECRET_KEY_BASE
abc123
$ hadoken env unset STRIPE_KEY
Each change triggers a rolling restart of your app. Values are
encrypted at rest and masked in hadoken env output.
Use --unmask to see plaintext.
Built-in variables
Set automatically on every deploy:
| Variable | Value |
PORT | 8080 |
RAILS_ENV | production |
RAILS_SERVE_STATIC_FILES | 1 |
RAILS_LOG_TO_STDOUT | 1 |
CLI environment variables
These control the CLI itself, not your app:
| Variable | Effect |
HADOKEN_API | Override API base URL |
HADOKEN_PROFILE | Select credential profile |
HADOKEN_NONINTERACTIVE | Disable prompts (set to 1) |
HADOKEN_YES | Auto-accept prompts (set to 1) |
Logs
Logs come from your app's stdout. Rails is configured with
RAILS_LOG_TO_STDOUT=1 so everything goes to stdout
by default.
$ hadoken logs
$ hadoken logs -f
$ hadoken logs --since 1h
$ hadoken logs --tail 50
Duration formats: 15m, 1h,
30s, 2h30m. Also accepts RFC 3339
timestamps.
Console and run
Rails console
$ hadoken console
Opens an interactive Rails console on the running app. Requires
kubectl in your PATH.
One-off commands
$ hadoken run -- rails db:migrate
$ hadoken run -- rails db:seed
$ hadoken run -- rails runner "puts User.count"
$ hadoken run -i -- bash
Separate the command from flags with --. Use
-i for interactive sessions.
Projects
A project is created the first time you deploy (or when you run
hadoken init). The project name defaults to your
directory name. If the name is taken, a random suffix is appended.
Your app is available at
https://<project-name>.hadoken.app.
TLS is automatic.
hadoken destroy tears down the project and all its
resources. You must confirm by typing the project name.
Limits
Per-app resources
| Resource | Limit |
| CPU | 500m |
| Memory | 512 MiB |
| Storage | 1 GiB persistent volume |
Account limits
| Limit | Value |
| Projects per user | 10 |
| Deploys per project per day | 100 |
| Concurrent builds | 3 |
Timeouts
| Operation | Timeout |
| Deploy (CLI wait) | 20 minutes |
| Rollout | 120 seconds |
| Stale builds | 15 minutes (auto-failed) |
Exit codes
For scripting and CI:
| Code | Meaning |
0 | Success |
1 | Usage error (bad flags, not a Rails app) |
2 | Auth error (not logged in, expired token) |
3 | Server error (build failed, deploy failed) |
4 | Config error (not initialized) |
5 | Timeout |
130 | Cancelled (Ctrl-C) |
hadoken deploy --yes --timeout 10m
if [ $? -eq 3 ]; then echo "Deploy failed"; fi
Config storage
Credentials are stored in ~/.hadoken/config.json.
Project configs are in ~/.hadoken/projects/, keyed
by a hash of your repo path so multiple projects don't collide.
Both files are created with mode 0600.
~/.hadoken/config.json
{"api_base": "https://api.hadoken.dev", "token": "<jwt>"}
~/.hadoken/projects/<hash>.json
{"project_id": "<uuid>", "project_name": "myapp"}