My normal setup works very nicely, using CIDER in emacs for both front-end and back-end (C-M-J). Things get complicated as I try to get my student workers set up, especially if there’s a database involved; for this reason, Docker would make a lot of sense. But my docker-fu is a bit weak; I don’t expect I’ll be able to get anything as easy as C-M-J, but how might I set up a compose situation that includes my DB (e.g. postgres) and also will provide me all the REPL hot-loading glory I need for development? Does anyone have any docker-based workflows or sample DOCKERFILE they would share?
I don’t have a Dockerfile ready to hand (or a docker-compose.yml
for that matter) but I think that if your goal is to have a Docker image where e.g., the JDK and lein
live, but still be able to have REPL-driven development with CIDER against the Clojure runtime inside that container, it would be as simple as:
- Mount your local project dir as a volume inside the container
-
EXPOSE
an nREPL port (and do the necessary config in your project to specify a known port for nREPL) - start the project up with something like
cd /mounted/project/volume && lein repl
as your imageENTRYPOINT
- use
cider-connect
instead ofcider-jack-in
to attach to the REPL - visit the files you want to change on your local disk, C-M-J to your heart’s content
In this case you’re running the REPL inside the container, connecting to it “remotely” from your emacs process on the host machine, while visiting/editing files that are on local disk but also mounted into the container.
I’ve also found this relevant video, although he jumps through all kinds of hoops and it’s a bit imposing for those of us with time constraints… https://www.youtube.com/watch?v=FtkHgQSSb3c
Most of what @chris mentioned - minor differences mostly for development:
- The host’s
~/.m2
folder is also mounted inside the container. - Instead of
EXPOSE
'ing ports and configuring the project, I use--net=host
on thedocker run
command. -
WORKDIR
instead ofcd
withinENTRYPOINT
-
ENTRYPOINT
is justlein
. This is so that you are able to easily run commands other thanrepl
at container start (you can userepl
as default throughCMD
). Most of the time, though,ENTRYPOINT
is set to a shell for more flexibility.
Ah – an excellent blog post that covers the setup with clojure in detail: http://danlebrero.com/2017/09/25/how-do-docker-compose-development-environement/ . I’ll be experimenting with this and will report back.
I don’t have a template Dockerfile extracted, but the rough steps I followed to get CIDER attached (to a remote container, which is slightly different from your needs) were:
- expose a REPL port from the container to the outside world
- embed an nREPL server in your application, so the app and the REPL are in the same process
- on your local machine, have CIDER 0.16.0 installed and
{:user {:plugins [[cider/cider-nrepl "0.16.0"]]}}
in your lein profile (~/.lein/profiles.clj) -
M-x
cider-connect
/C-c C-c
I put the host in my SSH config (~/.ssh/config) and therefore need to have the variable nrepl-use-ssh-fallback-for-remote-hosts
set to t
, which you can do by putting (setq nrepl-use-ssh-fallback-for-remote-hosts t)
in your ~/.emacs.d/init.el.
This process makes the Docker side of things rather minimal—just the port.
Did you get an answer to this? I have a component-based app, where one of the components is a repl-server. But the main point is that i) your repl in your container, will be listening on a port. And ii) you just need to expose that port, outside of the container.
So with an app Dockerfile as in A), you can have a docker-compose setup, as in B). Once you i) docker build ...
your image then ii) docker-compose up
, you can connect to the repl on the localhost port 5678. Hth.
A) Dockerfile
FROM pandeiro/lein:latest
COPY project.clj /your-app-location
WORKDIR /your-app-location
RUN lein deps
B) docker-compose.yml
version: '3.3'
services:
some-db:
image: namespace/some-db:1.2.3
ports:
- 1234:1234
your-app:
image: namespace/your-app:latest
depends_on:
- some-db
ports:
- 5678:5678
entrypoint: lein some-lein-alias-that-runs-a-repl-on-port-5678