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:
Latest comments (0)