5.9 KiB


We could do something fancy like a NixOS flake, but for the Emacs Survey server I think a simple Debian machine with a setup script should do the trick. Let's just work out a setup script to get everything up and running.

The idea is that this repository can be cloned/updated anywhere on the machine and sudo setup.sh will do the rest. In fact, here's a snippet to do exactly that:

git clone https://git.tecosaur.net/tec/emacs-survey-server.git /tmp/emacs-survey-server

Remember to (re)start services as appropriately, as this script leaves that to be done manually.

Installing software

Caddy web server

if ! dpkg -s caddy > /dev/null; then
    printf "\e[1;34mInstalling Caddy\e[m\n"
    # Taken from <https://caddyserver.com/docs/install#debian-ubuntu-raspbian>
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
    sudo apt update
    sudo apt install caddy

There are two notable extras that come with the Caddy software itself here:

  1. A systemd service automatically started that loads /etc/caddy/Caddyfile.
  2. The caddy user and caddy group.


First, we specify the Julia version we want and hope that the relevant paths continue to be predictable.


If either the julia command does not exist, or julia --version does not match the expected output, then we will install Julia in /opt/julia and symlink the binary into /usr/bin.

if ! command -v julia > /dev/null || [ ! "$(julia --version)" = "julia version $JULIA_VERSION" ]; then
    printf "\e[1;34mInstalling Julia\e[m\n"
    cd /tmp || exit 2
    # Following <https://julialang.org/downloads/platform/>
    wget "https://julialang-s3.julialang.org/bin/linux/x64/${JULIA_VERSION%.*}/julia-$JULIA_VERSION-linux-x86_64.tar.gz"
    mkdir -p "/opt/julia/"
    tar zxf "julia-$JULIA_VERSION-linux-x86_64.tar.gz" --directory=/opt/julia
    ln -sf "/opt/julia/julia-$JULIA_VERSION/bin/julia" /usr/bin/julia

Copying over relevant files

Before starting to do this, we will obtain the path to the folder of the script, so we can grab files relative to the root of this repository.

SETUPDIR=$(dirname "$(readlink --canonicalize-existing "$0")")

Caddy Config

We just need to redirect to Genie for now, which makes for a rather simple config. The only complication is serving the static files through Caddy not Genie, for performance reasons (Genie recommends against serving static files with it).

emacssurvey.tecosaur.net emacssurvey.org

@dynamic {
	not path /css/*
	not path /faq.html
	not path /favicon.ico
	not path /robots.txt
reverse_proxy @dynamic localhost:8000

We'll just pass all other requests to the public folder of the Emacs Survey.

root * /opt/emacs-survey/public

For HTTP errors we could re-use the Genie error pages … or have some fun 🐱.

handle_errors {
	rewrite * /{err.status_code}
	reverse_proxy https://http.cat {
		header_up Host {upstream_hostport}

Just this one file is all it takes to get Caddy set up to our liking 🙂.

cp -f "$SETUPDIR/Caddyfile" "/etc/caddy/Caddyfile"

Emacs Survey

Before we start copying files, we want to make sure these files are owned by the genie user, and so me must first ensure that the user exists.

if ! id genie >/dev/null; then
    groupadd -f genie
    useradd -r -g genie -m -d /var/lib/genie genie

This is actually a separate repo, so we need to ensure it exists, and update it if it does.

if [ -d /opt/emacs-survey ]; then
    cd /opt/emacs-survey || exit 2
    printf "\e[1;34mUpdating emacs-survey\e[m\n"
    sudo -u genie git pull origin main --ff-only
    mkdir -p /opt/emacs-survey
    chown genie:genie /opt/emacs-survey
    printf "\e[1;34mCloning emacs-survey\e[m\n"
    sudo -u genie git clone https://git.tecosaur.net/tec/emacs-survey /opt/emacs-survey

Then lets make sure that the packages are up to date.

printf "\e[34mInstantiating emacs-survey\e[m\n"
sudo -u genie julia --project=/opt/emacs-survey -e 'using Pkg; Pkg.instantiate()'

We also need to ensure that a secrets token exists.

if [ ! -e "/opt/emacs-survey/config/secrets.jl" ]; then
   printf "\e[34mCreating genie secrets token\e[m\n"
   cd /opt/emacs-survey
   sudo -u genie julia --project=/opt/emacs-survey -e 'using Genie; Genie.Generator.write_secrets_file()'

Genie service

To actually run the survey, we'll use a systemd service.

Description=Genie app
After=network.target network-online.target



Then we need to put this is the systemd folder, and make sure it is aware of the latest version of the service.

cp -f "$SETUPDIR/genie-app.service" /etc/systemd/system/
systemctl daemon-reload

To get this up and running, all one has to do is execute the following:

systemctl enable --now genie-app.service