As soon as you start working on multiple Rails projects with different dependencies, things often get complicated. You can use tools like Chruby, RVM, or Rbenv to manage versions of Ruby and gem, however, using Docker gives you even more flexibility.
A few years ago, I mostly used to work with Drupal. That’s when I had stumbled upon Lando – a tool that helps you dockerize your dev setup with ease.
Lando hides away certain complexities of Docker so that you can concentrate on your app instead of the Docker setup.
Recently, I started working on a Ruby on Rails project and I realized that Lando doesn’t have a recipe for Ruby on Rails. Thus began my endeavor to make Lando work with my Rails project. In this article, I’ll share my findings and walk through the steps it takes to make Rails work with Lando.
2 minute version
- Clone the lando-rails-example repository.
- For existing projects, read the prepare project directory section.
config/database.ymlbased on example.database.yml.
- Your Rails app should be available at
- To customize the setup, see:
- Basic Rails knowledge, at least the installation part.
- Basic Docker concepts, e.g. what an image and a container is.
- A working installation of Lando.
- My Lando version is
- My Lando version is
Step 1: Prepare project
You need a Rails app in order to use Lando with it.
If you don’t have a Rails app, you can start by cloning the lando-rails-example repository that contains code for this example.
If you already have a Rails app, copy the following files into the root of your app.
Step 2: Create Lando file
We begin by creating a Lando file, i.e.
.lando.yml containing the following top-level keys.
name: "lando-rails" proxy: appserver: - "rails.lndo.site:3000" services: # ... tooling: # ...
Here's a brief description of the various keys of the YML file:
- name: Project name. Docker container names will be derived from this name.
- proxy: Sets up a pretty URL for your Lando site.
- services: Services required by the project.
- tooling: Shortcuts for frequently-used commands.
A standard Rails app needs to store data in a database. Hence, we start by creating a database service. This example uses PostgreSQL, but you can use a different backend as well.
services: # ... database: type: postgres:12 portforward: true creds: database: ror_development user: postgres password: NO PASSWORD
Let’s take a quick look at what these settings do:
- type: Name of the database backend image.
- portforward: Exposes PostgreSQL port (5432) to the host machine. This allows you to connect to Postgres at
localhost:5432with tools like DataGrip.
- creds: Since the Lando file is only for dev envs, we simply include the database credentials in the Lando file itself.
This is the most complex part of the setup where we use a
Dockerfile to build a custom
ruby:rails image that fits into our Lando setup.
services: # ... appserver: type: compose services: image: ruby:rails command: "tail -f /dev/null" ports: - '3000' environment: DATABASE_USER: postgres DATABASE_PASS: '' RAILS_ENV: development overrides: build: ./lando/appserver build: - bundle install --gemfile=/app/Gemfile
Here’s a brief explanation of what the various
appserver.* keys defined above.
- type: The
composetype tells Lando to use a custom Docker image to build this service. This is used for services that Lando doesn’t support out of the box.
- services: Configures the custom service, i.e. Ruby on Rails in this case.
- overrides.build: Points to the directory containing a
Dockerfilethat will be used to build an image for the service. See the heading named Create Dockerfile.
- build: This contains commands that will be executed on top of the custom
ruby:railsimage being built by the
Now let’s take a look at the
- image: A name/tag for the custom image that’ll be built for this service.
- command: The command to execute when the container starts.
- ports: Exposes port
3000to which the Rails server listens.
- environment: Configure env vars, usually for configuring the Rails app. The
DATABASE_*variables are used in database.yml.
Having spent a bunch of time on
appserver.services.command while creating this example, I think it deserves a special mention. When the
appserver service starts, this command will be executed to keep the service running. I chose the harmless
tail -f /dev/null command which keeps
It is possible to run
rails server -b 0.0.0.0 here, however, there’s a catch. Say, you make some changes you made to the Rails app and the rails server fails to start due to these changes. In this case, the service container will refuse to start, thereby making it difficult to debug the problem.
Thus, this example discommends using
rails server as the command. You can start the rails server separately using the
lando rails-server command defined under
Step 3: Configure tooling
In any Docker setup, the app’s services run inside service containers. Issuing commands to these services from the host machine involves prefixing the command with
docker-compose exec SERVICE-NAME, followed by the command.
tooling section in your Lando file can create shortcuts to such commands.
tooling: rails: service: appserver cmd: bundle exec rails rails-server: service: appserver cmd: bundle exec rails server -d -b 0.0.0.0 rake: service: appserver
With the above setup, we can easily start the rails server with
lando rails-server. Also, we can issue any rails command with ease, e.g.
lando rails version.
Step 4: Create Dockerfile
Reference: The lando directory.
appserver.overrides.build section of the Lando file we told Lando to check the
lando/appserver directory for instructions on building the
ruby:rails image. We must ensure that a
Dockerfile and other supporting files are present in that directory.
Since this article is about configuring Lando, I won’t go into the details of the Dockerfile. You can use the Dockerfile provided with this example and modify it according to your needs.
Step 5: Configure Rails
To make the Rails app work, we need to configure it correctly.
- Ensure correct database connection parameters in
- You can base your configuration on example.database.yml.
Step 6: See it in action
Once all the pieces are in place, you can see your Docker setup in action:
lando start # Builds project images and starts the app. lando rails-server # Starts the Rails server.
Your Rails app should now be available at
The main advantage of using Lando are the easy-to-use recipes that come with it. Though there is no recipe for Ruby on Rails available at the moment, Lando has some helpful features that make life easy. The tooling configuration makes it easy to run commands in various service containers, and it is easy to add other services like Redis and Solr if required.
If you’re already using Lando for other projects, it might make sense to use Lando for your Rails dev envs. If you’re not a Lando user, it might make more sense to use Docker Compose instead.