Qoddi automatically builds your Ruby app.
In order to do that, Qoddi uses buildpacks to detect and build your app automatically.

Before Building your code

Qoddi requires several files to be placed inside the root directory of your app to be able to build it :

  • Gemfile (and Gemfile.lock generated by the bundle install command)
  • Procfile
  • file for web-serving applications using Rake

You can fork or build this repository to get started with Ruby on Qoddi

Create your app on Qoddi

Create a new app and link it with your repository using SSH keys.

Read this article for a detailed procedure or check this video :


A Gemfile is mandatory for your app to be able to build. Gemfile is the main configuration file of your Ruby app.

Run locally bundle install to generate the Gemfile.lock and make sure it’s available on your repository before building your app.

Specifying the Ruby version

Qoddi lets you build with different Ruby implementations. You can configure your app to select a specific runtime.

If your Gemfile does not contain a ruby entry, you will get MRI 3.1.2

The builder automatically uses the last available version if a ruby version is not specified. There is no lock-in to a specific version like with several other cloud providers.

We highly recommend specifying a Ruby version in your Gemfile and not relying on the default Ruby version.

Supported runtimes

Qoddi supports the following versions of Ruby and the associated Rubygems :


3.1.3, Rubygems 3.3.26

The oldest supported version is Ruby 3.1.0


  •, Ruby Versions: [2.3.3]
  •, Ruby Versions: [2.5.8]
  •, Ruby Versions: [2.6.8]

You can use the ruby keyword in your app’s Gemfile to specify a specific version of Ruby :

source ""
ruby "3.1.1"

For specifying non-MRI Ruby engines, you’ll need to use the :engine and :engine_version options. You can specify JRuby by using the following line:

ruby "2.6.8", :engine => "jruby", :engine_version => ""


The Procfile informs the engine of the type of app you are running and prepares the infrastructure accordingly. On Qoddi the Procfile always starts by web: regardless if your app is a worker or a web app. To expose your app to Internet traffic you can change the settings on the app settings page.

The Procfile basically contains the type of app and the initial script to run when the app starts :

web: bundle exec ruby server.rb

or with Puma:

web: bundle exec puma -C config/puma.rb

Declare app dependencies

Qoddi uses the Gemfile to build dependencies and it must contain all the dependencies your app needs to run.

A gemfile.lock file must also be committed to your repository, check the section “prepare your app”.

For instance, in our example, the Gemfile looks like that :

# frozen_string_literal: true

source ""

git_source(:github) {|repo_name| "{repo_name}" }

# gem "rails"

gem "puma", "~> 4.3"

gem "sinatra", "~> 2.0"

gem "cowsay", "~> 0.3.0"

Default Behavior

By default, your Ruby app is routed to the 8080 port of the container. If you need to change the instance port of your app you can do it from the app settings page by changing the network setting and the environment variable.

Note: you can set up any container port, but Qoddi will only route 80/443 traffic to your app. Qoddi’s apps are not reachable from the outside of Qoddi on any other port.

Support for Rack and additional buildpack support

By default, the Ruby buildpack uses Ruby 3.1.3 with limited support for web applications.

Adding a file will automatically extend the buildpack and add the support for Rack-based servers to start the application.

Ruby Default Web Server

If you don’t specify a Procfile, the default webserver will be used. That means bundle exec rackup for Rack and rails server for Rails.

Depending on the version of these libraries you are using and what gems you have in your Gemfile, the WEBrick server may be used to run your production application.

Even if your application does not use WEBrick, it is HIGHLY recommended you do not rely on this implicit behavior and instead explicitly declare how you want your webserver started via a Procfile. If you don’t have a preference, we recommend using Puma as a web server.

We don’t recommend the use of WEBrick in production.

Please check this article for detailed installation instructions.

Install Puma as Web Server

Puma uses resources efficiently and avoids a lot of bottlenecks while running your Ruby application.

To install start by adding it inside your Gemfile:

gem 'puma'

Set Puma as your web server inside your Procfile :

web: bundle exec puma -C config/puma.rb

Note: you can also add variables inside the Procfile like -e ${RACK_ENV:-development}

