CommandTower is a Rails engine. The install flow below gets the engine mounted, migrated, and doctor-checked. That alone is not a fully usable Me/Auth host — complete RBAC, feature gates, and a smoke check via the Host integration guide.
Back to README.
# Gemfile: gem "command_tower" (or path/git source)
bundle install
bin/rails command_tower:install
bin/rails db:migrate
bin/rails command_tower:doctorcommand_tower:install does not run db:migrate. Installing and migrating stay separate on purpose.
Continue with Host integration:
- Host
rbac_groups.ymlproduct role that grants CT-owned Me/Auth entity names (required — otherwise authenticated Me/Auth calls 403) - Set
authorization.default_membership_role(for example"member") or assign roles some other supported way - Enable feature gates you need (login, reset, availability, …)
- Smoke-check
GET /mewith a Bearer token - Wire messaging catalog/adapters when you emit or use phone/Pushover
- Runs Rails-native
command_tower:install:migrations(copies engine migrations into the hostdb/migrate/with*.command_tower.rbscope). - Runs
rails g command_tower:configureunless skipped (creates initializer; mounts the engine). - Prints next steps.
| Variable | Effect |
|---|---|
SKIP_CONFIGURE=1 |
Migrations only (existing custom initializer / mount) |
SKIP_MOUNT=1 |
Generate initializer but do not mount routes |
FORCE=1 |
Overwrite an existing config/initializers/command_tower.rb |
Examples:
SKIP_CONFIGURE=1 bin/rails command_tower:install
SKIP_MOUNT=1 bin/rails command_tower:install
FORCE=1 bin/rails command_tower:installPrefer command_tower:install for greenfield hosts. The generator remains available:
bin/rails generate command_tower:configure
bin/rails generate command_tower:configure --skip-routes
bin/rails generate command_tower:configure --forceThe generator:
- Adds
config/initializers/command_tower.rbwhen missing (or overwrites with--force). - Mounts
CommandTower::Engineunless--skip-routesor already mounted.
Dummy-host example initializer (engine development): rails_app/config/initializers/command_tower.rb.
CommandTower is the sole authoring authority for CommandTower-owned schema (db/migrate inside the gem). Hosts must not manually write, edit, or copy-paste CommandTower schema migrations (AD-SCH-01).
Handled by command_tower:install (step 1). Equivalent migration-only command:
bin/rails command_tower:install:migrations
bin/rails db:migratecommand_tower:install:migrations is the standard Rails engine task (wrapper around railties:install:migrations). Re-running installation is idempotent: already-installed CommandTower migrations are skipped.
Rails may retimestamp newly copied host files. That is normal. Do not hand-edit installed *.command_tower.rb files.
- Bump/release the CommandTower gem dependency in the host.
- Run
bin/rails command_tower:install:migrations(orSKIP_CONFIGURE=1 bin/rails command_tower:install). - Run
bin/rails db:migrate. - Optionally run
bin/rails command_tower:doctor.
Do not re-run configure on hosts that already customize the initializer unless you intend to regenerate it (FORCE=1).
- Author the migration only in CommandTower
db/migrate/. - Release / bump the gem in the host.
- Install + migrate as above.
Installed host copies are an execution context, not a second authoring home.
Required for production-ready hosts:
config.jwt.hmac_secret— typicallySECRET_KEY_BASE/Rails.application.secret_key_baseconfig.signup_session.jwt_secret— orSIGNUP_SESSION_JWT_SECRETconfig.password_recovery_session.jwt_secret— orPASSWORD_RECOVERY_SESSION_JWT_SECRETconfig.application.host_key— server-bound host/product identity for CT-generic user-scoped state (experience states). Not client-supplied. Blank → Me experience-state routes return 503.
Optional / feature-gated:
- Messaging SMS / Pushover adapters and credential resolution (
config.credentials.*or ENV) - Cookie + CSRF JWT modes
- Admin enablement, application URL, welcome content hooks
The generated initializer documents available options via class_composer. Defaults live in CommandTower; do not duplicate them unnecessarily in the host.
bin/rails command_tower:doctorChecks Rails version compatibility, engine baseline migrations, host-installed migration copies, JWT / session secrets, and messaging adapter names. Failures abort with remediation text; warnings print but allow success.
Doctor does not probe Redis/SMTP connectivity.
| Concern | Owner |
|---|---|
| Author CT schema migrations | CommandTower |
| Install / run migrations | Host (via engine tasks + db:migrate) |
| Product configuration / secrets | Host initializer + ENV |
| Dual-author CT schema in the host | Forbidden |
| Symptom | Fix |
|---|---|
users already exists on migrate |
Database not empty / stale schema.rb load — migrate an empty DB, or dump schema after a clean migrate |
| Install copies nothing new | Already installed — expected idempotency |
| Missing tables after install | You installed but did not db:migrate |
| Doctor fails on JWT default | Set config.jwt.hmac_secret from a real secret |
| Accidental public engine mount | Use SKIP_MOUNT=1 / --skip-routes, or mount at the path your product needs |
If the host already has a bespoke initializer and mount:
SKIP_CONFIGURE=1 bin/rails command_tower:install
# same as: bin/rails command_tower:install:migrations
bin/rails db:migrateDo not run rails g command_tower:configure unless you intentionally want stock scaffolding.
Shared FactoryBot definitions ship with the gem. In the host test boot path:
require "command_tower/testing"
CommandTower::Testing.install!Then extend with FactoryBot.modify as needed. See Testing with CommandTower.