Skip to content
ArtOfCode- edited this page Aug 7, 2025 · 1 revision

Encryption

Rails uses an encrypted file for storing the most sensitive configuration. For example, if you are using AWS your credentials would go into this encrypted file. By default, the repository contains the encrypted configuration file for Codidact's servers. However, since you don't have the encryption key, this file is useless to you.

One of the important entries in this file is the server secret. This is used as base for anything that needs encrypting, so you should set it to a unique value for your server.

  1. Delete the config/credentials.yml.enc you initially downloaded with the repository.
  2. Run EDITOR=nano RAILS_ENV=production bundle exec rails credentials:edit (you can change EDITOR to vim if you prefer vim)
  3. The secret key base will be set to a newly generated random hex key. If you want to set your own, you can run rails secret to have rails generate a new secret key that you can copy into the file.
  4. Save the file

Database

In config/database.yml rails expects a configuration of your database location and credentials, as well as the same information for redis. By default, the repository comes with a config/database.sample.yml file.

  1. Copy database.sample.yml to database.yml and open it in your editor.
  2. Decide on a database user for QPixel
  3. Create the MySQL user and grant it permission for the database you want to use. For example, in a mysql shell:
CREATE USER qpixel@localhost IDENTIFIED BY 'choose_a_password_here';
GRANT ALL ON qpixel_dev.* TO qpixel@localhost;
GRANT ALL ON qpixel_test.* TO qpixel@localhost;
GRANT ALL ON qpixel.* TO qpixel@localhost;
  1. Put the information in the config file and save.
  2. Specify the location of Redis (or leave the default).
  3. Run RAILS_ENV=production bundle exec rails db:create to create the database. If you get any errors, things may not be configured correctly.
  4. Run RAILS_ENV=production bundle exec rails db:schema:load to create the tables from the db/schema.rb definition (Note for MariaDB, see below)
  5. Run RAILS_ENV=production bundle exec rails r db/scripts/create_tags_path_view.rb
  6. Run RAILS_ENV=production bundle exec rails db:migrate to ensure that your schema contains all required migrations.
  7. QPixel needs timezone definitions to be loaded into MySQL for everything in QPixel to function properly. Follow the instructions at https://github.com/ankane/groupdate#for-mysql .

If you run into issues with multi-byte characters (such as emoji), make sure that your database is set to use utf8mb4.

MariaDB

If you want to use MariaDB instead of MySQL, you can do so. However, you will need to replace all occurrences of utf8mb4_0900_ai_ci with utf8mb4_unicode_ci in db/schema.rb. This is because MariaDB does not support utf8 v9. In practice you will probably not notice any major differences from these collation differences, only where the database is used for searching and sorting and special characters are important for the order.

Redis

Redis is used as semi-permanent cache storage by QPixel (it is a required component). It is essential that Redis is fast(er than your database), so it is recommended to run Redis on the same server as QPixel.

We recommend to configure Redis to have a maximum amount of memory it can use (to an appropriate amount for your server), and to use the least frequently used strategy (allkeys-lfu) to evict keys when Redis is full. The configuration (on Ubuntu) can be found under /etc/redis/redis.conf. You should set the following keys:

maxmemory <appropriate maximum>
maxmemory-policy allkeys-lfu

Storage

In QPixel users can upload files. These files have to go somewhere, and the configuration for this is in config/storage.yml. QPixel uses the ActiveStorage library for managing this, which in turn supports local storage and cloud storage. There is a sample file in config/storage.sample.yml.

  1. Copy the storage.sample.yml to storage.yml
  2. Set up your storage location(s). You can set multiple options here, and we will refer to them later by their name. For example, the following will save to <folder where qpixel is>/storage if local is set as the storage location.
local:
  service: Disk
  root: <%= Rails.root.join('storage') %>
  # root: '/absolute/path/here' if you want an absolute path
  1. In config/environments/production.rb, set:
config.active_storage.service = :name_of_your_selected_storage

to the name of the storage you want to use out of the ones available in storage.yml.

If you need more information on how to configure this, see their official tutorial at https://edgeguides.rubyonrails.org/active_storage_overview.html .

Email

The details of how rails runs your server are in config/environments/production.rb. For most settings you will not have to change the defaults already supplied, but there are a few important ones, one of which is for email.

  1. Set config.action_mailer.delivery_method to :smtp, :sendmail or :ses (Amazon SES).
  2. Set config.action_mailer.default_url_options to { host: 'your.site', protocol: 'https' }
  3. Set config.action_mailer.asset_host to 'https://your.site'

SMTP

If you are using smtp, you want to configure the following settings.

