Using Docker for Ruby on Rails development on Windows
Tested with Windows 10.
For impatiens: Docker configs are available at GitHub: https://github.com/sheroz/docker-rails
The past two and half years I worked full time on a project based on Ruby language and Rails framework. Life is an amazing teacher. It was a unique experience after having many years of C/C++ and Java development. Being thousands of kilometers far from my homeland and having a foreigner status in a new country, I had to accept a challenging offer from a very ambitious startup-like company and jump into a magical Ruby on Rails world.
I was provided with a MacBook Pro for day-to-day development. Ruby development on macOS is amazing. But, at home I historically tied with Microsoft OS, starting with MS-DOS in my youth and Windows 10 nowadays. I always used my Windows PC to make small changes, urgent hotfixes or to probe new ideas when I am at home.
People may think that software developers work only a fixed time at the office. It's not always true. As far as I know, when a developer is motivated and fully engaged, his brain works 7/24 to solve faced challenges.
Imagine that you are a Ruby on Rails developer in a startup...
It was my first experience with a startup. I found for myself that startups are a very different world. Sometimes I think if Cervantes was alive, maybe he would re-write his famous romance about Don Quixote according to the adventures of the heroes of our time, who decided to become modern knights 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 software engineering is art and science. The relationship between creativity and stress is a complex subject. Normally, quality and creativeness are opposite to rush, stress, and distractions. Furthermore, software engineering is a hard and mentally exhausting process. While pushing developers gives an imaginary gain in productivity in a short-term, the code developed under high pressure probably would include hidden time bombs.)
So, you are at home and while you drink a cup of tea (or coffee) with your loved ones in a warm and nonstressful atmosphere, your relaxed and happy brain catches this creative moment and starts to analyze unsolved challenges in the background, and... Suddenly, you see the bright solution to the interesting challenge you had no single chance to overcome at the office. You want immediately convert the idea into code, but... Unfortunately, you left your work laptop in 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 Windows PC what seems useless against Ruby on Rails...
That is because setting up Ruby on Rails development environment is not so straightforward on Windows, while it is native on Linux and macOS.
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)
Or, you can make the PC dual-bootable and use Linux for the development. This is the best option if you are going to use the PC primarily for RoR development.
I tried (1) and (2) options. It works and may be usable in small projects. But, in the case of complex RoR project, the performance was absolutely 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 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
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 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 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 sudo command is availabe without password prompt.
As a back-end developer, I start rails server in bash console what 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 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).
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)