Using Docker for Ruby on Rails development on Windows
Tested with Windows 10.
tl;dr: Docker configs are available at GitHub: https://github.com/sheroz/docker-rails
Life is an amazing teacher. For the past two and half years I worked full-time on a project based on Ruby language and Rails framework. It was a unique experience after having many years of C/C++ and Java development. Having a foreigner status in a new country and being thousands of kilometers away from my homeland, I had to accept a challenging offer from a very ambitious startup company and jump immediately into the magical Ruby on Rails world. The company provided me with a MacBook Pro laptop, and I found that the Ruby development on macOS is great! But…
Imagine that you are a Ruby on Rails developer in a startup...
It was my first experience with startups. I found that startups are a very different world. Sometimes, I think that if Cervantes was alive, maybe he would re-write his famous book about Don Quixote according to the adventures of the heroes of our time, who decided to become modern knight-errant at startups.
You are finally at home after long hours (or days) of office rush with tight deadlines, endless meetings, calls, and other distractions...
I believe that software engineering is an art and science. The relationship between creativity and stress is a complex subject. Normally, quality and creativity are the opposite of rush, stress, and distractions. Furthermore, software engineering is a hard and mentally exhausting process. While pushing developers gives an imaginary gain in productivity in the short-term, the product developed under high pressure probably would include baked-in time bombs.
People may think that software developers work only for a fixed time when they are in the office in front of their computers. That's not fairly true. As far as I know, when a developer is motivated and engaged, his brain works 7/24 to solve faced challenges.
So, you are at home and while you drink a cup of tea (or coffee) with your loved ones in a warm atmosphere, this creative moment probably will be caught by your relaxed and happy brain that will start to remember and analyze unsolved challenges in the background, and... suddenly, you see the bright solution to the interesting challenge that you had no single chance to overcome at the office. You are eager to convert the idea into code, but... unfortunately, you left your work laptop in the office (Due to the terrible traffic, of course. No laptop can survive if you carry it daily in over-crowded Istanbul traffic) and you have only your home PC that seems completely useless in front of Ruby on Rails... While setting up the Ruby on Rails development environment is native on Linux and macOS, it is not straightforward on Windows. I have always used my home PC to make small changes, urgent hotfixes, or to prove new ideas before.
I found some workarounds for doing RoR development on Windows, using:
- RailsInstaller (RubyInstaller for Windows)
- Windows Subsystem for Linux (WSL)
- VM tools (like VMWare, VirtualBox, Vagrant)
I tried (1) and (2) options. It works and may be usable in small projects. But, in the case of a complex RoR project, the performance was not acceptable for doing any real development.
I did not try to use VM-based solutions. I know that VM would work and overall performance would be acceptable. But I think the Docker-based solution is more promising and flexible. It can make the setup process of the development environment easier and be used as a part of IaC solution to automate the installation process. Furthermore, I was already using Docker for the integration tests for the same project. So, I decided to give it a try and after doing some digging with Docker it worked well.
General architecture and Docker configuraion
The application consists of the following components:
- AngularJS based Front-end managed by Bower package manager
- REST API Back-end powered by Ruby On Rails
- MongoDB and PostgreSQL databases
- Redis based in-memory key-value storage
Other tools and frameworks:
- RSpec - API and Selenium based end-to-end tests
- Sidekiq - background processing and job scheduling
- Capistrano - remote server automation and deployment
Codebase is hosted on GitHub in a private repository.
Step by step I built and configured Docker images, containers, and wired services to cover all the requirements above.
Docker configuration is available at GitHub: https://github.com/sheroz/docker-rails
Ruby on Rails container
The app (Ruby on Rails) container is based on Linux Ubuntu 18.0.4 (bionic) image to ensure that it would work equally the same way both in development and production.
Since I use Docker, I decided to compile Ruby from the source as there is no real need to use the version managers like RVM or rbenv. Ruby version can be upgraded/set in .env parameters. After changing the Ruby version the app image should be rebuilt.
To achieve better performance, I had to duplicate the source folder in the app container, as directly accessing files from the host-mounted volume was very slow on Windows. (Seems the volume 'cached' option can speed up mounted volume access for macOS-based hosts, but this option does not work for Windows-based hosts yet.)
To synchronize host and in-container sources, I am using the File Watchers plugin on RubyMine IDE (finally, after having tried many other different options like unison, lsyncd, ...).
Network settings for the database and Redis services
Rails application was configured to access the database and Redis services on the same localhost (127.0.0.1) and this requirement is achieved by using network_mode: "service:[service name]" option.
Running services and available tools
The app container runs in user mode and the sudo command is available without a password prompt.
As a back-end developer, I start rails server in the bash console which allows me to debug Ruby code by using binding.pry and see the logs. Front-end developers can configure it to start by default.
The app image has a bunch of tools, including mc (The Midnight Commander, my favorite file manager).
A separate bash console can be used to start sidekiq service, capistrano, and rspec tasks.
Docker Engine configuration to enable connection from RubyMine IDE
In the General section of your Docker settings, turn on the Expose daemon on tcp://localhost:2375 without TLS option.
RubyMin IDE configuration
File Watchers plugin configuration for RubyMine IDE
Ruby on Rails development performance using Docker on Windows is approximately the same as development on native macOS (MacBook Pro 15, 2018) when using comparable hardware components (CPU, RAM, SSD).
2023 August (1)
2019 May (1)
2016 March (2)
2016 February (1)
2014 December (1)
2013 May (1)
2013 March (1)
2013 February (1)
2012 December (2)
2012 October (1)
2011 February (2)
2010 October (2)
2010 July (1)
2010 May (1)
2010 April (1)