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
-
EXPOSEan 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 replas your imageENTRYPOINT - use
cider-connectinstead ofcider-jack-into 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
~/.m2folder is also mounted inside the container. - Instead of
EXPOSE'ing ports and configuring the project, I use--net=hoston thedocker runcommand. -
WORKDIRinstead ofcdwithinENTRYPOINT -
ENTRYPOINTis justlein. This is so that you are able to easily run commands other thanreplat container start (you can usereplas default throughCMD). Most of the time, though,ENTRYPOINTis 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-xcider-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