Skip to main content
March 23, 2026Noble Desktop Publishing Team/7 min read

Getting ready to Deploy

Preparing Rails Applications for Production Deployment

Development to Production Transition

After fourteen sections of local development, this tutorial marks the critical transition from local development environment to production-ready deployment. This involves upgrading from SQLite to PostgreSQL and implementing image storage capabilities.

Topics Covered in This Ruby on Rails Tutorial:

Adding an Image to the Cookbook, Introducing PostgreSQL

Exercise Overview

After covering the fundamentals across fourteen comprehensive sections, we've built a solid foundation in Rails development. However, everything we've accomplished has remained confined to our local development environment. It's time to prepare your applications for the real world—where they'll face actual traffic, user interactions, and production challenges.

This section bridges the gap between development and deployment by enhancing our cookbook application with production-ready features. We'll leverage Active Storage to implement image uploads—a critical feature in modern web applications—and configure AWS S3 for scalable media storage.

Additionally, we'll transition from SQLite to PostgreSQL, the industry-standard database that powers countless production Rails applications. This shift isn't just about compatibility; it's about understanding the architectural decisions that separate hobby projects from professional applications.

Deployment Preparation Process

1

Add Image Support

Integrate Active Storage with image processing capabilities to handle file uploads for recipe images

2

Install PostgreSQL

Replace SQLite with PostgreSQL database system for production-level performance and reliability

3

Configure Database

Set up PostgreSQL user roles, permissions, and Rails database configuration

Adding an Image to the Cookbook

Visual content drives user engagement, and recipe applications particularly benefit from appetizing imagery. Let's implement a robust image upload system using Rails' Active Storage framework.

  1. Navigate back to your cookbook application directory and open it in your preferred code editor. Ensure you have both your editor and Terminal positioned for efficient workflow.

  2. Launch Terminal in your cookbook directory. This dual-window setup should feel natural by now—it's the standard workflow for professional Rails development.

  3. Open your Gemfile and locate line 26. Uncomment the image processing gem, which provides the ImageMagick bindings necessary for image manipulation:

    gem 'image_processing', '~> 1.2'
  4. Save the file to commit your changes.

  5. Return to Terminal and install the new dependency:

    bundle
  6. Initialize Active Storage, Rails' built-in solution for handling file uploads. Execute these commands to generate the necessary database tables and run the migration:

    rails active_storage:install
    rails db:migrate
  7. Modify your Recipe model to establish the attachment relationship. This single line enables your recipes to store associated images:

    class Recipe < ApplicationRecord
      has_one_attached :image
        end
  8. Start your Rails server in a separate Terminal window to test changes in real-time:

    rails s
  9. Update the form partial at app > views > recipes > _form.html.erb to include a file upload field. This addition seamlessly integrates with Rails' form helpers:

    <%= form.text_area :directions %>
      </div>
    
      <div class="field">
        <%= form.label :image %>
        <%= form.file_field :image %>
      </div>
    
      <div class="actions">
        <%= form.submit %>
  10. Configure the recipes controller at app > controllers > recipes_controller.rb to accept image uploads through strong parameters:

    def recipe_params
            params.require(:recipe).permit(:title, :description, :prep_time, :ingredients, :directions,  :image)
    end
  11. Enhance the recipe detail view at app > views > recipes > show.html.erb to display uploaded images. The conditional check prevents errors when no image is attached:

    <%= @recipe.title %>
    </h1>
    
    <% if @recipe.image.attached? %>
      <p>
        <%= image_tag(@recipe.image.variant(resize: "400x400")) if @recipe.image.attached? %>
      </p>
    <% end %>
    
    <p>
      <em><%= @recipe.description %></em>
  12. Add thumbnail images to your index page for improved visual hierarchy. Modify app > views > recipes > index.html.erb:

    <thead>
        <tr>
          <th>Image</th>
          <th>Title</th>
          <th>Prep time</th>
    <% @recipes.each do |recipe| %>
          <tr>
            <td><%= image_tag(recipe.image.variant(resize: "100x100")) if recipe.image.attached? %></td>
            <td><%= recipe.title %></td>
  13. Test your implementation by navigating to http://localhost:3000. Edit an existing recipe, upload the pasta.jpg image from your snippets directory, and observe the results. You've successfully implemented a professional-grade image upload system.

Active Storage Implementation Checklist

0/5

Image Processing Features

Variant Resizing

Images are automatically resized to 400x400 pixels on detail pages and 100x100 pixels on index pages for optimal performance and consistent display.

Conditional Display

Images only render when attached, preventing broken image links and maintaining clean layouts when no image is present.

Introducing PostgreSQL

While SQLite serves development needs admirably, production applications demand more robust database solutions. SQLite's file-based architecture, though convenient for prototyping, buckles under concurrent user loads and lacks the advanced features required for scalable applications.

Professional Rails applications typically employ dedicated database servers capable of handling complex queries, concurrent connections, and high-availability requirements. Popular enterprise options include:

PostgreSQL stands out as the preferred choice for Rails applications, particularly in cloud deployment scenarios. Its open-source nature, exceptional performance characteristics, and comprehensive feature set make it the default database for platforms like Heroku. As we prepare for cloud deployment, PostgreSQL proficiency becomes essential.

SQLite vs PostgreSQL for Production

FeatureSQLitePostgreSQL
Traffic HandlingLimited (Lite)High Volume
Setup ComplexitySimpleModerate
Production ReadyNoYes
Heroku SupportNot AllowedRequired
Recommended: PostgreSQL is essential for production deployments due to its robust performance under load and Heroku compatibility requirements.

Popular Database Options for Rails

PostgreSQL

Open source database with excellent Rails integration. Required for Heroku deployment and offers robust performance under heavy traffic loads.

MySQL

Widely used open source database with strong community support. Good alternative to PostgreSQL with similar performance characteristics.

Microsoft SQL Server

Enterprise-grade database solution with comprehensive features. Well-suited for organizations already invested in Microsoft ecosystem.

Installing PostgreSQL

