diff --git a/wdocker_compose.org b/wdocker_compose.org index fe42365..d3d504b 100644 --- a/wdocker_compose.org +++ b/wdocker_compose.org @@ -1,4 +1,6 @@ #+TITLE: Making docker-compose easier with wdocker +#+DATE: 2016-02-21 +#+COLESLAW_TAGS: wdocker docker docker-compose #+OPTION: num:nil * Introduction 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 +;;;;; + +
+wdocker is a little utility written by a 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:
+
docker stop CONTAINER && docker rm CONTAINER && docker rmi IMAGE && \
+ docker build -t IMAGE && docker run --name CONTAINER IMAGE
+
++By using wdocker to define a command he can greatly simplify his own +workflow. Let's call it rebuild: +
+ +#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# run = docker run --name {container} {image} + +#wd# rebuild: {stop} && {rm} && {rmi} && {build} && {run} + +FROM ubuntu + +# ... ++
+Now he can use the following command instead of the list presented +before: +
+ ++wdocker rebuild ++
+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. +
++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:
+
#wd# rspec: docker-compose run --rm -e RACK_ENV=test -e RAILS_ENV=test container bundle exec rspec + +FROM ruby + +#... ++
+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:
+
#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 + +# ... ++
+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:
+
#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 + +# ... ++
+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:
+
#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 + +# ... ++
+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. +
+