Skip to content

Local environment with Docker4Ruby

Docker4Ruby is an open-source project (GitHub page) that provides pre-configured docker-compose.yml file with images to spin up local environment on Linux, Mac OS X and Windows.



Database data persistence

By default Docker will create a persistent volume for your DB data and unless you explicitly remove volumes the files will not be deleted. However, if you run docker-compose down (it's ok to use stop though) these volumes will not be reattached when you run docker-compose up. If you want to have your DB data all-time persistent and attached, we recommend using a bind mount. To use a bind mount uncomment to corresponding line under db server's volumes: in your docker-compose.yml and update the host path to your data directory.

  1. Download docker4ruby.tar.gz from the latest stable release and unpack to your Ruby project root
  2. Ensure database credentials match in your database config and .env files, see example for Ruby on Rails below
  3. Configure domains
  4. Optional: import existing database
  5. Optional: uncomment lines in the compose file to change DBMS (PostgreSQL by default) or run Sidekiq, Redis, Elasticsearch, etc
  6. Optional: macOS users please read this
  7. Optional: Windows users please read this
  8. By default ruby container will start Puma HTTP server, if you want to change it modify Dockerfile
  9. Build your ruby image by running make build or docker-compose build. This will create a new image with installed gems from your Gemfile.lock. If compilation of native extension for some of your gems fail you probably need to install additional dev packages, see example in Dockerfile
  10. Run containers: make or docker-compose up -d. Your codebase from ./ will be mounted to the ruby image with installed gems
  11. Your ruby application should be up and running at http://ruby.docker.localhost:8000
  12. You can see status of your containers and their logs via portainer: http://portainer.ruby.docker.localhost:8000

You can stop containers by executing make stop or docker-compose stop.

Examples for Ruby on Rails database setup, config/database.yml:

  adapter: <%= ENV['DB_ADAPTER'] %>
  encoding: unicode
  database: <%= ENV['DB_NAME'] %>
  pool: 5
  username: <%= ENV['DB_USER'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>

Optional files

If you don't need to run multiple projects and don't use docker-sync to improve volumes performance on macOS feel free to delete traefik.yml and docker-sync.yml that come with the docker4ruby.tar.gz

Get updates

We release updates to images from time to time, you can find detailed changelog and update instructions on GitHub under releases page


Docker4Ruby uses traefik container for routing. By default, we use port 8000 to avoid potential conflicts but if port 80 is free on your host machine just replace traefik's ports definition in the compose file.

By default BASE_URL set to ruby.docker.localhost, you can change it in .env file.

Add ruby.docker.localhost to your /etc/hosts file (some browsers like Chrome may work without it). Do the same for other default domains you might need from listed below:

Service Domain
nginx http://ruby.docker.localhost:8000
adminer http://adminer.ruby.docker.localhost:8000
mailhog http://mailhog.ruby.docker.localhost:8000
solr http://solr.ruby.docker.localhost:8000
kibana http://kibana.ruby.docker.localhost:8000
node http://front.ruby.docker.localhost:8000
varnish http://varnish.ruby.docker.localhost:8000
portainer http://portainer.ruby.docker.localhost:8000

Database import and export


See MariaDB stack documentation


See PostgreSQL stack documentation

Make commands

We provide Makefile that contains commands to simplify the work with your local environment. You can run make [COMMAND] to execute the following commands:

Usage: make COMMAND

    up              Start up all container from the current docker-compose.yml 
    build           Build ruby image with gems from your Gemfile.lock 
    stop            Stop all containers for the current docker-compose.yml (docker-compose stop) 
    down            Same as stop
    prune           Stop and remove containers, networks, images, and volumes (docker-compose down)
    ps              List container for the current project (docker ps with filter by name)
    shell           Access Ruby container via shell as a default user  (docker exec -ti $CID sh)
    logs [service]  Show containers logs, use [service] to show logs of specific service

Docker for mac

There two major problems macOS users face with when using Docker for mac:

macOS permissions issues

To avoid any permissions issues caused by different user id (uid), group id (gid) between your host and a container use -dev-macos version of php image (uncomment the environment variables in .env files) where the default user wodby has 501:20 uid/gid that matches default macOS user.

Bind mounts performance

Out of the box Docker for mac bind mounts (volumes from host) have poor performance on sync. There are 2 ways how it can be improved.

User-guided caching

Since Docker for Mac 17.06 there's a new native :cached option available for bind mounts. You can find more information about this in docker blog.

Replace codebase volume definition of php and nginx/apache services with the option below marked as "User-guided caching".


Performance tests 2017 Docker-sync vs Native.

The core idea of this project is to use an external volume that will sync your files with a file synchronizer tool.

gem install docker-sync
  1. Download docker-sync.yml file (inside of docker4x.tar.gz archive) from the latest stable release
  2. Uncomment docker-sync volume definition in your compose file
  3. Replace volumes definition of php and nginx/apache services with the option below marked as "Docker-sync".
  4. Start docker-sync: docker-sync start
  5. In a new shell run after you started docker-sync docker-compose up -d

Now when you change your code on the host machine docker-sync will sync your data to php and nginx/apache containers.

For more information visit docker-sync project page.

Permissions issues

You might have permissions issues caused by non-matching uid/gid on your host machine and the default user in php container.



Use -dev-macos version of ruby image where default wodby user has 501:20 uid/gid that matches default macOS user.


Since you can't change owner of mounted volumes in Docker for Win, the only solution is to run everything as root, add the following options to ruby service in your docker-compose file:

    user: root

Different uid/gid?

You can rebuild the base image wodby/ruby with custom user/group ids by using docker build arguments WODBY_USER_ID, WODBY_GROUP_ID (both 1000 by default)

Running multiple Projects

Træfik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. To understand the basics of Traefik it is suggested to check Træfik's documentation page:

Image: Multi-domain set-up example (Source:

Steps to set up two projects on one host:

  1. Create two dirs where you will host two projects. Let's name them site1 and site2
  2. Copy docker-compose.yml file to both dirs (site1 and site2)
  3. Download traefik.yml file (inside of tar.gz archive) from the latest stable release to the parent dir where site1 and site2 dirs are
  4. Edit traefik.yml and change project1-dir_default to site1_default and project2-dir_default to site2_default. Those are docker networks names that are created automatically from the dir name where docker-compose.yml is located
  5. Edit site1's docker-compose.yml file. There are 3 main things that need to be done there:
    • In nginx service, under labels, change traefik.backend=nginx to traefik.backend=site1_nginx_1. This is the name of the container. You can see that under NAMES when your have the containers running by executing docker ps
    • Change traefik.frontend.rule from Host:ruby.docker.localhost to Host:site1.docker.localhost
    • Comment out all lines of traefik service at the bottom of the file
  6. Make similar 3 changes in site2's docker-compose.yml file:
    • traefik.backend=nginx to traefik.backend=site2_nginx_1
    • Host:ruby.docker.localhost to Host:site2.docker.localhost
    • Comment out all lines of traefik service at the bottom of the file
  7. Run docker-compose up -d in site1 and site2 dirs to spin up containers for both projects
  8. Run stand-alone traefik docker-compose -f traefik.yml up -d to spin up traefik reverse proxy
  9. Visit http://site1.docker.localhost and http://site2.docker.localhost in your browser

This set up also works for any Docker projects. You can replace nginx-proxy config with Traefik and get other projects all routed with on traefik container.

For macOS users with docker-sync

Make sure names of syncs in docker-sync.yml are unique per project. The recommended way is to run a stand-alone docker-sync with syncs definition for all projects. Do not forget to update src paths for projects

In case of issues:

  • Check docker ps to see which containers are running and check if you have set up all names correctly.
  • Check docker network ls to check if the network names are matching.
  • Run docker-compose logs -f in site1 or site2 to see the log of each project.