A friendly CLI for deploying Rails apps ✨
Tomo is a friendly command-line tool for deploying Rails apps.
💻 Rich command-line interface with built-in bash completions
☁️ Multi-environment and role-based multi-host support
💎 Everything you need to deploy a basic Rails app out of the box
🔌 Easily extensible for polyglot projects (not just Rails!)
📚 Quality documentation
🔬 Minimal dependencies
→ See how tomo compares to other Ruby deployment tools like Capistrano and Mina.
Tomo is distributed as a ruby gem. To install:
$ gem install tomo
💡 Protip: run
tomo completion-scriptfor instructions on setting up bash completions.
Tomo is configured via a
.tomo/config.rbfile in your project. To get started, run
tomo initto generate a configuration that works for a basic Rails app.
An abbreviated version looks like this:
# .tomo/config.rbplugin "git" plugin "bundler" plugin "rails"
...
host "[email protected]"
set application: "my-rails-app" set deploy_to: "/var/www/%{application}" set git_url: "[email protected]:my-username/my-rails-app.git" set git_branch: "main"
...
setup do run "git:clone" run "git:create_release" run "bundler:install" run "rails:db_schema_load"
...
end
deploy do run "git:create_release" run "core:symlink_shared" run "core:write_release_json" run "bundler:install" run "rails:assets_precompile" run "rails:db_migrate" run "core:symlink_current"
...
end
→ The reference docs have a complete guide to tomo configuration.
→ Check out the Deploying Rails From Scratch tutorial for a step-by-step guide to using tomo with a real app.
Once your project is configured, you can:
tomo setupto prepare the remote host for its first deploy.
tomo deployto deploy your app.
tomo runto invoke one-off tasks, like launching a Rails console.
💡 Protip: add
-hor--helpwhen running any of these commands to see detailed docs and examples.
tomo setup
tomo setupprepares the remote host for its first deploy by sequentially running the
setuplist of tasks specified in
.tomo/config.rb. These tasks typically create directories, initialize data stores, install prerequisite tools, and perform other one-time actions that are necessary before a deploy can take place.
Out of the box, tomo will:
RAILS_ENVand
SECRET_KEY_BASE
→ Here is the default list of tasks invoked by the setup command.
→ The
tomo setupsection of the reference docs explains supported command-line options.
tomo deploy
Whereas
tomo setupis typically run once, you can use
tomo deployevery time you want to deploy a new version of your app. The deploy command will sequentially run the
deploylist of tasks specified in
.tomo/config.rb. You can customize this list to meet the needs of your app. By default, tomo runs these tasks:
💡 Protip: you can abbreviate tomo commands, like
tomo dfortomo deployortomo sfortomo setup.
→ Here is the default list of tasks invoked by the deploy command.
→ The
tomo deploysection of the reference docs explains supported command-line options, like
--dry-run.
tomo run [TASK]
Tomo can also
runindividual remote tasks on demand. You can use the
taskscommand to see the list of tasks tomo knows about.
One of the built-in Rails tasks is
rails:console, which brings up a fully-interactive Rails console over SSH.
💡 Protip: you can shorten this as
tomo rails:console(theruncommand is implied).
tomo runsection of the reference docs explains supported command-line options and has more examples.
Tomo has a powerful plugin system that lets you extend tomo by installing Ruby gems (e.g. tomo-plugin-sidekiq). You can also define plugins on the fly within your project by adding simple
.rbfiles to
.tomo/plugins/. These plugins can define tasks as plain ruby methods. For example:
# .tomo/plugins/my-plugin.rbdef hello remote.run "echo", "hello", settings[:application] end
Load your plugin in
config.rblike this:
# .tomo/config.rbplugin "./plugins/my-plugin.rb"
And run it!
→ The Writing Custom Tasks tutorial has an in-depth explanation of how plugins work.
→ The TaskLibrary API is tomo's DSL for building tasks.
→ The Publishing a Plugin tutorial explains how to package your plugin as a Ruby gem to share it with the community.
unsupported option "accept-new"error mean?
By default, tomo uses the "accept-new" value for the StrictHostKeyChecking option, which is supported by OpenSSH 7.6 and newer. If you are using an older version, this will cause an error. As a workaround, you can override tomo's default behavior like this:
# Replace "accept-new" with something compatible with older versions of SSH set ssh_strict_host_key_checking: true # or false
Tomo relies on the host user's bash profile for various things, like setting environment variables and initializing rbenv and nodenv. This makes it impractical to deploy multiple apps to a single host using the same deploy user.
The solution is to create multiple users on the remote host, and then configure a different user for deploying each app. That way each user can have its own distinct environment variables and you can easily configure each app differently without risking conflicts. Refer to the tomo Rails tutorial for instructions on creating a deploy user.
E.g. app1 would be configured to deploy as:
host "[email protected]"
And app2 would be configured to deploy as:
host "[email protected]"
Next run
tomo setupfor both apps; this will set everything up for both users on the remote host (environment variables, rbenv, etc.). You can now deploy both apps to the same host, with the confidence that their configurations will be kept cleanly separated.
This project is a labor of love and I can only spend a few hours a week maintaining it, at most. If you'd like to help by submitting a pull request, or if you've discovered a bug that needs my attention, please let me know. Check out CONTRIBUTING.md to get started. Happy hacking! —Matt
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Tomo project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Interested in filing a bug report, feature request, or opening a PR? Excellent! Please read the short CONTRIBUTING.md guidelines before you dive in.