Deployment and CI

53.1 Docker

Pin dependencies with Qlot/ocicl or a fixed Quicklisp dist version for reproducible builds.

FROM clfoundation/sbcl:latest AS build      # or a Debian image + apt install sbcl
WORKDIR /app
RUN curl -O https://beta.quicklisp.org/quicklisp.lisp && \
    sbcl --non-interactive --load quicklisp.lisp --eval '(quicklisp-quickstart:install)'
COPY . /root/quicklisp/local-projects/my-app/
RUN sbcl --non-interactive --load /root/quicklisp/setup.lisp \
         --eval '(ql:quickload "my-app")' \
         --eval '(asdf:make "my-app/executable")'

FROM debian:bookworm-slim
COPY --from=build /root/quicklisp/local-projects/my-app/bin/my-app /usr/local/bin/my-app
EXPOSE 8080
CMD ["my-app"]

53.2 Long-Running Servers and Live Updates

Run under systemd or in a container. Optionally start a Swank/Slynk server (on localhost, behind SSH) to connect your editor to the production image for live inspection and hot patches, with appropriate caution and access control.

(ql:quickload "swank")
(swank:create-server :port 4005 :dont-close t)   ; then M-x slime-connect through an SSH tunnel

53.3 Continuous Integration

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        lisp: [sbcl-bin, ccl-bin]
    steps:
      - uses: actions/checkout@v4
      - uses: 40ants/setup-lisp@v4          # installs Roswell + the chosen implementation + Qlot
        with:
          asdf-system: my-app
      - uses: 40ants/run-tests@v2
        with:
          asdf-system: my-app