Skip to content


Subversion checkout URL

You can clone with
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: jpetazzo/thin
base: yes
head fork: jpetazzo/thin
compare: master
  • 11 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
Commits on Aug 20, 2011
@jpetazzo DotCloud Build File
The DotCloud Build File, ``dotcloud.yml``, describes our stack.

We declare a single "ruby" service. We use "ruby" because it features
two useful things for us:

* a Ruby interpreter (obviously!) and a mechanism to install gems;
* a public-facing HTTP server (nginx).

The role and syntax of the DotCloud Build File is explained in further
detail in the documentation, at
@jpetazzo Sample Rack Application
A very simple Rack application is placed into ````.

For testing purposes, our app will just display the HTTP request environment.
You can actually use any other Rack or Rails app.

At this point, you can ``dotcloud push`` the application, and go
to its URL (the URL is shown at the end of the push): the app does
not run on Thin (yet!) but it runs on Passenger.
@jpetazzo Gemfile & Dependencies
To tell DotCloud to automatically install the gem for Thin, we create a
standard Gemfile. DotCloud will detect this, and automatically use ``bundler``
to install dependencies defined in the Gemfile.

See for details about bundler and the
Gemfile format.
@jpetazzo Route Requests to Thin
By default, DotCloud sends HTTP requests to Nginx, on port 80.
Thin will be running on port 8080. We will connect the two together,
by adding a Nginx configuration snippet instructing Nginx to proxy
all the requests to Thin.

At this point, we can test our setup manually, by:

* pushing to DotCloud with ``dotcloud push thin``;
* logging into our service with ``dotcloud ssh thin.www``;
* starting Thin manually with ``cd current ; thin start -p 8080``.

If we browse our service URL, we should see our simplistic Rack
app. The headers will display the Thin version, showing that we
are not using Passenger anymore.
@jpetazzo Install God Process Manager
We want something to start, stop, and monitor the "thin" process
better than what we could do with crude scripts. We will use the
"god" process manager. It is the Ruby equivalent of e.g. Supervisor
or Monit.

To tell DotCloud to install it automatically for us, we simply
add it to our Gemfile.
Commits on Aug 25, 2011
@jpetazzo God Configuration File
God requires a configuration file. The one included here is
a working example, but leaving out a lot of interesting features
(e.g., restarting the process automatically if its CPU or memory
usages exceed given limits).

The important part is the ``w.start`` line, which basically
tells god to make sure that Thin will be running, and sets
the appropriate command-line flag to make it listen on port

We also redirect Thin's output messages to ``/home/dotcloud/thin.log``,
so if anything goes wrong, we can inspect that file and see what's

You can see more god configuration options on its official
web page (
@jpetazzo Postinstall Script
To start god (and, therefore, Thin) automatically, we will use a
``postinstall`` script.

We could use SSH and start god manually each time we push the service,
but that would not be very convenient. To make sure that our processes
are started automatically when the service is pushed or scaled, we will
write a short postinstall script. The postinstall script is executed
automatically after each push, and after each deployment of a new
scaled instance.

In this script, we just have to invoke ``god`` and give him the
configuration file name.

Remember to make sure that the ``postinstall`` script is executable,
with e.g. ``chmod +x postinstall``.
@jpetazzo Better Postinstall Script
To make sure that Thin gets restarted properly when we push new versions
of our code, we augment our postinstall script to restart god each time
the postinstall script is run (i.e. after each push).

The last ``god status`` line is for information purposes only: it will
just add a line in the build log, telling us if thin runs correctly.
@jpetazzo Mandatory README File
Explain what we did in the mandatory README, that will show up on
the GitHub page of the repository.
@jpetazzo Improve README file
There were some typos in the README file; also, the special way
the commits were arranged was not very clear. This will hopefully
make it better.
@jpetazzo Add begin..end tags to the git log command 04ae674
3  Gemfile
@@ -0,0 +1,3 @@
+source :rubygems
+gem 'thin'
+gem 'god'
78 README.rst
@@ -0,0 +1,78 @@
+What Is This?
+This code shows how to run the `Thin <>`_
+web server on `DotCloud <>`_.
+Thin is a fast asynchronous web server, able to run Rack and Rails apps.
+To run this code on DotCloud, you need to `get a DotCloud account
+<>`_. DotCloud has a free tier,
+so you won't even need to draw your wallet!
+Then clone this repository::
+ $ git clone git://
+And push it to DotCloud::
+ $ cd thin
+ $ dotcloud push thin
+Happy hacking! Remember: each time you modify something, you need to
+git add + git commit your changes before doing ``dotcloud push``.
+How Does It Work?
+Since DotCloud cannot run arbitrary web servers (yet!), we use a ruby
+service (which uses the nginx web server to handle HTTP requests). Inside
+this service, we setup Thin to run on port 8080. Then, we add a nginx
+configuration snippet to proxy all incoming HTTP requests to port 8080,
+effectively routing them to Thin.
+To streamline scaling and deployment, we use a Gemfile (to install the
+thin gem automatically), as well as the god process manager (to start
+Thin automatically).
+**This repository is also a step-by-step tutorial:** each commit
+corresponds to one step, with the commit message providing explanations.
+You can view the whole tutorial, and the modified files at each step,
+with at least three different methods:
+* by using GitHub's awesome `compare view
+ <>`_:
+ you will see the list of commits involved in the tutorial, and by
+ clicking on each individual commit, you will see the file modifications
+ for this step;
+* by running ``git log --patch --reverse begin..end`` in your local
+ repository, for a text-mode equivalent (with the added benefit of being
+ available offline!);
+* by browsing a more `traditional version
+ <>`_ on DotCloud's
+ documentation website.
+You can also learn more by diving into `DotCloud documentations
+<>`_, especially the one for the `Ruby service
+<>`_ which is used by this app.
+Is This A Hack?
+Yes, in the positive acceptance of this word :-)
+Is This Supported?
+Not officially. However, since it uses only documented parts of DotCloud
+(ruby service, postinstall script, nginx snippet...), it will very probably
+still work with future versions of DotCloud.
+As a matter of fact, when DotCloud will release better support for Thin
+and other evented web servers, the modifications required to update your
+code will most certainly be very, very minor.
@@ -0,0 +1,5 @@
+app = do |env|
+ [ 200, {'Content-Type' => 'text/plain'},
+ {|k,v| "#{k}=#{v}\n"}.collect ]
+run app
3  dotcloud.yml
@@ -0,0 +1,3 @@
+ type: ruby
4 nginx.conf
@@ -0,0 +1,4 @@
+location ^~ / {
+ proxy_pass http://localhost:8080;
4 postinstall
@@ -0,0 +1,4 @@
+god terminate || echo "(you should ignore the error on the previous line)"
+god -c thin.god
+god status
18 thin.god
@@ -0,0 +1,18 @@
+# Start with "god -c thin.god"
+ do |w|
+ = "thin"
+ w.dir = "/home/dotcloud/current"
+ w.interval = 30.seconds # default
+ w.start = "thin start -p 8080"
+ w.log = "/home/dotcloud/thin.log"
+ w.start_if do |start|
+ start.condition(:process_running) do |c|
+ c.interval = 5.seconds
+ c.running = false
+ end
+ end

No commit comments for this range

Something went wrong with that request. Please try again.