This guide walks you through standing up a brand-new Rails application using the philosophies and tooling that LocoMotion recommends: Docker for a stable development environment, Just for command running, HAML for templates, and TailwindCSS + DaisyUI for styling.
This guide picks up where the Docker guide leaves off — every command below runs inside the dev container it builds. If you didn't mean to skip it, start there and come back. Skipping on purpose? Install Ruby, Node, and PostgreSQL on your machine and run each command directly.
We use Just as our command runner instead of Make. It provides a cleaner, more readable syntax for defining commands, better error handling, and is easier to maintain than complex Makefiles.
Inside the development container, everything is set up and ready for you
to install Rails. Change into the app directory (which is mapped to your
local machine) and run rails new:
cd /home/app && rails new . --skip --database=postgresql --javascript=esbuild --css=tailwind
If you want something other than PostgreSQL or TailwindCSS, you can change
that here — these are just our recommendations.
We also tend to recommend lagging slightly behind the latest Ruby version,
as the newest release occasionally has trouble building the Rails project.
You can change it in dev/Dockerfile via the FROM line at the top.
If you run into trouble with the rails new command, this resets the
generated files so you can try again without losing your dev config:
rm -rf .dockerignore .git .gitattributes .gitignore .node-version .ruby-version Gemfile README.md Rakefile app bin config config.ru
Open the newly created config/database.yml and add the following three
lines under the default key so Rails can reach the Postgres container:
# config/database.yml (under the default: key)
host: db
username: postgres
password: passwordNow uncomment the app section in your docker-compose.yml file and run
just app to build and start the application. After a minute or two you
should see Puma listening on port 3000, and you can visit
http://localhost:3000 to view your running app!
Once the container is built, you can run just app-fast to simply start
the containers without rebuilding. This is much faster than a full
build every time.
We believe strongly in using UUIDs for primary keys to increase security and avoid potential scaling issues down the road. To enable this by default for all generated models, create the following initializer:
# config/initializers/generators.rb
Rails.application.config.generators do |generator|
generator.orm :active_record, primary_key_type: :uuid
endWhile you can use the default ERB templating system, we highly recommend
HAML — it provides a much cleaner language for your
template files. Add the gems to your Gemfile:
# Gemfile
gem "haml-rails", "~> 2.0"
# For development only (helps convert ERB to HAML)
group :development do
gem "html2haml"
endOpen a Docker shell in the app container with just app-shell and run
bundle to install the gems. Then point Tailwind at your HAML views by
updating tailwind.config.js:
// tailwind.config.js
module.exports = {
content: [
'./app/views/**/*.html.haml',
// ...
]
}Finally, convert any existing .erb files to .haml:
This deletes your ERB files, so make sure you have a backup or can easily
do a git revert.
HAML_RAILS_DELETE_ERB=true rails haml:erb2haml
For a deeper dive into HAML syntax and conventions, see the HAML guide.
TailwindCSS is a utility-based CSS framework
that lets you build components by composing utility classes. It is already
installed via the rails new command above, and we highly recommend it
for every project.
DaisyUI builds on top of Tailwind by providing
ready-made component classes, so a button becomes as simple as
%button.btn. And LocoMotion builds on top of DaisyUI, wrapping
those classes in ready-made Rails components like daisy_button.
Installing LocoMotion? Follow the Install guide — it covers the gem, the npm package, and the exact CSS block to copy. You do not need to install DaisyUI separately; LocoMotion depends on it and pulls it in automatically.
LocoMotion — full Rails components like daisy_button
DaisyUI — ready-made component classes like btn
TailwindCSS — utility classes like font-bold
Just want DaisyUI? Open an app shell with just app-shell and
install the packages yourself:
yarn add tailwindcss @tailwindcss/cli daisyui
Then register the plugin at the top of your application.tailwind.css.
With Tailwind 4, plugins are configured directly in the CSS file:
/* app/assets/stylesheets/application.tailwind.css */
@import "tailwindcss";
@plugin "daisyui";Tailwind 4 moves all plugin configuration into the CSS file. Do not
add DaisyUI to tailwind.config.js — that file is now only used to
declare content scan paths.
If you installed LocoMotion, the loco.css import from the
Install guide quietly fixes several papercuts.
You shouldn't need to think about these — dive in only if one of them
surprises you:
Components apply their visual defaults through the where:
variant, which compiles to zero-specificity :where() rules —
so any utility you pass via css: overrides a default without
!important. More than a dozen components rely on it, which is
why the import is required rather than optional.
The custom dark: variant responds to both the OS-level dark
preference and a DaisyUI theme controller set to a dark theme,
so manual theme switching and system preference agree.
Add floating-sticky alongside floating-label (e.g. via
label_wrapper_css:) to pin the label in its raised position
while an empty field still shows its placeholder — DaisyUI
normally collapses the label until the field is focused or has a
value. The rule also keeps the label visible on disabled fields.
DaisyUI 5 only reveals a tooltip on focus when the focused
element is a child of .tooltip, so tip: tooltips placed
directly on a button or link show on hover but not when a
keyboard user tabs to them. loco.css ships the missing rule:
/* @profoundry-us/loco_motion/loco.css */
/* Reveal `tip:`/`tooltip` tooltips on keyboard focus */
.tooltip:focus-visible:is([data-tip]:not([data-tip=""]), :has(.tooltip-content:not(:empty))) {
&[data-tip]::before,
&::after,
& > .tooltip-content {
opacity: 1;
--tt-pos: 0rem;
}
}Prefer no custom CSS at all for tooltips? Wrap the element in the
daisy_tooltip (aliased daisy_tip) component instead — the
focusable element becomes a child of the .tooltip, so keyboard
focus works through DaisyUI's own rule.
With everything installed, let's confirm it all works. First, tell the
Rails server to bind to all interfaces in your Procfile.dev:
# Procfile.dev
web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0Update your Dockerfile to start the app using Foreman:
# Dockerfile
CMD ["rails", "server", "-b", "0.0.0.0"]# Dockerfile
CMD ["./bin/dev"]Since we are using Docker, it also helps to clear out stale PID files on
boot. Add these lines to bin/setup, just above the lines that restart
the application server:
# bin/setup
puts "\n== Removing old PID files =="
system! "rm -rf /home/app/tmp/pids/server.pid"Restart with just app (a full rebuild is required because we changed the
Dockerfile). Now wire up a quick test route and controller action:
# config/routes.rb
root "application#test"
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def test
render html: "Test", layout: true
end
endAnd modify your layout's body to show some Tailwind styling (and, if you installed it, a DaisyUI button):
- # app/views/layouts/application.html.haml
%body
.m-2.p-2.rounded.bg-red-400
= yield
- # If you installed DaisyUI, add this too:
.btn
Test ButtonVisit http://localhost:3000 — you should see a red, rounded box with the word "Test", and a gray DaisyUI button that reacts when you hover and click it!
Once you are done playing around, undo these layout and routing changes so they do not cause confusion later.
You now have a fully-configured Rails app the LocoMotion way. Keep the momentum going with these guides:
Create virtual credit / debit cards to keep your real info safe.
Get $5 when you sign up — free to start!
Everything you need to grow your business with confidence!
CRM, Lead Generation, Project Management, Contracts, Online Payments, and more!
The ads above are affiliate links to products I regularly use and highly
recommend.
I may receive a commission if you decide to purchase.