Setting up PostgreSQL locally ensures development-production parity and enables seamless database synchronization between environments. This configuration is crucial for debugging production issues and maintaining data consistency.

  1. Install PostgreSQL on your local machine using Homebrew (macOS users). This local instance will mirror your production database environment:

    brew install postgresql
  2. Start PostgreSQL and configure it to launch automatically on system startup. This ensures your development environment remains consistent:

    pg_ctl -D /usr/local/var/postgresql start && brew services start postgresql
  3. Verify successful installation by looking for this confirmation message:

    ==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
  4. Unlike SQLite's zero-configuration approach, PostgreSQL requires user management and database creation. Access the PostgreSQL console to begin setup:

    psql postgres
  5. You'll see the PostgreSQL command prompt, indicating successful connection:

    psql (11.4)
    Type "help" for help.
    
    postgres=#

    This interactive console accepts SQL commands and PostgreSQL-specific administrative functions.

  6. Examine existing database users with the \du command, which lists all roles (PostgreSQL's term for user accounts):

    postgres=# \du
                                   List of roles
     Role name |                         Attributes                         | Member of—————-+——————————————————————————————+—————-
     matt      | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
  7. Create a dedicated role for your Rails application following the principle of least privilege. This approach enhances security by limiting database access:

    CREATE ROLE cookbook WITH LOGIN PASSWORD 'booksRcooked';

    Replace cookbook and booksRcooked with more secure credentials appropriate for your project. In production, use environment variables for credential management.

  8. Grant database creation privileges to your new role. Rails requires this capability for running migrations and managing database schema:

    ALTER ROLE cookbook CREATEDB;

    Run \du again to confirm the privilege assignment.

  9. Exit the superuser session and reconnect as your application user:

    \q
  10. Reconnect to PostgreSQL using your application credentials:

    psql postgres -U cookbook
  11. Create your application database using standard SQL syntax:

    CREATE DATABASE cookbook;
  12. Verify database creation with the \list command:

    postgres=> \list
                           List of databases
       Name    |  Owner   | Encoding | Collate | Ctype | Access privileges—————-+—————+—————+————-+———-+—————————-
     cookbook  | cookbook | UTF8     | C       | C     | 
     postgres  | matt     | UTF8     | C       | C     | 
     template0 | matt     | UTF8     | C       | C     | =c/matt          +
           |          |          |         |       | matt=CTc/matt
     template1 | matt     | UTF8     | C       | C     | =c/matt          +
           |          |          |         |       | matt=CTc/matt
    (4 rows)

    Your cookbook database now exists and is ready for Rails integration.

  13. Exit the PostgreSQL console and return to Rails configuration:

    \q
  14. Add the PostgreSQL adapter gem to your Gemfile. This gem provides the interface between Rails and PostgreSQL:

    gem 'pg'
  15. Remove SQLite3 from your Gemfile to ensure Heroku compatibility. Cloud platforms reject applications containing SQLite dependencies. Delete these lines completely:

    # Use sqlite3 as the database for Active Record
    gem 'sqlite3', '~> 1.4'
  16. Install the updated dependencies:

    bundle
  17. Configure Rails to use PostgreSQL by updating config > database.yml. This file defines database connections for different environments:

    default: &default
      adapter: postgresql
      encoding: unicode
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
      timeout: 5000
    
    development:
      <<: default
      database: cookbook
      username: cookbook
      password: booksRcooked
      host: localhost
  18. Execute your existing migrations against the new PostgreSQL database:

    rails db:migrate

    You should observe both CreateRecipes and CreateActiveStorageTables migrations executing successfully.

  19. Visit http://localhost:3000 to confirm your application functions correctly. The database transition will have cleared existing data—this is expected behavior when switching database systems. You're now running a production-ready database configuration locally.

PostgreSQL Installation and Setup

1

Install via Homebrew

Use 'brew install postgresql' to install PostgreSQL on Mac systems with automatic dependency management

2

Start Service

Start PostgreSQL and configure automatic startup with 'pg_ctl start && brew services start postgresql'

3

Create Application User

Create dedicated Rails application user with 'CREATE ROLE cookbook WITH LOGIN PASSWORD' for security isolation

4

Grant Database Permissions

Add CREATEDB privilege with 'ALTER ROLE cookbook CREATEDB' to enable Rails database operations

5

Configure Rails

Update Gemfile and database.yml configuration to use PostgreSQL adapter with connection credentials

Heroku Deployment Requirement

The sqlite3 gem must be completely removed from the Gemfile, not just commented out, as Heroku will reject deployments containing SQLite dependencies.

Essential PostgreSQL Commands

Master these PostgreSQL console commands for efficient database management:

  • \list—List all databases in the PostgreSQL instance.
  • \c [databasename]—Switch active database connection.
  • \dt—List tables for the currently active database.
  • \d [tablename]—Display detailed schema information for a specific table.
  • \du—List all database users and their assigned roles.
  • \q—Exit the psql console and return to the system terminal.

Key Takeaways

1Active Storage integration requires uncommenting the image_processing gem and running installation migrations to enable file attachment capabilities
2PostgreSQL is essential for production Rails deployments due to superior traffic handling and Heroku hosting requirements
3SQLite gem must be completely removed from Gemfile for successful Heroku deployment, not just commented out
4PostgreSQL setup involves creating dedicated application users with CREATEDB privileges for security and functionality
5Image variants allow automatic resizing for different display contexts, improving performance and user experience
6Database switching from SQLite to PostgreSQL results in data loss, requiring planning for data recreation or migration
7PostgreSQL offers multiple popular alternatives including MySQL and SQL Server, all supported by Rails framework
8Production database configuration requires updating both Gemfile dependencies and database.yml connection settings

RELATED ARTICLES