The deployment of the Emacs Survey.
https://emacssurvey.tecosaur.net
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
5.9 KiB
200 lines
5.9 KiB
#+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
|
|
that:
|
|
|
|
#+begin_src sh :tangle no
|
|
git clone https://git.tecosaur.net/tec/emacs-survey-server.git /tmp/emacs-survey-server
|
|
/tmp/emacs-survey-server/setup.sh
|
|
#+end_src
|
|
|
|
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
|
|
fi
|
|
#+end_src
|
|
|
|
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
|
|
JULIA_VERSION="1.8.2"
|
|
#+end_src
|
|
|
|
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
|
|
fi
|
|
#+end_src
|
|
|
|
* 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")")
|
|
#+end_src
|
|
|
|
** Caddy Config
|
|
:PROPERTIES:
|
|
:header-args:prog: :tangle Caddyfile
|
|
:END:
|
|
|
|
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
|
|
#+end_src
|
|
|
|
We'll just pass all other requests to the public folder of the Emacs Survey.
|
|
|
|
#+begin_src prog
|
|
root * /opt/emacs-survey/public
|
|
file_server
|
|
#+end_src
|
|
|
|
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}
|
|
}
|
|
}
|
|
#+end_src
|
|
|
|
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"
|
|
#+end_src
|
|
|
|
** 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
|
|
fi
|
|
#+end_src
|
|
|
|
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
|
|
else
|
|
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
|
|
fi
|
|
#+end_src
|
|
|
|
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()'
|
|
#+end_src
|
|
|
|
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()'
|
|
fi
|
|
#+end_src
|
|
|
|
* Genie service
|
|
|
|
To actually run the survey, we'll use a systemd service.
|
|
|
|
#+begin_src systemd :tangle genie-app.service
|
|
[Unit]
|
|
Description=Genie app
|
|
After=network.target network-online.target
|
|
Requires=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
Restart=on-failure
|
|
User=genie
|
|
Group=genie
|
|
ExecStart=/opt/emacs-survey/bin/server
|
|
WorkingDirectory=/opt/emacs-survey
|
|
Environment="GENIE_ENV=prod"
|
|
Environment="JULIA_NUM_THREADS=auto"
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
#+end_src
|
|
|
|
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
|
|
#+end_src
|
|
|
|
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
|
|
#+end_src
|
|
|