diff options
author | Tom Willemse | 2016-02-21 15:52:51 +0100 |
---|---|---|
committer | Tom Willemse | 2016-02-21 15:52:51 +0100 |
commit | 141b1f40d93ab521a35ecfed97ff9230e32ddd94 (patch) | |
tree | 06000b9e655ce200a22d7b71a2e64e84443922ff /wdocker_compose.post | |
parent | 57c0d1cc3da53bce340be25924372cbcb024d184 (diff) | |
download | blog-141b1f40d93ab521a35ecfed97ff9230e32ddd94.tar.gz blog-141b1f40d93ab521a35ecfed97ff9230e32ddd94.zip |
Publish "Making docker-compose easier with wdocker"
Diffstat (limited to 'wdocker_compose.post')
-rw-r--r-- | wdocker_compose.post | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/wdocker_compose.post b/wdocker_compose.post new file mode 100644 index 0000000..dc61bf8 --- /dev/null +++ b/wdocker_compose.post @@ -0,0 +1,237 @@ +;;;;; +title: Making docker-compose easier with wdocker +date: 2016-02-21 +tags: wdocker docker docker-compose +format: html +;;;;; + +<div id="outline-container-orgheadline1" class="outline-2"> +<h2 id="orgheadline1"><span class="section-number-2">1</span> Introduction</h2> +<div class="outline-text-2" id="text-1"> +<p> +<a href="https://github.com/babab/wdocker">wdocker</a> is a little utility written by a <a href="https://benjamin.althu.es">friend</a> and former colleague +of mine. It allows you to define commands for it in a +<code>Dockerfile</code>. He wrote it because he used a lot of composite +commands when writing docker images like: +</p> + +<div class="org-src-container"> + +<pre class="src src-sh">docker stop CONTAINER && docker rm CONTAINER && docker rmi IMAGE && <span class="org-sh-escaped-newline">\</span> + docker build -t IMAGE && docker run --name CONTAINER IMAGE +</pre> +</div> + +<p> +By using wdocker to define a command he can greatly simplify his own +workflow. Let's call it rebuild: +</p> + +<div class="org-src-container"> + +<pre class="src src-dockerfile"><span class="org-comment-delimiter">#</span><span class="org-comment">wd# container = CONTAINER</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# image = IMAGE</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# stop = docker stop {container}</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# rm = docker rm {container}</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# rmi = docker rmi {container}</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# build = docker build -t {image}</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# run = docker run --name {container} {image}</span> + +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# rebuild: {stop} && {rm} && {rmi} && {build} && {run}</span> + +<span class="org-keyword">FROM</span> ubuntu + +<span class="org-comment-delimiter"># </span><span class="org-comment">...</span> +</pre> +</div> + +<p> +Now he can use the following command instead of the list presented +before: +</p> + +<pre class="example"> +wdocker rebuild +</pre> +</div> +</div> + +<div id="outline-container-orgheadline2" class="outline-2"> +<h2 id="orgheadline2"><span class="section-number-2">2</span> Syntax</h2> +<div class="outline-text-2" id="text-2"> +<p> +wdocker has very simple syntax. You can define variables and +commands: +</p> + +<pre class="example"> +#wd# variable = value +#wd# command: program +</pre> + +<p> +Variables can be used by putting them in braces, including in other +variables, as you've seen in the first example. +</p> + +<pre class="example"> +#wd# variable = -l +#wd# list: ls {variable} +</pre> + +<p> +This would run <code>ls -l</code> when the command <code>wdocker list</code> is called. +</p> + +<p> +As you can see you're not limited to using docker in your wdocker +commands. This property is what allows me to use wdocker in my +workflow. +</p> +</div> +</div> + +<div id="outline-container-orgheadline3" class="outline-2"> +<h2 id="orgheadline3"><span class="section-number-2">3</span> Combining with docker-compose</h2> +<div class="outline-text-2" id="text-3"> +<p> +I started using docker not too long ago at work to develop our +projects in. This is nice because it allows me to completely isolate +my development environments. Since we have a few processes running +together a single docker image isn't a great option, so I use +docker-compose to define and combine the containers I need. +</p> + +<p> +As a side-effect this requires me to write long commands to do +something like run rspec tests: +</p> + +<pre class="example"> +docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test \ + container bundle exec rspec +</pre> + +<p> +The alternative is defining a specialized test container with a +bogus entry command (such as <code>true</code>) and use that, which would still +make the command: +</p> + +<pre class="example"> +docker-compose run --rm test-container bundle exec rspec +</pre> + +<p> +Instead I can define a wdocker command in the <code>Dockerfile</code> used to +build the containers used: +</p> + +<div class="org-src-container"> + +<pre class="src src-dockerfile"><span class="org-comment-delimiter">#</span><span class="org-comment">wd# rspec: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec rspec</span> + +<span class="org-keyword">FROM</span> ruby + +<span class="org-comment-delimiter">#</span><span class="org-comment">...</span> +</pre> +</div> + +<p> +Now I can run the following, much shorter, command to run the rspec +tests: +</p> + +<pre class="example"> +wdocker rspec +</pre> + +<p> +We also use cucumber for some other tests, which is even longer to +type in, adding the <code>cucumber</code> command is easy: +</p> + +<div class="org-src-container"> + +<pre class="src src-dockerfile"><span class="org-comment-delimiter">#</span><span class="org-comment">wd# rspec: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec rspec</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# cucumber: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec cucumber</span> + +<span class="org-keyword">FROM</span> ruby + +<span class="org-comment-delimiter"># </span><span class="org-comment">...</span> +</pre> +</div> + +<p> +Now I can run <code>wdocker cucumber</code> as well. +</p> + +<p> +The latest git version of wdocker passes any arguments after the +command name directly to the command to be executed. So if I need to +run tests in a single spec file I can just do: +</p> + +<pre class="example"> +wdocker rspec spec/models/mymodel_spec.rb +</pre> + +<p> +We have two commands defined now that are 90% the same. I always use +the <code>--rm</code> switch to remove the started container after it's done, I +don't want a lot of containers piling up. I also always have to use +<code>bundle exec</code> to run commands, since the containers don't use rvm or +add the script directories to <code>$PATH</code>. We can extract them to some +variables: +</p> + +<div class="org-src-container"> + +<pre class="src src-dockerfile"><span class="org-comment-delimiter">#</span><span class="org-comment">wd# run = docker-compose run --rm</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# exec = bundle exec</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# test = -e RACK_ENV=test -e RAILS_ENV=test</span> + +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# rspec: {run} {test} container {exec} rspec</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# cucumber: {run} {test} container {exec} cucumber</span> + +<span class="org-keyword">FROM</span> ruby + +<span class="org-comment-delimiter"># </span><span class="org-comment">...</span> +</pre> +</div> + +<p> +Right now these commands always use the <code>container</code> service defined +in <code>docker-compose.yml</code>. I could add it to the <code>run</code> command, but I +might need to run some commands on another container, but I can +define another variable: +</p> + +<div class="org-src-container"> + +<pre class="src src-dockerfile"><span class="org-comment-delimiter">#</span><span class="org-comment">wd# run = docker-compose run --rm</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# test = -e RACK_ENV=test -e RAILS_ENV=test</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# run-test-container = {run} {test} container</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# exec = bundle exec</span> + +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# rspec: {run-test-container} {exec} rspec</span> +<span class="org-comment-delimiter">#</span><span class="org-comment">wd# cucumber: {run-test-container} {exec} cucumber</span> + +<span class="org-keyword">FROM</span> ruby + +<span class="org-comment-delimiter"># </span><span class="org-comment">...</span> +</pre> +</div> + +<p> +Now you also see that variables can be nested in other variables. +</p> + +<p> +If you ever forget what you defined or if the mix of commands and +variables becomes too much for you, you can call the wdocker command +without arguments to see the commands you defined and the shell +commands they'll run. +</p> +</div> +</div> |