Rails 8 application template with CI/CD, Kamal deployment, devcontainer, Claude Code hooks, RuboCop custom cops, TDD workflow, and Bitwarden Secrets Manager integration.
rails new my_cool_app -d postgresql -m /path/to/template.rbOr from GitHub:
rails new my_cool_app -d postgresql -m https://raw.githubusercontent.com/AxiumFoundry/rails8-template/main/template.rb- Rails 8.x with PostgreSQL
- Solid Stack - Solid Cache, Solid Queue, Solid Cable (multi-database)
- Hotwire - Turbo + Stimulus
- Tailwind CSS
- Devise for authentication
- ViewComponent for reusable UI components
- Kamal for deployment
- Devcontainer - PostgreSQL, Selenium, BWS CLI, Claude Code
- CI - GitHub Actions: scan, lint, test, system-test, autofix (Claude Code), email notifications
- CD - Kamal deploy on CI success (main -> production, develop -> staging)
- BWS - Bitwarden Secrets Manager for all secrets (only
BWS_ACCESS_TOKENneeded as GitHub secret)
- RuboCop with 5 custom cops:
Custom/NoComments- Enforces self-documenting codeRails/SkinnyController- Max 5 lines per action, no business logicRails/StrictRestfulRoutes- Only 7 RESTful actions, no custom routesRails/NoMetaprogramming- Nodefine_method,send, etc.Rails/TurboBroadcasts- Enforces async broadcasts, nolocal: true
- Claude Code hooks - TDD enforcement, auto-test, auto-lint on every edit (see Hooks)
- Git pre-commit hook - RuboCop + related tests on staged files
- Minitest + Capybara with parallel test execution
- FactoryBot for test data
- WebMock for HTTP stubbing
- SimpleCov for code coverage
- TDD workflow enforced by Claude hooks
- Root
CLAUDE.mdwith project conventions - 8 nested
CLAUDE.mdfiles for models, controllers, services, helpers, views, components, Stimulus, tests CLAUDE.local.md.examplefor personal preferences
You don't need to find-and-replace anything after generation. The template automatically inserts your project name into every config file, workflow, and script.
The name you pass to rails new drives everything:
rails new my_cool_app -d postgresql -m template.rb
# ^^^^^^^^^^^
# This becomes `app_name` -- every value below is derived from it.| Where it shows up | What gets inserted | Example |
|---|---|---|
| Database names | {app_name}_development, _test, etc. |
my_cool_app_development |
| Docker image name | {app_name} (hyphens become underscores) |
my_cool_app |
| Devcontainer service | {app_name} in compose.yaml, devcontainer.json |
my_cool_app |
| Container name | {app_name}-rails-app-1 (used in pre-commit hook, CLAUDE.md) |
my_cool_app-rails-app-1 |
| Kamal deploy config | service: {app_name} in config/deploy.yml |
service: my_cool_app |
| BWS secret prefix | {APP_NAME} uppercased (see below) |
MY_COOL_APP |
Bitwarden Secrets Manager keys are prefixed with your project name so multiple projects can share one BWS organization. The prefix is derived by uppercasing app_name and replacing hyphens with underscores.
my_cool_app -> MY_COOL_APP
my-cool-app -> MY_COOL_APP
This prefix appears in:
.kamal/secrets-KAMAL secrets extract MY_COOL_APP_RAILS_MASTER_KEY.devcontainer/setup-bws-env.sh- maps BWS secrets to environment variables.github/BWS_SECRETS.md- documents every secret your CI/CD needs
See templates/.github/BWS_SECRETS.md.tt for the full list of required secrets and which workflows use them.
The template configures Claude Code with hooks that run automatically before and after file edits. These enforce code quality without manual intervention.
| Hook | Trigger | What it does |
|---|---|---|
rails_test_guide.sh |
Write/Edit | Checks that a test file exists before implementing code (TDD enforcement) |
no_skip_tests.sh |
git commit |
Blocks commits that use --no-verify |
| Hook | Trigger | What it does |
|---|---|---|
test_posttooluse.sh |
Write/Edit | Runs related tests for the edited file |
tdd_check.sh |
Write/Edit | Validates TDD workflow (test written before implementation) |
controller_response_check.sh |
Write/Edit | Checks controllers only use HTML/Turbo Stream responses, no JSON |
broadcast_test_guide.sh |
Write/Edit | Checks Turbo broadcasts use _later async variants |
rubocop_test.sh |
Write/Edit | Runs RuboCop on the edited file |
log_hook.sh |
All | Logs hook executions to .claude/hook_execution.log |
The settings.json also configures allowed and denied commands:
- Allowed: Rails, RuboCop, git, bundle, common shell commands, GitHub CLI
- Denied:
--no-verify,git push --force, modifications to.git/hooks/
- BWS: Create secrets in Bitwarden Secrets Manager with the correct prefix
- GitHub: Add
BWS_ACCESS_TOKENandCLAUDE_CODE_OAUTH_TOKENas repository secrets - Kamal: Update
config/deploy.ymlandconfig/deploy.staging.ymlwith your server IPs and domains - Docker Hub: Update registry username in deploy configs
.kamal/secrets: Add your BWS secret UUIDs
template.rb # Main orchestrator
templates/ # Thor template files
Gemfile.tt
Dockerfile.tt
.rubocop.yml.tt
.rubocop/cop/ # 5 custom RuboCop cops
.claude/ # Claude Code settings + 8 hook scripts
.devcontainer/ # VS Code devcontainer
.github/ # CI/CD workflows + BWS action
.kamal/ # Kamal secrets
config/ # Database, cable, cache, queue, storage, puma, deploy
app/ # ApplicationService, ApplicationComponent, Stimulus controllers
test/ # Test helper, system test case, factories
git_hooks/ # Pre-commit hook
CLAUDE.md.tt # + 8 nested CLAUDE.md templates