This image provides an easy, generic, consistent and non-intrusive Docker Compose setup for all your Ruby projects. Why?
Usage
Setup
Simply create a docker-compose.yml file in your project root directory like this:
version: "3" volumes: bundle: { driver: local } node_modules: { driver: local } config: { driver: local } services: app: image: alpinelab/ruby-dev volumes: - ./:/app - bundle:/bundle - node_modules:/node_modules - config:/config
💡 Feel free to use
alpinelab/ruby-dev:<ruby-version>: we support multiple Ruby versions via image tags
If you're on MacOS, you'll very likely want to use Docker Sync too.
⚠️ Use your actual application name suffixed with
-syncinstead ofyour_app-syncto prevent conflicts between your projects.
-
install it with
gem install docker-sync -
add a
docker-sync.ymlfile:version: "2" syncs: your_app-sync: src: ./ sync_excludes: [log, tmp, .git, .bundle, .idea]
-
add the sync container as external container in
docker-compose.yml:volumes: your_app-sync: { external: true }
-
use it by replacing
- ./:/appwith- your_app-sync:/app:nocopyindocker-compose.yml -
start the sync with
docker-sync start
Run
You can now start your project with:
Or run any command (like rake, bash, or whatever else) with:
docker-compose run app [rake|bash|...]
💡 Note that you don't need to prefix commands with
bundle exec.
About
Goals
- use the same Docker image in all your projects
- stop messing your host environment with multiple rubies and gemsets
- stop building your Docker image every time you change your
Gemfile(or worse: your code 😱) - use up-to-date Ruby, Bundler, Node and Yarn versions
Features
- shell history
- IRB/Pry history
- auto-install Ruby (Bundler) and Javascript (NPM) dependencies
- basic in-container tools (
vim,nano,heroku, …) - runs whatever you define in the
Procfile
Conventions
Filesystem conventions:
/appholds your application source code/bundleholds gems installed by Bundler/node_modulesholds packages installed by Yarn/configholds miscellaneous configuration files
Dependencies conventions:
bundle installis run before any command if necessaryyarn installis run before any command if necessary
Other conventions:
- the default command run by the image is
foreman start
Configuration
Most configurations can be done from a docker-compose.override.yml file alongside your docker-compose.yml file (by default, it will be automatically read by docker-compose, and it should probably be gitignore'd globally).
Heroku CLI authentication
The recommended approach to have the Heroku CLI authenticated is to set the HEROKU_API_KEY in docker-compose.override.yml with an OAuth token:
version: "3" services: app: environment: HEROKU_API_KEY: 12345-67890-abcdef
If you don't have an OAuth token yet, you can create and output one with:
heroku authorizations:create --output-format short --description "Docker [alpinelab/ruby-dev]"An alternative but less secure approach would be to mount your host's ~/.netrc to the container's /root/.netrc.
Git authentication
If you're using SSH as underlying Git protocol, you may want to use your host SSH authentication from within the container (to use git from there, for example).
You can do it by mounting your host's ~/.ssh to the container's /root/.ssh from docker-compose.override.yml:
version: "3" services: app: volumes: - ~/.ssh:/root/.ssh
Customisation
Custom Yarn check command
By default, we use yarn check --integrity --verify-tree --silent to check that all JS dependencies are met, but you can override this if you need to by defining your own check command in the scripts section of package.json, like:
{
"scripts": {
"check": "cd client && yarn check --integrity --verify-tree --silent"
}
}Installing software in the container
To temporarily install a package inside the container (e.g. for a one-time debugging session), you can simply run:
apt-get update && apt-get install <your_package>
⚠️ This will probably not be persisted (because it will likely be installed in this container instance UnionFS layer that will be discarded when you exit it).
To permanently install packages inside a container, you'll need to create a new Docker image based on this very one (or any of its tags). For example, to add packages needed to compile Thoughtbot's capybara-webkit gem native extensions, create the following Dockerfile in your project root folder (it will build an image based on this one but with some extra packages installed by apt-get on top of it):
FROM alpinelab/ruby-dev RUN apt-get update \ && apt-get install --assume-yes --no-install-recommends --no-install-suggests \ qt5-default \ libqt5webkit5-dev \ gstreamer1.0-plugins-base \ gstreamer1.0-tools \ gstreamer1.0-x \ && rm -rf /var/lib/apt/lists/*
Then, change your docker-compose.yml to use it (and to build it on-demand) by changing image: alpinelab/ruby-dev to build: ..
Contributing
Contributions are indeed warmly welcome as pull requests, or issues.
There's also a few handy scripts to help maintainance tasks:
add-ruby-version-support.shadds support for a Ruby versionrebase-all.shapplies a change made onlatestbranch to all other branchesbuild_all.shbuilds images on all branches and pushes them to Docker repository