201 lines
5.9 KiB
Org Mode

#+title: Setup
#+property: header-args :comments no
#+property: header-args:sh :tangle yes :shebang "#!/usr/bin/env sh" :eval no
We could do something fancy like a NixOS flake, but for the [[https://git.tecosaur.net/tec/emacs-survey][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
#+begin_src sh :tangle no
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
#+begin_src sh
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.
** Julia
First, we specify the Julia version we want and hope that the relevant paths
continue to be predictable.
#+begin_src sh
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=.
#+begin_src sh
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.
#+begin_src sh
SETUPDIR=$(dirname "$(readlink --canonicalize-existing "$0")")
** Caddy Config
:header-args:prog: :tangle Caddyfile
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).
#+begin_src prog
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.
#+begin_src prog
root * /opt/emacs-survey/public
For HTTP errors we could re-use the Genie error pages ... or have some fun 🐱.
#+begin_src prog
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 🙂.
#+begin_src sh
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.
#+begin_src sh
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.
#+begin_src sh
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.
#+begin_src sh
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.
#+begin_src sh
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.
#+begin_src systemd :tangle genie-app.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.
#+begin_src sh
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:
#+begin_src sh :tangle no
systemctl enable --now genie-app.service