A self-contained rails development environment
This setup lets you develop a rails application on any machine with Docker, docker-compose and Bash. The technique is adaptable for other web stacks (think Node, PHP, ...).
Make sure you've installed
Clone the source, then
bin/bootstrap bin/start development
You can now browse the app by visiting
Getting started / useful commands
||Switch to the development environment|
||Start the development environment|
||Stop the development environment|
||Restart the development environment|
||Run the tests|
||Dump the development database|
||Load a dump into the development database|
||Show the running containers|
||Follow the rails log|
||Run the rails console in a new container (you can run all rails tasks like this)|
||Install the bundle|
||Start a bash inside the running rails container (you will see the rails process with ps)|
||Install a node module|
||Show all containers running on your system|
||Stop all containers running on your system|
There is a development and a testing environment, implemented as separate sets of containers.
You can start and stop these environments. It's also possible to inspect each environment and perform commandline tasks inside the containers.
- To start an environment:
- To stop an environment:
- To point your docker-compose/Docker CLI at an environment:
. bin/source_env developmentor
. bin/source_env test
Have a look at what the scripts are doing, there's no rocket science involved.
Images and file permissions
All files created by the containers will belong to you. This means you can do all editing and browsing with your favorite tools that you install and configure locally.
To achieve correct ownership, most Docker images contain a user
app whose id
and primary group id are the same as your users'. Processes in those containers (such as
rails s) will belong to
app, having the same uid/gid as you have, is effectively an alias of your user.
All state (runtime data managed by the containers) lives inside volumes. A volume is a directory under
- Database files
- Gems, Node modules
- Separate history files for the shells of each container
Volumes need to have correct permissions set so both you and the containers can access them.
This bootstrapping is done via
Having all state in volumes also means you can reliably recreate the situation on your device
otherwhere by checking out the same commit on another device and copying your
Why not docker volumes?
Docker also has an approach to volumes - the implemented alternative seems to facilitate inspecting volume contents, measuring volume size and cleaning up. Maybe it would just be a matter of using docker volumes correctly...
Caveats / further possibilities for improvement
- This setup prevents you from using spring. One approach to solving this would be to start a container
running spring for both environments, then rewire the scripts to run all rails commands in it,
docker-compose exec spring rails s
- What will
bundle opendo? Can we extract the path to the relevant gem inside the container with bundler, then pass it locally to
xdg-opento get the same behaviour?
At the moment, this primarily showcases a dockerized environment. We're open to let it become more.
So if you base your setup on this and discover any improvements to either the architecture or the process of setting this up for your project - let's look at it together! Please open an issue.
Big bang: Generating the rails app
This repo already contains a generated rails app. The following information is intended as an example of how to start a project without ever installing the necessary dependencies locally.
To get things running without an existing app (meaning the
src directory is empty), do
bin/bootstrap # this will fail when trying to install the gems . bin/source_env development docker-compose run rails bash
Now you're in a bash shell inside a Ruby enabled container. On we go:
gem install rails rails new . --database=postgresql --skip-git
Leave the shell (Ctrl + D)
Make sure the database connection infos are read from the environment variables (see database.yml) and finish boostrapping:
Starting from there, you can use
to start your environment. Have a look at the logs:
. bin/source_env development docker-compose logs rails
therubyracer to your Gemfile and
. bin/source_env development docker-compose run rails bundle install docker-compose run rails rails db:migrate bin/start development
As soon as the app boots, you can browse it by visiting