Create a configuration file for Puma at config/puma.rb or at a path of your choosing. For a simple Rails application, we recommend the following basic configuration:

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count


rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'production'

on_worker_boot do
  # Worker specific setup for Rails 4.1+

Make sure that your app uses the port 3000 OR update the env variable PORT to the port used by your application inside your app settings page!

You can create an ENV Variable inside your app settings with the WEB_CONCURRENCY and adapt its value depending on your app size. For Free apps, we don’t recommend more than 2-4 concurrent threads. Monitor your app resource usage while increasing this parameter as needed.

The Environment variable RACK_ENV can be added to your app settings to choose between development and production (default to production).

Launch a Console Command

Please check this article on how to launch a command directly to your running app. This can be used to perform database migrations, launch local scripts, or perform database backups.

Ephemeral Disk

Contrary to Marketplace apps that can use Qoddi’s virtual disk features to store and retrieve persistent data, apps created from code use an immutable file system.

For instance, you can temporarily write data locally to process files during your application’s life. Still, the data written into your app’s disk is not persistent and gets wiped out after your app restart.

All apps restart at least once every 24 hours to apply a new setting or to deploy a new build.

To store data and keep it persistent you can use external services like Amazon S3 or Wasabi, an S3-compatible storage service with very affordable pricing.

Add a domain name

Please check this article for a detailed method on how to use your domain name with Qoddi apps.

Define environment variables

Note: Environment variables in your app settings are injected during the build process. If the build of your app needs to use an env variable, make sure to set it before requesting the build.

Qoddi lets you externalize your app’s configuration: the Qoddi cluster will automatically inject the data when the app starts or restart.

Environment variables can include any external data your app needs to run, like external resources, database addresses, encryption keys, etc…

To add an environment variable, access your app settings and click “Add ENV Variable” :

Enter the key (like DATABASE_USER) and the value and click “Add”. Qoddi will automatically add your environment variable and restart your app after a one-minute delay (to let you add more env variables if necessary without restarting the app each time a new variable is added).

Provision a database

Qoddi Marketplace includes all popular datastore engines, including Mysql, Postgres, MongoDB, and Redis.
To add a database to your app, click on Marketplace and select the database you want to run, then create the new app database inside the same stack as your Ruby app.

Once the app is running, visit the database app’s settings and retrieve the “internal name” :

Use this internal name as you would use a server address, for instance for MySQL this name replaces the usual “localhost”. Some scripts require you to add the database port at the end of the server address. Qoddi uses a common port for each database software, for MySQL it will be 3306 and you can write it like that inside your scripts: internal-name:3306
Postgres usually uses credentials sent inside the login URL, like that : postgres://<user>:<password>@<internalname>:5432/<database>

The login and password information is available inside the Environment Variables of the database app.

Note: Qoddi’s datastores run on a private and encrypted network. Therefore SSL support is deactivated for all datastores available on Qoddi. Ensure that your code doesn’t require using SSL before deploying your app.

Reach your app from another app

Inside your app stack, you can reach any other Qoddi app member of this stack on any port. Qoddi automatically routes the traffic internally and opens the appropriate port. By opposition, your app is only reachable on ports 80/443 outside Qoddi.

To reach your app internally, retrieve the internal name from your app settings page :

This name can be used to reach your app from another app inside the same stack. Use it in any form that works with your script :


Note: https:// is not available, all the traffic inside apps is already encrypted by the cluster.

Migrate the database

If your application uses a database, you may need to launch a command to migrate the database before the application can start. This can be done from your app settings page under Console Commands.


Qoddi uses at-rest encryption for the app’s virtual disks, builds images, and encrypts transport inside the cluster. To make sure the traffic is encrypted between your app and the browser of your users you can set up SSL certificates for any domain name connected to the app (including Qoddi’s default domain name).

Scale your App

From your app settings, you can scale your app vertically and horizontally: by upgrading the app size (refer to our pricing for app sizes details) or by adding more nodes.

Additional nodes will run another copy of your app inside another Qoddi server located inside the same cluster (same geographical location). Traffic is automatically sent to the least occupied node by Qoddi’s load balancer.

Was this helpful?

5 / 3