Help:Toolforge/My first Ruby on Rails tool
This guide explains how to deploy a Ruby on Rails web application using Toolforge's build service. Although it's tailored for Rails applications, the same principles apply to deploying any Ruby web application.
A basic Rails app configured for the Toolforge Build Service is available in this repository. It's an adaptation of the official Getting started with Rails guide.This tutorial will focus on deployment aspects specific to Toolforge rather than on the app development itself.
Under the hood, Toolforge build service uses Heroku buildpacks to build and run your application. Heroku web applications require a
Procfile. This file is used to explicitly declare your application’s process types and entry points. It's located in the root of your repository.
Procfile is not technically required to deploy simple apps written in most Heroku-supported languages — the platform automatically detects the language and creates a default web process type to boot the application server. However, creating an explicit Procfile is recommended for greater control and flexibility over your app.
Procfile can contain several processes, such as different types of workers and scheduled jobs. For the sake of keeping things simple, we will only see two types of processes in this guide:
webThe web process is special in that it’s the only process type that can receive external HTTP traffic.
migrateThis is a process that will apply the database migrations. This process is not special – the name `migrate` is arbitrary and can be changed. So is the command that this process runs. We will see this in action later when we talk about the database.
Heroku buildpacks require the application to have a
Gemfile in the root directory. Even if an application has no gem dependencies it must include an empty
Gemfile to document that your app has no gem dependencies.
Particular actions are taken depending on the type of application deployed, which is determined by the following rules:
- Presence of
Gemfileindicates a Ruby application
- Presence of
config.ruindicates a Rack application
- Presence of
config/environment.rbindicates a Rails 2 application
- Presence of
config/application.rbcontaining the string Rails::Application indicates a Rails 3 application.
The example app provided is based on Rails 7.
Procfile for the example app is as follows:
migrate: bundle exec rake db:migrate
web: bundle exec puma -C config/puma.rb
This Procfile uses Puma, a high-performance Ruby web server. Following the official Rails guide ensures that your app includes the Puma gem and the
Toolforge build service builds your application from a public git repository. Your code will therefore need to be uploaded to a repository such as GitLab, GitHub, Bitbucket, or other.
If your Gemfile doesn’t contain a ruby entry, you get MRI 3.1.4.
Default rubies are locked into the app until you specify a Ruby version. For example, if your app is using a default Ruby version of 3.0.3, you continue to stay on 3.0.3.
We highly recommend specifying a Ruby version in your Gemfile and not relying on the default Ruby version.
Many Ruby applications use Node ecosystem tools to generate frontend assets. This is supported by the Toolforge build service, as long as there is a
package.json in the root of the project's repository.
Secrets & Config
For each environment variable needed in production, run the following command:
$ toolforge envvars create <NAME>
To check which environment variables you have currently set:
$ toolforge envvars list
If you change the variables or set new ones once the webservice is running, you will have to restart it manually for the changes to take effect. The environment variables will persist across restarts, so there's no need to set them again if you need to redeploy.
Some environment variables are available by default, such as the tool's data directory (
TOOL_DATA_DIR, used for NFS mounts) and the tool's database credentials, both for Toolsdb and the wikireplicas.
The example app uses SQLite3 for demonstration. However, using sqlite in production on Toolforge is discouraged due to NFS performance issues.
Here's the sqlite configuration in
database: <%= ENV['TOOL_DATA_DIR'] %>/db.sqlite3
To switch to Toolsdb, edit the configuration as shown and add the mysql2 gem to your Gemfile:
username: <%= ENV['TOOL_DATABASE_USER' %>
password: <%= ENV['TOOL_DATABASE_PASSWORD'] %>
- SSH into Toolforge
toolforge build start GIT_REPO
- Wait for the build to complete. You can check the status with
toolforge build show. When finished, the status should show 'ok (Succeeded)'
If needed, check the build logs with
toolforge build logs
Start the webservice
toolforge webservice buildservice start
- Wait for the webservice to spin up, then check the logs to see if everything went ok:
toolforge webservice logs -f
- Navigate to https://sample-ruby-rails-buildpack-app.toolforge.org/ to verify the application is working as expected.
DB migrations and other one-off jobs
One-off jobs, including db migrations, can be run using the Toolforge jobs framework. In the
Procfile we created above, we defined a `migrate` process type that will run
bundle exec rake db:migrate for us. Here is how we apply the migration:
$ toolforge jobs run --image tool-<tool-name>/tool-<tool-name>:latest --command "migrate" --no-filelog --wait --mount=all migrate
migrate at the end of the command is an arbitrary name that we give the job, while the
--command refers to the process with the same name in the
--mount=all is necessary here due to the app's use of the tool's home directory for the SQLite database. This wouldn't be required for ToolsDB or a Trove instance.
You can display the application logs with
toolforge webservice logs -f.
Communication and support
Support and administration of the WMCS resources is provided by the Wikimedia Foundation Cloud Services team and Wikimedia movement volunteers. Please reach out with questions and join the conversation: