
In this post, we are going to take a look at how we can run docker commands from Common Lisp. Lately I have been exploring Common Lisp development in Docker. So I have to run docker commands from a terminal frequently.
I was basically looking for a way to run docker commands within SLIME itself. Then I came across theuiop:run-program function from theCommon Lisp Cookbook
uiop:run-program
fully portably runs a program as a synchronous external subprocess.
So if you want to list all the Docker containers from SLIME or any Lisp REPL, you have to call therun-program
function like this:
(uiop:run-program"docker ps -a":outputt)
We need to provide the:output t
argument to print the results of the command to the standard output.
The result will be something like:
CL-USER> (uiop:run-program "docker ps -a" :output t)CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES673b20976166 docker101tutorial "/docker-entrypoint.…" 19 months ago Exited (0) 4 days ago docker-tutorialNILNIL0
cl-docker
Running docker commands everytime usinguiop:run-program
and passing all the options to print the output to the standard output felt like a time-consuming and non-Lispy way of doing stuff for me.
I wanted to run docker commands in a more natural way using Lisp, so I planned to write a package for the same. The original inspiration for this idea came from another Common Lisp package calledcl-virtualbox byFernando Borretti.cl-virtualbox
is a library that allows you to control VirtualBox from Common Lisp, by calling thevboxmanage
command.
So our new package calledcl-docker will allow us to control Docker from Common Lisp by calling thedocker
command.
Installation
(ql:quickload:cl-docker)
Usage
So now, to list out all the Docker containers in your machine, you can just call the below function in your REPL
;; List all docker containers(docker:ps:a)
Output:
"CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES673b20976166 docker101tutorial \"/docker-entrypoint.…\" 19 months ago Exited (0) 16 hours ago docker-tutorial"NIL0
Following is some of the docker commands and their correspondingcl-docker
functions
docker command | cl-docker |
---|---|
docker ps -a | (docker:ps :a) |
docker images | (docker:images) |
docker build DIRECTORY | (docker:build "myimage") |
docker rm CONTAINER | (docker:rm "web") |
docker start CONTAINER | (docker:start "web") |
docker stop CONTAINER | (docker:stop "web") |
The more complete list of commands can be viewed from the projectREADME
Moving away from uiop:run-program
Usinguiop:run-program
to run and manage docker from Common Lisp seems like an easy way to get things done. But it's not a clean and scalable way of doing things, basically we are interfacing with docker using the operating system command line capabilities. There are still issues in capturing the proper output, error information and unnecessary output likeNIL
and0
, which are actually the function return values and the return codes for the commands you run withuiop:run-program
.
So how do we get around these things? The best way to properly manage docker from Common Lisp is to use theDocker Engine SDKs.
Docker provides an API for interacting with the Docker daemon (called the Docker Engine API), as well as SDKs for Go and Python. At present, there is no pre-built SDK available for Common Lisp.
The SDKs allow you to build and scale Docker apps and solutions quickly and easily. So for Common Lisp, we have to use the Docker Engine API directly.
The Docker Engine API is a RESTful API accessed by an HTTP client such as wget or curl, or the HTTP library which is part of most modern programming languages.
Using the SDK API to get a list of containers, just like usingdocker ps
, we need to send a curl request like this:
curl --unix-socket /var/run/docker.sock http://localhost/v1.41/containers/json
All we need to figure out is how to replicate this curl request in Common Lisp using an HTTP Client library using unix sockets. That's what I am trying to figure out now. If you have any ideas, please let me know in the comments.
cl-docker
is still in early stages of development. It may not have covered all the docker commands with all the options that can be provided. So please give a try to the package and let me know for any queries/feedback in the comments section. You can also raise bug fixes, enhancements and feature requests through the Githubissues
Top comments(2)
For further actions, you may consider blocking this person and/orreporting abuse