I'm using docker on my local box for some apps I can't (or don't want) to install, one of them being openresty (until there's a guix package (or I manage to create it), I'll keep it that way). But using docker for local development is a bit more complex than just running an app there.
First, a few tips for using docker for local development:
Using docker without sudo
By default, docker asks for superuser permissions in order to comunicate to docker server. You have to create a user group called docker and add your user to that group. After that, you can run docker commands as your regular user.
Building docker images and running them
In the beginning,I was creating lots of images, because every time you change any code in your app, the image has to be rebuilt. To build an image, being in your app directory (where your Dockerfile is and your code is), you normally do 'docker build .' Then, after building, the last line of the output contains the hash for that image in a line like: 'Successfully built 01b4cd5d3e'. you normally want to run it afterwards, so you'll 'docker run -t -i 01b4cd5d3e bash', to get in a console inside it. I just wrote a couple of shell functions to ease the loop of build and run.
function dbuild { export DBUILD=$(docker build . | grep "Successfully built" | col -b | awk '{print $3}') echo -n $DBUILD } function dattach () { docker run -t -i $DBUILD bash }
With this I can save the copypasting of the image id.
There's yet a better trick to not have to rebuild the image every time, which is to mount a directory of the host machine inside the container. For this to happen, we have to add the '-v' flat to docker run. Now, in the docker file, we'll create a directory for our code to be in, and just mount it the current directory in that place. In my case, the directory is '/opt/apisonator'.
function dattach () { docker run -v $(pwd):/opt/apisonator/:rw -t -i $DBUILD bash }
With this, we have a pretty slick way to run our code and tests inside docker, with full access to the docker, but also being in synch with the outside.
Sooo.... what about emacs?
In case you have many images and containers, you'll probably want to do bulk actions on them (running them, deleting, etc.). Emacs has 2 modes for interacting with docker: docker.el and docker-tramp.el .
The first one (docker.el) uses tabulated-list to show all docker images and containers in your machine, and allows you to run, pause,kill, push or pull images and containers.
Docker-tramp.el allows you to use tramp to access the files inside the container from your host emacs. That's pretty pretty neat: c-x c-f //docker:012f23e2fb/var/logs/.... .
Again, emacs saves the day.