RubyMine with Docker

Several humpback whales with open mouths feeding at the surface of the ocean.

Lately I've been experimenting with RubyMine. I've played around with it in the past, but always ended up back on vim for various reasons. This time I'm making a concerted effort to learn its feature set and make them work for me, and so far I'm thoroughly impressed.

Unfortunately I had some problems setting up Ruby/Rails projects running in Docker containers to work with RubyMine's debugging features, so I've documented how I did it and some of the issues I ran into.

Setting up a Rails Project

Let's start with a basic Rails API project with two containers: one for the app and one for the DB.

FROM ruby:3
RUN apt-get update -qq && apt-get install -y postgresql-client
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

Dockerfile

version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

docker-compose.yml

#!/usr/bin/env bash
set -e

rm -f /myapp/tmp/pids/server.pid

exec "$@"

entrypoint.sh

The full code is available on GitHub.

Running docker-compose up and navigating to localhost:3000 shows me the standard Rails welcome page. Now stop those containers and open the project in RubyMine.

The Ruby Interpreter

The first step is to set the correct Ruby interpreter, which lives in our Docker container.

Head to Settings ▸ Languages & Frameworks ▸ Ruby SDK and Gems. Click the "+" and select "Docker Compose". RubyMine should pre-fill most fields here, but you'll need to select the "Service" — or container — that your rails server is running inside. In our case, it's "web". Click OK and you should see a couple of progress indicators fly by.