Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Containerize your Ruby on Rails/PostgreSQL application with RHSCL Docker images

October 20, 2015
Josef Stříbný
Related topics:
ContainersLinux
Related products:
Red Hat Enterprise Linux

Share:

    New RHSCL-based Docker images that are now in beta let you easily build your own application containers even without writing any Dockerfiles. Here is an example of a Ruby on Rails application built with the Ruby 2.2 image using the PostgreSQL 9.4 image as a database backend.

    For building the application image we will use a tool called source-to-image (s2i, formally sti) which is a program that can build your application image on top of s2i images. For example the latest version of OpenShift uses s2i images to run your applications as well and you can use them with source-to-image to containerize your own applications locally.

    Prerequisites

    In this blog post I assume you are running RHEL 7 and you have the latest Docker from rhel-7-server-extras-rpms channel and that you enabled rhel-server-rhscl-7-beta-rpms channel for getting the source-to-image tool.

    If you did not, run:

    $ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
    $ sudo subscription-manager repos --enable=rhel-server-rhscl-7-beta-rpms
    $ sudo yum install -y docker source-to-image
    

    Database setup

    To use PostgreSQL image we need to provide the database user, password and name. We also need to map ports from the container to the host and map the data directory from the container to somewhere else.

    For now let's assume we want to use /data directory to store our application data:

    $ sudo mkdir -p /data
    $ sudo chmod a+rwx /data
    $ sudo chcon -t svirt_sandbox_file_t /data
    

    We need svirt_sandbox_file_t label if we are using SELinux with Docker.

    And export application password if we did not yet expose it:

    $ export APP_DATABASE_PASSWORD=password1
    

    Afterwards everything is ready to start the Docker daemon and run our database container:

    $ sudo systemctl start docker
    $ sudo docker run -d --name db -e POSTGRESQL_USER=app -e POSTGRESQL_PASSWORD=$APP_DATABASE_PASSWORD -e POSTGRESQL_DATABASE=app_production -p 5432:5432 -v /data:/var/lib/pgsql/data rhscl_beta/postgresql-94-rhel7
    

    The command above run RHSCL rhscl_beta/postgresql-94-rhel7 image in the background (-d) with the required username (app), password ($APP_DATABASE_PASSWORD from the environment) and name (app_production) while mapping the PostgreSQL standard port 5432 to the same one on the host (-p). -v option at the end then specifies volume mounts telling Docker to use our /data directory. We call this container db (--name). The name just makes it easier to reference it in the next steps.

    Use docker ps command to check that the database is running as expected (if the database is not running, it was stopped for some reason):

    $ sudo docker ps
    CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                    NAMES
    8293e4586ba0        rhscl_beta/postgresql-94-rhel7   "run-postgresql.sh p   12 seconds ago      Up 11 seconds       0.0.0.0:5432->5432/tcp   db
    

    Rails application setup

    For our example we need a Rails application powered by PostgreSQL database. We could use any Rails app from any remote git repository, but for the sake of completeness we create one. Therefore we need to install some dependencies first:

    $ sudo yum install -y libxml2-devel ruby-devel postgresql-devel gcc-c++ patch redhat-rpm-config nodejs curl git
    

    We need libxml2-devel, ruby-devel, postgresql-devel, gcc-c++, patch, redhat-rpm-config for installing Ruby on Rails and application dependencies, git for creating a repository and curl for checking out the results.

    Once done, install Ruby on Rails and create a brand new application with the PostgreSQL backend:

    $ gem install rails
    $ rails new app --database=postgresql && cd app
    

    To take advantage of our PostgreSQL database we build a simple ToDo lists management into our app:

    $ bin/rails generate scaffold todo_list title:string description:text
    

    Specify the database connection in config/database.yml as:

    ...
    production:
      <<: *default
      url: postgres://<%= ENV['APP_DATABASE_USER'] %>:<%= ENV['APP_DATABASE_PASSWORD'] %>@<%= ENV['APP_DATABASE_HOST'] %>/<%= ENV['APP_DATABASE_NAME'] %>
    

    As you can see we will want to connect to the $APP_DATABASE_NAME database with the $APP_DATABASE_USER database user and $APP_DATABASE_PASSWORD password to a PostgreSQL running on a given $APP_DATABASE_HOST host.

    And run bundle command to create Gemfile.lock:

    RAILS_ENV=production bundle
    

    As we are finished building the application let's check it in the source control:

    $ git init && git add * -f
    $ git config --global user.name "Git username"
    $ git commit -am 'Initial commit'
    

    The latest upstream version of source-to-image tool should not require the git repository to be created, but old versions do.

    Building the application container

    To build the application container we will use RHSCL-based rhscl_beta/ruby-22-rhel7 image with Ruby 2.2 and source-to-image tool. rhscl_beta/ruby-22-rhel7 is s2i image meaning it contains assemble s2i script that can build the application image for us.

    Install source-to-image if you haven't yet and create a new application image called app:

    $ sudo s2i build file:///$PWD rhscl_beta/ruby-22-rhel7 app
    

    First argument is our current working directory (file:///$PWD, it could be any git repository), second is the name of our s2i image and last the name of the new application image to create.

    By default it will use production environment which we want, but you could change RACK_ENV variable to something else in .s2i/environment file to avoid it.

    $ sudo docker images
    REPOSITORY                                                  TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    app                                                         latest              ee406846e337        23 seconds ago      523.6 MB
    registry.access.redhat.com/rhscl_beta/ruby-22-rhel7         latest              a6c37f6f13e2        2 weeks ago         466.4 MB
    registry.access.redhat.com/rhscl_beta/postgresql-94-rhel7   latest              20a1960468dc        3 weeks ago         236 MB
    

    We have just build a Rails application in a container without writing any Dockerfile, how nice!

    Running the containers

    Our database container is already running, but to run our Rails application container we need to set two things. Database access and secret key base (a long randomized string which is used to verify the integrity of signed cookies used in Rails by default).

    Create a secret key base and export it:

    $ RAILS_ENV=production rake secret
    d68735d681db2ef0639f149e45bb11c805e1e46ae309b464541b89ab91b589dc8e94bc9e86508b8e35f6c5d5a5e1b48a6cef4ff9c7113b851267a021e3659e10
    
    $ export SECRET_KEY_BASE=d68735d681db2ef0639f149e45bb11c805e1e46ae309b464541b89ab91b589dc8e94bc9e86508b8e35f6c5d5a5e1b48a6cef4ff9c7113b851267a021e3659e10
    

    Last missing piece of configuration is the IP address of our database server:

    $ sudo docker inspect db | grep '"IPAddress"'
            "IPAddress": "172.17.0.42",
    $ export APP_DATABASE_HOST=172.17.0.42
    

    (Yes, we could avoid that by using Docker linking ability by specifying DB_PORT_5432_TCP_ADDR instead of APP_DATABASE_HOST in our config/database.yml. We would then run our application image with --link db:db option.)

    But let's not forget that this is our new application and so we did not even run our database migrations which has to be done beforehand. The commands themselves will be pretty similar. First we run rake db:migrate and later we run our container in the background (-d) without arguments which will run the container entrypoint (in our case the s2i run script which will eventually run rackup).

    Migrations:

    $ sudo docker run -e APP_DATABASE_USER=app -e APP_DATABASE_PASSWORD=$APP_DATABASE_PASSWORD -e APP_DATABASE_NAME=app_production -e APP_DATABASE_HOST=172.17.0.42 -e SECRET_KEY_BASE=$SECRET_KEY_BASE -e RAILS_ENV=production -p 8080:8080 app rake db:migrate
    

    Running the app itself:

    $ sudo docker run -d --name=app -e APP_DATABASE_USER=app -e APP_DATABASE_PASSWORD=$APP_DATABASE_PASSWORD -e APP_DATABASE_NAME=app_production -e APP_DATABASE_HOST=$APP_DATABASE_HOST -e SECRET_KEY_BASE=$SECRET_KEY_BASE -e RAILS_ENV=production -p 8080:8080 -e app
    

    As with our database image we needed to specify all the required environment variables — for connecting to the database, RAILS_ENV=production for the production setup of the Rails app and -p 8080:8080 to map the container port to the same one on the host. In the last command we also name our container as app.

    Check that both db and app containers are running:

    $ sudo docker ps
    CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                    NAMES
    d29efb225a5f        app                              "container-entrypoin   6 seconds ago       Up 5 seconds        0.0.0.0:8080->8080/tcp   app
    8293e4586ba0        rhscl_beta/postgresql-94-rhel7   "run-postgresql.sh p   About an hour ago   Up About an hour    0.0.0.0:5432->5432/tcp   db
    

    If not try docker logs db and docker logs app commands to investigate.

    If they are both running you should be able to fetch the index of our ToDo list controller:

    $ curl 0.0.0.0:8080/todo_lists
    ...
    <h1>Listing Todo Lists</h1>
    
    <table>
      <thead>
        <tr>
          <th>Title</th>
          <th>Description</th>
          <th colspan="3"></th>
        </tr>
      </thead>
    
      <tbody>
      </tbody>
    </table>
    ...
    

    That should mean everything works. You can now visit http://0.0.0.0:8080/todo_lists in your browser, add some items and check that our PostgreSQL database at /data/userdata/ is getting filled up.

    And that's it! We created a new application image for our Ruby on Rails application with source-to-image tool and RHSCL Ruby 2.2 image and made it to save data to /data using the PostgreSQL RHSCL image.

    Last updated: November 1, 2023

    Recent Posts

    • The benefits of auto-merging GitHub and GitLab repositories

    • Supercharging AI isolation: microVMs with RamaLama & libkrun

    • Simplify multi-VPC connectivity with amazon.aws 9.0.0

    • How HaProxy router settings affect middleware applications

    • Fly Eagle(3) fly: Faster inference with vLLM & speculative decoding

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue