summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Willemse2016-02-17 01:03:19 +0100
committerTom Willemse2016-02-17 01:04:09 +0100
commit1f5e1c683a24aad559b5df1d23efe020b65d849b (patch)
treebc4720c6c52463bd6792e665f8adb9e41bcc023a
parent352f62af98359bd5c76fa1169fc115e2a8057e26 (diff)
downloadblog-1f5e1c683a24aad559b5df1d23efe020b65d849b.tar.gz
blog-1f5e1c683a24aad559b5df1d23efe020b65d849b.zip
Add post "Making docker-compose easier with wdocker"
-rw-r--r--wdocker_compose.org160
1 files changed, 160 insertions, 0 deletions
diff --git a/wdocker_compose.org b/wdocker_compose.org
new file mode 100644
index 0000000..e1190eb
--- /dev/null
+++ b/wdocker_compose.org
@@ -0,0 +1,160 @@
+#+TITLE: Making docker-compose easier with wdocker
+#+OPTION: num:nil
+
+* Introduction
+
+ [[https://github.com/babab/wdocker][wdocker]] is a little utility written by a [[https://benjamin.althu.es][friend]] and former colleague
+ of mine. It allows you to define commands for it in a
+ ~Dockerfile~. He wrote it because he used a lot of composite
+ commands when writing docker images like:
+
+ #+BEGIN_SRC sh
+ docker stop CONTAINER && docker rm CONTAINER && docker rmi IMAGE \
+ docker build -t IMAGE && docker start -n CONTAINER IMAGE
+ #+END_SRC
+
+ By using wdocker to define a command he can greatly simplify his own
+ workflow. Let's call it rebuild:
+
+ #+BEGIN_SRC dockerfile
+ #wd# container = CONTAINER
+ #wd# image = IMAGE
+ #wd# stop = docker stop {container}
+ #wd# rm = docker rm {container}
+ #wd# rmi = docker rmi {container}
+ #wd# build = docker build -t {image}
+ #wd# start = docker start -n {container} {image}
+
+ #wd# rebuild: {stop} && {rm} && {rmi} && {build} && {start}
+
+ FROM ubuntu
+
+ # ...
+ #+END_SRC
+
+ Now he can use the following command instead of the list presented
+ before:
+
+ : wdocker rebuild
+
+* Syntax
+
+ wdocker has very simple syntax. You can define variables and
+ commands:
+
+ : #wd# variable = value
+ : #wd# command: program
+
+ Variables can be used by putting them in braces, including in other
+ variables, as you've seen in the first example.
+
+ : #wd# variable = -l
+ : #wd# list: ls {variable}
+
+ This would run =ls -l= when the command =wdocker list= is called.
+
+ 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.
+
+* Combining with docker-compose
+
+ 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.
+
+ As a side-effect this requires me to write long commands to do
+ something like run rspec tests:
+
+ : docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test \
+ : container bundle exec rspec
+
+ The alternative is defining a specialized test container with a
+ bogus entry command (such as ~true~) and use that, which would still
+ make the command:
+
+ : docker-compose run --rm test-container bundle exec rspec
+
+ Instead I can define a wdocker command in the ~Dockerfile~ used to
+ build the containers used:
+
+ #+BEGIN_SRC dockerfile
+ #wd# rspec: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec rspec
+
+ FROM ruby
+
+ #...
+ #+END_SRC
+
+ Now I can run the following, much shorter, command to run the rspec
+ tests:
+
+ : wdocker rspec
+
+ We also use cucumber for some other tests, which is even longer to
+ type in, adding the ~cucumber~ command is easy:
+
+ #+BEGIN_SRC dockerfile
+ #wd# rspec: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec rspec
+ #wd# cucumber: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec cucumber
+
+ FROM ruby
+
+ # ...
+ #+END_SRC
+
+ Now I can run =wdocker cucumber= as well.
+
+ 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:
+
+ : wdocker rspec spec/models/mymodel_spec.rb
+
+ We have two commands defined now that are 90% the same. I always use
+ the ~--rm~ 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
+ ~bundle exec~ to run commands, since the containers don't use rvm or
+ add the script directories to ~$PATH~. We can extract them to some
+ variables:
+
+ #+BEGIN_SRC dockerfile
+ #wd# run = docker-compose run --rm
+ #wd# exec = bundle exec
+ #wd# test = -e RACK_ENV=test -e RAILS_ENV=test
+
+ #wd# rspec: {run} {test} container {exec} rspec
+ #wd# cucumber: {run} {test} container {exec} cucumber
+
+ FROM ruby
+
+ # ...
+ #+END_SRC
+
+ Right now these commands always use the ~container~ service defined
+ in ~docker-compose.yml~. I could add it to the ~run~ command, but I
+ might need to run some commands on another container, but I can
+ define another variable:
+
+ #+BEGIN_SRC dockerfile
+ #wd# run = docker-compose run --rm
+ #wd# test = -e RACK_ENV=test -e RAILS_ENV=test
+ #wd# run-test-container = {run} {test} container
+ #wd# exec = bundle exec
+
+ #wd# rspec: {run-test-container} {exec} rspec
+ #wd# cucumber: {run-test-container} {exec} cucumber
+
+ FROM ruby
+
+ # ...
+ #+END_SRC
+
+ Now you also see that variables can be nested in other variables.
+
+ 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.