Help:Toolforge/My first Ruby on Rails tool
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:
web
The web process is special in that it’s the only process type that can receive external HTTP traffic.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: mysql
host: tools.db.svc.wikimedia.cloud
database: your-database-name
username: <%= ENV['TOOL_DATABASE_USER' %>
password: <%= ENV['TOOL_DATABASE_PASSWORD'] %>
Build
- SSH into Toolforge
become <tool-name>
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
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:
- Chat in real time in the IRC channel #wikimedia-cloud connect or the bridged Telegram group
- Discuss via email after you have subscribed to the cloud@ mailing list
- Subscribe to the cloud-announce@ mailing list (all messages are also mirrored to the cloud@ list)
- Read the News wiki page
Use a subproject of the #Cloud-Services Phabricator project to track confirmed bug reports and feature requests about the Cloud Services infrastructure itself
Read the Cloud Services Blog (for the broader Wikimedia movement, see the Wikimedia Technical Blog)