config.action_mailer.smtp_settings = {
  address: 'localhost',       # Default localhost
  port: 25,                   # Default 25
  domain: 'HELO domain',      # HELO Domain. Remove if not used
  user_name: 'user_name',     # Remove if no authentication is used
  password: 'password',       # Remove if no authentication is used
  authentication: :plain,     # Remove if no authentication is used. Options are :plain, :login and :cram_md5
  enable_starttls: false,     # Default false (but autodetect is by default enabled)
  enable_starttls_auto: true, # Autodetect starttls. Default true
  openssl_verify_mode: :none, # Openssl verify mode, either :none or :peer
  tls: true,                  # Enables SMTP/TLS (SMTPS). Remove if you don't want to use or are using starttls.
  open_timeout: 0,            # Nr of seconds to wait while attempting to open a call. Remove if you want default
  read_timeout: 0             # Nr of seconds before timeout a read call. Remove if you want default
}

You can find more details on each of the SMTP parameters at https://guides.rubyonrails.org/configuring.html#config-action-mailer-smtp-settings.

Sendmail

If you are using sendmail with non-default settings, you want to configure the following settings.

config.action_mailer.sendmail_settings = {
  location: '/path/to/sendmail', # Default is /usr/sbin/sendmail
  arguments: '-i' # The command line arguments, default is '-i'
}

SES

If you want to use Amazon SES, set the delivery method to :ses. Next, make sure your SES credentials are set in EDITOR=nano RAILS_ENV=production bundle exec rails credentials:edit. Finally, look at config/initializers/amazon_ses.rb and set it to the correct amazonaws server and signature version.

Devise (user accounts)

QPixel uses a framework called Devise for handling everything related to registration and authentication. There is an example configuration in config/initializers/devise_example.rb.

  1. Rename devise_example.rb to devise.rb (make sure devise_example.rb does not exist in parallel, otherwise it will override your settings)
  2. Run rails secret and copy the generated secret to config.secret_key (the one in the example is obviously insecure since it is publicly available!)
  3. Set config.mailer_sender to the name and email address you want to appear as sender for account related emails

There are many more settings in this file, all pretty decently explained. We have listed the most important ones that you may want to change below.

Keep users signed in
Set config.remember_for to the amount of time you want to keep a user signed in before they need to give their credentials again.

Password length
Set config.password_length to the range of password lengths you want to accept (e.g. 6..100 is between 6 and 100 inclusive).

Email regexp
Set config.email_regexp to a regex defining the email addresses you want to accept.

Locking accounts
It is possible to enable account locking after a certain number of invalid attempts. See the settings under :lockable and under :recoverable in the file.

SAML
If you want to use SAML sign in, follow the instructions at Setting Up SAML Sign In. We recommend that you first make sure QPixel fully runs on your server before going ahead with enabling the SAML configuration.

Scheduled jobs

QPixel uses cron jobs to schedule the emails it sends for subscriptions. The specification of this is in config/schedule.rb. You can modify the times in this file to send out the emails at different moments if you wish. To actually create the corresponding cronjobs from this schedule, run:

RAILS_ENV=production bundle exec whenever --update-crontab

You can also use RAILS_ENV=production bundle exec whenever to just see the created crontab, such that you can set it yourself.

Codidact network

A lot of the codebase expects that you are part of the Codidact network of communities. If you are not, you should alter config/initializers/zz_codidact_sites.rb to have the following content:

Rails.cache.persistent 'codidact_sites', clear: true do
  []
end

By default it will showcase Codidact communities in the navigation bar based on a list, but this will set it to not advertise any communities.

(Optional) Puma

In config/puma.rb you can specify the details of the server process. Here you can set the default amount of threads, port and pidfile of the server process. You can also set all of these with environment variables (PORT, PIDFILE, RAILS_MAX_THREADS, RAILS_MIN_THREADS) when calling rails s or by passing flags to this command instead.

(Optional) Content Security Policy

You can configure a content security policy in config/initializers/content_security_policy.rb. See the instructions in the file for more information.

(Optional) Donations

If you want to use Stripe for donations, set your stripe secrets with EDITOR=nano RAILS_ENV=production rails credentials:edit (stripe_live_secret).

(Optional) Version

By default QPixel uses git in the current repository to generate a version from the commit hash of the last commit. If you do not have the git repository in your server directory, then alter config/initializers/zz_cache_setup.rb to have the following content:

Rails.cache.persistent 'current_commit', clear: true do
  ['1.0', '2023-01-18 13:45:00 +0100']
end

You can set the date here to the date you last updated the system. There may be components which rely on the date being formatted in the way as shown in the example.

Finalizing

Congratulations, you got through the main configuration for the server (at least the things that are in the config folder).

Clone this wiki locally