This article shows how to deploy a typical Rails application with custom Dockerfile to Render. We’ll deploy Rails and Sidekiq processes as well as PostgreSQL and Redis databases. We’ll also see how to add automatic pull request previews.

Render

Render is a hosting company not too different from Heroku. There are two ways of deploying your applications to Render. We can either manually deploy services from the console interface, or with Render’s infrastructure as code by writing down a blueprint file.

PostgreSQL and Redis

Before we’ll deploy the Rails and Sidekiq process we’ll create databases so the services can connect successfuly during deploy.

Dockerfile considerations

Before we head down to add a new Rails service, we’ll edit the Business Class Dockerfile a little.

First we want to serve assets directly as we don’t have CDN at the moment. Uncomment the following line:

# Serve assets directly
ENV RAILS_SERVE_STATIC_FILES=true

Second, change the final CMD to include automatic check for migrations:

# Configure the main process to run when running the image
CMD bundle exec rails db:migrate && bundle exec puma -C config/puma.rb

This is important since Render currently doesn’t have a specific release step, so migrations have to happen during build time or before restarting the Rails process.

Rails and Sidekiq

Now we should be ready to add the main web and background processes.

After clicking “Create Web service” your new web service should start its build and be deployed in a couple of minutes.

Note: You can also store secret files (like .env or .npmrc files and private keys) in Render. These files will then be available during builds and in your code just like regular files.

Blueprint configuration

If we prefer to maintain our services in a more pragmatic way, we can write a blueprint file.

Here’s a complete blueprint for what we did manually in previous steps:

# render.yaml
# See https://render.com/docs/blueprint-spec for details
services:
  - type: web
    name: template_rails
    env: docker
    repo: https://gitlab.com/user/application.git
    region: oregon # optional (defaults to oregon)
    plan: free # optional (defaults to starter)
    branch: master # optional (defaults to master)
    numInstances: 1 # optional (defaults to 1)
    healthCheckPath: /
    envVars:
      - key: RUBY_VERSION
        value: "3.0.1"
      - key: SECRET_KEY_BASE
        value: "0e3b249272a7f1ea40b719317f677d2d54b3d1c5835c0292344a8de5b1a41f945cf7a70d15d8394ac96f01df867435a2aa8586ee9831d1b059ae5eea3b19fffd"
      - key: DATABASE_URL
        fromDatabase:
          name: template_db
          property: connectionString
      - key: REDIS_URL
        fromService:
          type: redis
          name: template_redis
          property: connectionString

  - type: worker
    name: sidekiq
    env: docker

  - type: redis
    name: template_redis
    ipAllowList: []
    plan: free # optional (defaults to starter)
    maxmemoryPolicy: noeviction # optional (defaults to allkeys-lru)

databases:
  - name: template_db
    databaseName: template_db # optional (Render may add a suffix)
    user: template_db # optional
    plan: free
    postgresMajorVersion: 15
    ipAllowList: []

The above blueprint file can be saved as render.yaml (note it cannot be render.yml) and added from the console under “Blueprints” tab next to the “Dashboard” link. Make sure the file is commited to the repository.

Conclusion

This is one of the most minimal Render setups for Ruby on Rails applications, including the default Business Class code, and apart from deploying a separate worker process can be even run for free (with the limitations of the free plan).