Jan 09, 2017

Tip: Docker Development Environment

One of my resolutions this year is to use Docker as the single source of truth for all my development environments. So instead of installing the required software, like databases or development libraries, directly into my path I will be leveraging Docker and Docker Compose to have everything always working locally.

The main problem I currently face is my development setup. I ditched Linux about 7 years ago and migrated completely to macOS, and since Docker Mac is still a work in progress having a development environment based on Docker is a challenge.

The biggest issue is shared volumes, the performance is not the same compared to the Linux version. I spent some time researching about how to get the best performance with the current available tools, and after testing several tools I settle with d4m-nfs that internally uses NFS for sharing the volumes.

The keys to remember when using Docker and D4M are:

  • When using D4M for the first time make sure the Shared Volumes are removed from Docker, leave /tmp/ only. See the README.
  • After cloning d4m-nfs, create the file etc/d4m-nfs-mounts.txt, make sure its contents are something like:
/Users/<username>:/Users/<username>
  • When sharing volumes make sure the folder exists locally, recall the volume is being shared using NFS, the folder must exist in advance otherwise errors will be thrown. There’s an option though, apparently you can use root:wwheel to automatically make the folders, I tried it but did not work for me.
  • If you experience issues related to Mounts denied, try to:
    1. Quit Docker, start it again and wait a bit.
    2. Run the d4m-nfs.sh again.

Dockerizing share-activerecord-models Gem

Part of this exercise for me was to update my share-activerecord-models gem, the one I introduced in the post Sharing ActiveRecord models between projects. The idea is simple, to use docker-compose for building the gem without installing anything else but docker.

Consider taking a look at the change that introduced the Dockerization, important bits are:

  • New folder .gems/, which is shared volume, the idea is to have the gems installed locally not inside the image, similar to a gemset, to speed-up building the image.
  • Database configuration change, to use the linked container instead of the hardcoded localhost.

With that I can easily interact with the gem by doing something like:

docker-compose up
docker-compose run gem bundle exec rails generate migration create_my_table
docker-compose run gem bundle exec rails generate scenic:view my_materialized_table --materialized
docker-compose down