|
3 | 3 | <title>Pallet, DevOps for the JVM</title>
|
4 | 4 | <link href="http://palletops.com/atom.xml" rel="self"/>
|
5 | 5 | <link href="http://palletops.com/"/>
|
6 |
| - <updated>2014-08-11T18:59:41+00:00</updated> |
| 6 | + <updated>2014-08-11T23:01:42+00:00</updated> |
7 | 7 | <id>http://palletops.com/</id>
|
8 | 8 | <author>
|
9 | 9 | <name>Antoni Batchelli</name>
|
|
13 | 13 |
|
14 | 14 | <entry>
|
15 | 15 | <title>Article: Run clojure projects on Docker with lein-uberimage</title>
|
16 |
| - <link href="http://palletops.com//blog/lein-uberimage/"/> |
| 16 | + <link href="http://palletops.com//blog/lein-uberimage"/> |
17 | 17 | <updated>2014-08-07T00:00:00+00:00</updated>
|
18 |
| - <id>http://palletops.com//blog/lein-uberimage/</id> |
| 18 | + <id>http://palletops.com//blog/lein-uberimage</id> |
19 | 19 | <content type="html"><p>We built a lein plugin to make it easy to run clojure projects in Docker containers. This article first introduces containers and Docker, and then shows how you can effortlessly create such containers for your Clojure projects with <code>lein uberimage</code>. </p>
|
20 | 20 |
|
21 | 21 | <p><image src="/images/docker-large-h-trans.png" alt="Docker logo" class="img-responsive"></p>
|
@@ -854,6 +854,84 @@ to the function.</p>
|
854 | 854 |
|
855 | 855 | <!-- news -->
|
856 | 856 |
|
| 857 | + <entry> |
| 858 | + <title>News: Run clojure projects on Docker with lein-uberimage</title> |
| 859 | + <link href="http://palletops.com//blog/lein-uberimage"/> |
| 860 | + <updated>2014-08-07T00:00:00+00:00</updated> |
| 861 | + <id>http://palletops.com//blog/lein-uberimage</id> |
| 862 | + <content type="html"><p>We built a lein plugin to make it easy to run clojure projects in Docker containers. This article first introduces containers and Docker, and then shows how you can effortlessly create such containers for your Clojure projects with <code>lein uberimage</code>. </p> |
| 863 | + |
| 864 | +<p><image src="/images/docker-large-h-trans.png" alt="Docker logo" class="img-responsive"></p> |
| 865 | + |
| 866 | +<h2>Why Containers and Why Docker</h2> |
| 867 | + |
| 868 | +<p>A container is a lighweight form of computer virtualization. Containers run within a host, and a host can run many containers concurrently. Each container is functionally equivalent to a computer loaded with a full OS, but behind the scenes all containers in the same host are sharing the same host resources: kernel, memory, IO, and disk.</p> |
| 869 | + |
| 870 | +<p>There are many ways of virtualization technologies used today, VirtualBox, Xen (used by Amazon Web Services) and vmware to name a few, but what makes containers special is their lightweight nature. Each container uses very little resources (disk, memory, cpu) and they all boot orders of magnitude faster than a virtual machine or |
| 871 | +a computer.</p> |
| 872 | + |
| 873 | +<p>Containers are very convenient for both development and production environments. For development, they provide a fast and simple way to run different and isolated runtime environments for each application. In production, they are very fast and efficient, with the added bonus that containers in production always match the ones in development; the same exact containers are used during all app&#39;s lifecycle.</p> |
| 874 | + |
| 875 | +<p><a href="http://www.docker.com">Docker</a> is a novel container technology for Linux that provides a very low friction access to containers. Containers have been around for a while, and the Linux kernel has provided key container technologies for a while already. Docker wraps all these kernel features under a high level API and defines a standard container and image formats using union filesystems. To make containers easy to share and distribute, Docker also provides public and private image repositories. All these features have brought containers to the masses.</p> |
| 876 | + |
| 877 | +<p>Although Docker is currently Linux only, you can use it on OSX installing <a href="http://boot2docker.io">boot2docker</a></p> |
| 878 | + |
| 879 | +<p>For a more detailed introduction to Docker, check out this video on <a href="http://sysadmincasts.com/episodes/31-introduction-to-docker">sysadmincasts.com</a>.</p> |
| 880 | + |
| 881 | +<h2>Docker images</h2> |
| 882 | + |
| 883 | +<p>Each container is a process tree that is started from an existing image. These images contain a filesystem with the files necessary to run your application. Sometimes this entails a linux distribution and sometimes just one statically linked binary. The common practice in the Docker world is to build a custom image for each type of service you intend to run. This contrasts with other forms of virtualization where you start the VMs from a base image and then you configure them with the required software. In the case of VMs, the time it takes a VM to boot until it is ready to run your application is measured in minutes, whereas in Docker a container can boot in sub-second times.</p> |
| 884 | + |
| 885 | +<h2>Building Docker images with uberimage</h2> |
| 886 | + |
| 887 | +<p><code>lein-uberimage</code> builds a Docker image for clojure projects. The generated images contain a base operating system, a java runtime, and your project&#39;s <code>uberjar</code>. Once this image is built, you can instantiate as many containers as you need using this image, each container running your <code>uberjar</code>.</p> |
| 888 | + |
| 889 | +<p>At the time of writing this, <code>lein-uberimage</code> requires that the project builds with <code>lein uberjar</code> and that the resulting jar can be run via <code>java -jar &lt;your-uberjar&gt;.jar</code>. This means your <code>project.clj</code> will have to have a <code>:main</code> entry pointing to the <code>-main</code> function in your code. This restriction will be removed in the future.</p> |
| 890 | + |
| 891 | +<p>To build the Docker image for your project, run the following in your project&#39;s root:</p> |
| 892 | +<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>lein uberimage |
| 893 | +</code></pre></div> |
| 894 | +<p><code>uberimage</code> will call lein&#39;s <code>uberjar</code> to build the standalone jar file. Then it will build a new image with <code>Ubuntu 14.04</code>, <code>OpenJDK 7</code> and the freshly built jar. The image is also configured to run your jar file on boot. This task will return the <code>uuid</code> for this image.</p> |
| 895 | + |
| 896 | +<p>From this image you just created, you can spawn as many containers as you need. The most basic way to start a container is this:</p> |
| 897 | +<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>docker run &lt;my-image-uuid&gt; |
| 898 | +</code></pre></div> |
| 899 | +<p>In most cases, your app won&#39;t be useful unless you can access it via known ports, and by default, Docker does not expose any ports of a container, so you need to tell Docker to expose those ports. Since you will be running many containers on the same host you need to ensure that not two containers are bound to the same port. For example, if your application listens on port 3000, you need to tell Docker to bind the container&#39;s port 3000 to any unbound port in the host, e.g. 8080:</p> |
| 900 | +<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>docker run -p 3000:8080 &lt;my-image-uuid&gt; |
| 901 | +</code></pre></div> |
| 902 | +<p>Once the container has started, just head over to <code>http://&lt;docker-host&gt;:8080</code> to access your newly deployed service. If you launch a second container with the same image, you cannot bind it to the same host port (8080 in this case) and you should instead map it to port 8081 <code>docker run -p 3000:8081 ...</code>.</p> |
| 903 | + |
| 904 | +<h2>Trying It Out</h2> |
| 905 | + |
| 906 | +<ul> |
| 907 | +<li><a href="https://docs.docker.com/installation/#installation">Install</a> Docker.</li> |
| 908 | +<li>Clone this <a href="https://github.com/tbatchelli/compojure-example">example clojure project</a>.</li> |
| 909 | +<li>On the project root, run <code>lein uberimage</code> and copy the supplied image uuid</li> |
| 910 | +<li>At the shell, run <code>docker run -d -p 3000:3000 &lt;image-uuid&gt;</code></li> |
| 911 | +<li>Open the browser and head on to <code>http://&lt;docker-host&gt;:3000</code>. Docker-host could be <code>localhost</code> in case you are in linux, or the boot2docker IP address if you are using boot2docker.</li> |
| 912 | +<li>Run <code>docker run -d -p 3001:3000 &lt;image-uuid&gt;</code> to run a second instance and check <code>http://&lt;docker-host&gt;:3001</code> with your browser. Notice the different IP address.</li> |
| 913 | +</ul> |
| 914 | + |
| 915 | +<h2>Additional Options</h2> |
| 916 | + |
| 917 | +<p>In case the supplied OS and java versions are not what you&#39;re looking for, you can supply your own base image to <code>lein-uberimage</code>:</p> |
| 918 | +<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>lein uberimage -b &lt;your-image-with-jvm&gt; |
| 919 | +</code></pre></div> |
| 920 | +<p>And in case your Docker is not locally installed on the default port or it is remote, you can override its url:</p> |
| 921 | +<div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>lein uberimage -H http://&lt;host&gt;:&lt;port&gt; |
| 922 | +</code></pre></div> |
| 923 | +<h2>Concluding remarks</h2> |
| 924 | + |
| 925 | +<p>There is not much more to it for now. This is our first stab at helping clojurians leverage containers. Please submit bugs and ideas to our project&#39;s <a href="https://github.com/palletops/lein-uberimage/issues">Issues</a> or drop by our chatroom <a href="http://webchat.freenode.net/?channels=pallet">#pallet</a> on freenode.</p> |
| 926 | + |
| 927 | +<p><code>lein-uberimage</code> is build on top of <a href="https://github.com/palletops/clj-docker.">clj-docker</a>, a clojure wrapper over docker.</p> |
| 928 | +</content> |
| 929 | + <author> |
| 930 | + <name>Antoni Batchelli</name> |
| 931 | + <uri></uri> |
| 932 | + </author> |
| 933 | + </entry> |
| 934 | + |
857 | 935 | <entry>
|
858 | 936 | <title>News: Hugo Duncan talking about Pallet at EuroClojure 2012</title>
|
859 | 937 | <link href="http://palletops.com//news/Euroclojure-2012-Pallet-Talk/"/>
|
|
0 commit comments