Getting Started with a New Rails App

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.

You do not need to follow this guide to use the LocoMotion gem — see the Install guide for adding the component library to an existing app. This guide presents an opinionated starting point for new projects, but you should feel free to adapt these recommendations to suit your preferences and requirements.

1. A Dockerized Foundation

We recommend using Docker from the very beginning — even before you run rails new. This gives you a stable development environment regardless of your OS, and keeps the dev container small and simple so troubleshooting is easy.

For the full Docker walkthrough — installing Docker, copying the example config files, and booting the containers — follow the Docker guide first. Once you can run just dev to build the containers and just dev-shell to open a shell inside the development container, come back here.

Why Just?

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.

2. Creating the Rails App

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
Versions & Databases

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

3. Database Configuration

Open the newly created config/database.yml and add the following three lines under the default key so Rails can reach the Postgres container:

# Under the default section in config/database.yml
host: db
username: postgres
password: password

Now 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!

Note

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.

4. Using UUIDs by Default

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
end

5. Install HAML (Optional)

While 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:

# App-Specific Gems
gem "haml-rails", "~> 2.0"

# For development only (helps convert ERB to HAML)
group :development do
  gem "html2haml"
end

Open 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:

module.exports = {
  content: [
    './app/views/**/*.html.haml',
    // ...
  ]
}

Finally, convert any existing .erb files to .haml:

Warning

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.

6. Install DaisyUI (Optional)

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. With Tailwind 4, DaisyUI is configured directly in your CSS file rather than in tailwind.config.js. Open an app shell with just app-shell and install the packages:

yarn add tailwindcss @tailwindcss/cli daisyui

Then add the @import and @plugin directives to your application.tailwind.css:

/* Import the base Tailwind theme */
@import 'tailwindcss';

/* Include DaisyUI via @plugin directive */
@plugin 'daisyui' {
  themes: light --default, dark --prefersdark;
}

/* Custom variant to reduce selector specificity for component defaults */
@custom-variant where (:where(&));

/* Custom dark: variant for System-based & DaisyUI ThemeController dark mode */
@custom-variant dark (@media (prefers-color-scheme: dark), :root:has(input.theme-controller[value=dark]:checked) &);

/* Point to tailwind.config.js for content scan paths only */
@config "../tailwind.config.js";
Tailwind 4 Configuration

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.

Reveal Tooltips on Keyboard Focus

LocoMotion lets you attach a tooltip to many components with the tip: attribute, which adds the tooltip class and data-tip directly to the element. DaisyUI 5, however, only reveals a tooltip on keyboard focus when the focused element is a child of the .tooltip element — so tooltips placed directly on a focusable element (a button, link, etc.) show on hover but not when a keyboard user tabs to them.

Add this small rule to your application.tailwind.css so those tooltips also appear on focus. It mirrors DaisyUI's own reveal rule for the case where the tooltip element itself is focused:

/* 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 Wrapping?

If you'd rather not add custom CSS, wrap the element in the daisy_tooltip (aliased daisy_tip) component instead. That follows DaisyUI's recommended structure — the focusable element becomes a child of the .tooltip, so focus works without any extra rule.

7. Try It Out!

With everything installed, let's confirm it all works. First, tell the Rails server to bind to all interfaces in your Procfile.dev:

web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0

Update your Dockerfile to start the app using Foreman:

# Change this line:
CMD ["rails", "server", "-b", "0.0.0.0"]

# To this:
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:

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
end

And 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 Button

Visit 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!

Clean Up

Once you are done playing around, undo these layout and routing changes so they do not cause confusion later.

Success!

You now have a fully-configured Rails app the LocoMotion way. From here, set up a solid foundation with the Debugging & Testing guide, structure your business logic with the Service Objects guide, and add user sign-in with the Authentication guide.

Made with by Profoundry .
Copyright © 2023-2026 Profoundry LLC.
All rights reserved.