To create a Rails API app that uses a PostgresQL database and run it using Docker Compose, you will need to complete the following steps:
Must be installed ruby 3.0.x and docker
1 Install rails gem
gem install rails
2 Create a new Rails API app by running the command
rails new my_api --api -d postgresql
3 Check your ruby version in Gemfile. The Rails version you are using may not support the latest Ruby version. Updating the Ruby version specified in the Gemfile to '~> 3.0' allows you to use a version of Ruby that is compatible with the version of Rails you are using.
ruby '~> 3.0'
4 Create a Dockerfile file in the root of your app with the following contents:
FROM ruby:3.0
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /my_api
WORKDIR /my_api
COPY Gemfile /my_api/Gemfile
COPY Gemfile.lock /my_api/Gemfile.lock
RUN bundle install
COPY . /my_api
CMD ["rails", "server", "-b", "0.0.0.0"]
The FROM instruction sets the base image for the Dockerfile, in this case ruby:3.0.
The RUN instruction runs a command in a new layer added to the image. The first RUN command updates the package lists and installs nodejs and postgresql-client packages.
The RUN command that follows creates a new directory called /my_api. The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile.
The COPY instruction copies files from the host file system to the container file system. The first COPY command copies the Gemfile and Gemfile.lock from the host to the /my_api directory in the container.
The next RUN command runs bundle install command to install the dependencies specified in the Gemfile and Gemfile.lock files.
The second COPY command copies all the files from the current directory on the host to the /my_api directory in the container.
The CMD instruction provides default command to execute when a container is created from the image. The command ["rails", "server", "-b", "0.0.0.0"] runs the rails server command with the option -b set to 0.0.0.0, which means that the server will bind to all available network interfaces.
5 Create a docker-compose.yml file in the root of your app as well. It should contain the following:
version: '3'
services:
db:
image: postgres
environment:
POSTGRES_USER: my_api
POSTGRES_PASSWORD: my_api
POSTGRES_DB: my_api_development
ports:
- "5432:5432"
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
environment:
POSTGRES_USER: my_api
POSTGRES_PASSWORD: my_api
POSTGRES_DB: my_api_development
volumes:
- .:/my_api
ports:
- "3000:3000"
depends_on:
- db
The version field specifies the version of the Compose file format. In this case, it is version 3.
The services field defines all the services that make up the application. It has two services defined: db and web.
The db service uses the postgres image and sets environment variables for the PostgreSQL user, password, and database name to be used. The ports field maps the host's port 5432 to the container's port 5432, allowing access to the PostgreSQL instance running in the container.
The web service uses the build field to specify that the image should be built from the current directory (.) and the command field to specify command that will be executed when the container starts. This command removes the server.pid file and runs the rails server command with options to listen on port 3000 and bind to all available network interfaces. It also sets environment variables for the PostgreSQL user, password, and database name to be used, which should match with the db service's environment variables.
The volumes field mount the current directory on the host to the /my_api directory in the container, allowing changes made on the host to be reflected in the container.
The ports field maps the host's port 3000 to the container's port 3000, allowing access to the Rails application running in the container.
The depends_on field specifies that the web service depends on the db service. This means that Compose will ensure that the db service is running before starting the web service.
6 Update the config/database.yml file to include the necessary information to connect to your PostgresQL database.
development:
<<: *default
database: <%= ENV['POSTGRES_DB'] %>
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
host: db
7 Add this simple endpoint to config/routes.rb
Rails.application.routes.draw do
get '/status', to: 'status#index'
end
8 Create a controller status_controller.rb in app/controllers with this content
class StatusController < ApplicationController
def index
render json: {status: 'OK'}
end
end
Run docker-compose build to build the images for your app and database
Run docker-compose up to start your app and database.
Check the first API endpoint in your Rails app:

Top comments (0)