Getting Started

Devstep comes in two flavors, you can either use the provided CLI or you can build on top of the provided images from Dockerfiles.

Regardless of the flavor you choose, it is a good idea to docker pull fgrehm/devstep:v0.4.0 before creating your first container / image for a better user experience. Docker will download that image as needed when using Dockerfiles but the Devstep CLI won't.

Sanity check

This project is being developed and tested on an Ubuntu 14.04 host with Docker 1.7.0, while it is likely to work on other distros / Docker versions / boot2docker, I'm not sure how it will behave on the wild.

Please note that the CLI is currently limited to connecting to a local /var/run/docker.sock socket only and the user that runs devstep commands will need non-root access to it. Support for execution over TCP is likely to be added at some point in the future.

Getting started with the CLI

IMPORTANT: A developer user will be used by Devstep and it assumes your user and group ids are equal to 1000 when using the CLI or the container's init process will be aborted. This is to guarantee that files created within Docker containers have the appropriate permissions so that you can manipulate them on the host without the need to use sudo. This is currently a Devstep limitation that will be worked around in case there is enough demand or will be fixed once Docker adds support for user namespaces.

The 1000 id was chosen because it is the default uid / gid of Ubuntu Desktop users that are created during the installation process. To work around this limitation you can build your own image with the appropriate ids and add a source_image: '<YOUR-IMAGE>:<OPTIONAL-TAG>' line to your ~/devstep.yml so that the image is used as a source for your projects.

To install the CLI, you can run the one liner below and read on for more:

L=$HOME/bin/devstep && curl -sL > $L && chmod +x $L

The snippet above assumes $HOME/bin is on your PATH, change $HOME/bin to an appropriate path in case your system is not configured like that.

Doing a quick hack on a project

With the CLI and Docker in place, just cd into your project and run devstep hack, it should be all you need to start working on your project. Devstep will create a Docker container, will install your project dependencies in it and at the end you'll be dropped on a bash session inside the container with project sources available at /workspace.

From inside the container, you can do your work as you would on your own machine. For example, you can use rake test to run your Ruby tests or go build to compile Golang apps while editing files from your machine using your favorite IDE.

When you are done hacking, just exit the container and it will be "garbage collected" (aka docker rmed) and no project specific dependencies will be kept on your machine.

Taking snapshots of the environment to reduce startup time

Building an environment from scratch all the time you need to work on a project is not very productive. To alleviate that pain you can use the devstep build command which will create a Docker image with all dependencies required to hack on your project so that further devstep hacks have a reduced startup time.

When your project dependencies are changed (like when a new RubyGem is needed for a Ruby app), you can run devstep build again and it will reuse the previously built image as a starting point for building the new environment instead of starting from scratch, so use it for projects that you hack on every day.

Accessing web apps from the host machine

The devstep hack command accepts an additional -p parameter that accepts ports in the same way that the Docker CLI does. For example, if your app runs on the 8080 port, you can start your hacking sessions with:

devstep hack -p 8080:8080

And it will redirect the 8080 port on your host to the 8080 port within the container so you can just hit http://localhost:8080 on your browser to see your app running after it is up.

Using databases or other services from within containers

In order to connect your project to additional services you can either link containers to the appropriate service if you want to manage it from outside or install and configure it by hand inside the container.

Connecting to services that runs from other containers are as simple as passing in a --link argument to the devstep hack command. The provided base image is smart enough to detect that a link has been provided and will automatically forward a localhost port to the external service published port.

For example, you can start a PostgreSQL service on the background with:

docker run -d --name postgres postgres:9.3

And then start your hacking session with:

devstep hack --link postgres:db

From inside the container you'll be able to access the external PostgreSQL service using the local 5432 port that is redirected to the same port exposed by that image.

Installing services inside the container makes sense if, for example, you are developing a library that interacts with it. Please note that since the Docker image does not run Ubuntu's default init process (it uses runit instead), some additional steps will be required to start the service. Recipes for installing some services are available in the form of "addons" so you don't have to worry about that.

For example, installing and configuring memcached inside the container is a matter of running configure-addons memcached from there.

Bootstrapping a new project (AKA solving the chicken or the egg problem)

Assuming you are willing to use Docker / Devstep to avoid cluttering your machine with development tools, there's no point on installing Ruby / Python / ... on your computer in order to scaffold a new project. To make that process easier, you can use the devstep bootstrap command and manually trigger a buildpack build from there using the build-project command.

For example, scaffolding a new Rails project means:

cd $HOME/projects # or whatever directory you keep your projects
devstep bootstrap -r devstep/my_app

build-project -b ruby
gem install rails
rails new my_app

exit # Or do some extra setup before exiting

Once you exit the container, you will end up with a devstep/my_app image and a brand new Rails app under $HOME/projects/my_app on the host machine.

To bootstrap projects for other platforms and frameworks you can follow a similar approach, replacing the Ruby / Rails specifics with the platform / framework of choice.

As with devstep build, subsequent devstep commands like build and hack will use devstep/my_app:latest as the source image so that the environment don't have to be rebuilt from scratch.

Caching project's dependencies packages on the host

As mentioned on the introduction section, Devstep is also capable of reducing disk space and initial configuration times by caching packages on the host using a strategy similar to vagrant-cachier's cache buckets.

This behavior is enabled by default and will be further documented on the future. For now you need to know that the /tmp/devstep/cache dir on the host will be bind mounted to containers created by the CLI under /home/devstep/cache and most of your project's dependencies packages will be downloaded there. Note that the dependencies themselves are extracted and kept inside the images built by the CLI and you can safely clean things up or disable the caching behavior at will.

Building images using Dockerfiles

In case your project require additional dependencies to work you can use the provided fgrehm/devstep image as a starting point for your Dockerfiles.

The fgrehm/devstep image is the base image used for Devstep environments and requires you to manually trigger the build:

FROM fgrehm/devstep:v0.4.0

# Add project to the image and build it
ADD . /workspace
WORKDIR /workspace
RUN CLEANUP=1 /opt/devstep/bin/build-project /workspace

By using a Dockerfile to build your images (instead of using devstep build) you'll be able to skip mounting project's sources on the container when running it and a simple docker run -it <IMAGE-NAME> should do the trick. Keep in mind that changes made to project sources will be kept inside the container and you'll lose them when you docker rm it.

More information

If you reached this point it means you should have a good understanding of how Devstep works and what you can do with it. For more information please check out the links on the menu above and if you are still wondering how you can use the tool or benefit from it, please create a new issue or reach out on Gitter so that we can have a chat :)