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.
emacs-survey-server/setup.org

201 lines
5.9 KiB

2 months ago
#+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:
2 months ago
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).
2 months ago
#+begin_src prog
emacssurvey.tecosaur.net emacssurvey.org
2 months ago
@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
2 months ago
#+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
2 months ago
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
2 months ago
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
2 months ago
User=genie
Group=genie
ExecStart=/opt/emacs-survey/bin/server
WorkingDirectory=/opt/emacs-survey
Environment="GENIE_ENV=prod"
Environment="JULIA_NUM_THREADS=auto"
2 months ago
[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