Help:Toolforge/My first Ruby on Rails tool

From Wikitech

Overview

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.

Example App

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.

Configuration

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.

A 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.

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

  1. web The web process is special in that it’s the only process type that can receive external HTTP traffic.
  2. migrate This 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.

Expected files

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 Gemfile indicates a Ruby application
  • Presence of config.ru indicates a Rack application
  • Presence of config/environment.rb indicates a Rails 2 application
  • Presence of config/application.rb containing the string Rails::Application indicates a Rails 3 application.

The example app provided is based on Rails 7.

Procfile

The 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 config/puma.rb configuration.

Git

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.

Ruby versions

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.

Node.js support

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.

Deployment

Configuration

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 /config/database.yml:

production:
  <<: *default
  database: <%= ENV['TOOL_DATA_DIR'] %>/db.sqlite3

To switch to Toolsdb, edit the configuration as shown and add the mysql2 gem to your Gemfile:

production:
  <<: *default
  adapter: mysql2
  host: tools.db.svc.wikimedia.cloud
  database: your-database-name
  username: <%= ENV['TOOL_DATABASE_USER'  %>
  password: <%= ENV['TOOL_DATABASE_PASSWORD']  %>

Build

  1. SSH into Toolforge
  2. become <tool-name>
  3. toolforge build start GIT_REPO
  4. 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

  1. toolforge webservice buildservice start
  2. Wait for the webservice to spin up, then check the logs to see if everything went ok: toolforge webservice logs -f
  3. 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

The migrate at the end of the command is an arbitrary name that we give the job, while the "migrate" after --command refers to the process with the same name in the Procfile.

--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.

Logs

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:

Discuss and receive general support
Stay aware of critical changes and plans
Track work tasks and report bugs

Use a subproject of the #Cloud-Services Phabricator project to track confirmed bug reports and feature requests about the Cloud Services infrastructure itself

Read stories and WMCS blog posts

Read the Cloud Services Blog (for the broader Wikimedia movement, see the Wikimedia Technical Blog)