Crane is a Docker orchestration tool similar to Docker Compose with extra features.
For example, it offers ultra-fast, dependency-free bind-mounts for Docker on Mac, with a speed boost of at least 10x!

Welcome to Crane! You can either:

 

Existing docker-compose project

If you already have an existing project, it is easy to use Crane instead of docker-compose to get fast bind-mounts! In general, you only need to add a small snippet to tell Crane which folders should be accelerated.

In this example, we'll assume a Rails project with the following docker-compose.yml:

services:
  postgres:
    image: postgres:9.6.2
    env:
      - "POSTGRES_USER=example"
      - "POSTGRES_PASSWORD=secret"
      - "POSTGRES_DB=example_development"
  web:
    depends_on:
      - "postgres"
    build:
      context: .
    tty: true
    stdin_open: true
    ports:
      - "3000:3000"
    volumes:
      - ".:/web"
    command: "bin/rails s -b 0.0.0.0"

All you need to do is create a separate crane.yml in the same folder. Crane will automatically merge both config files together. The file should look like this:

accelerated-mounts:
  web:
    uid: 1000
    gid: 1000

That's it. Next time you start the "web" service, it'll be fast! Try it out now: crane run example.

 

New project from scratch

We're going to walk through all steps required to setup a new Rails project, but if you use another language / framework, most things should be very similar and you can adapt as needed. For the purposes of this guide, let's assume we name our project "example", so we create a new folder example, which is where all files mentioned below are to be placed.

After you have installed Crane, let's start by creating a configuration file. Following is the Crane format (which strictly follows the flag names of docker run), but you can also use the docker-compose format. An example of that can be seen in the section about using an existing project with Crane.

This is how the crane.yml looks like:

services:
  postgres:
    image: postgres:9.6.2
    env:
      - "POSTGRES_USER=example"
      - "POSTGRES_PASSWORD=secret"
      - "POSTGRES_DB=example_development"
  example:
    requires: ["postgres"]
    build:
      context: .
    publish: ["3000:3000"]
    volume: [".:/example"]
    tty: true
    interactive: true
    command: "bin/rails s -b 0.0.0.0"

accelerated-mounts:
  example:
    uid: 1000
    gid: 1000

We are using the official PostgreSQL image for the database and will build our own image for the example app. Let's write the Dockerfile for it:

FROM ruby:2.3.3

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

RUN useradd -m -s /bin/bash example; \
    chgrp -R example /usr/local; \
    find /usr/local -type d | xargs chmod g+w; \
    mkdir -p /etc/sudoers.d; \
    echo "example ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/example; \
    chmod 0440 /etc/sudoers.d/example

ENV HOME /home/example

USER example

RUN gem install rails --no-ri --no-rdoc

WORKDIR /example

ENV BUNDLE_PATH /example/vendor/bundle

Now we are ready to build this image and create a new Rails project. Crane's up command can do both at the same time for us:

crane up example rails new . --force --database=postgresql --skip bundle

To configure our app to talk to the Postgres container, edit config/database.yml and uncomment password: secret and host: postgres under the development section. One last step is to install the dependencies:

crane run example bundle install

Finally, start the server with crane run example and check out the result at http://localhost:3000.

Copyright © 2020 Michael Sauter