From 77bffc8c84f0dd2f58307af0c5b40da67a13ff23 Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 16 Oct 2022 16:19:34 +0800 Subject: [PATCH] Initial commit --- Caddyfile | 3 + genie-app.service | 15 +++++ setup.org | 168 ++++++++++++++++++++++++++++++++++++++++++++++ setup.sh | 53 +++++++++++++++ 4 files changed, 239 insertions(+) create mode 100644 Caddyfile create mode 100644 genie-app.service create mode 100644 setup.org create mode 100755 setup.sh diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..3a9bea3 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,3 @@ +emacssurvey.tecosaur.net + +reverse_proxy localhost:8000 diff --git a/genie-app.service b/genie-app.service new file mode 100644 index 0000000..990e341 --- /dev/null +++ b/genie-app.service @@ -0,0 +1,15 @@ +[Unit] +Description=Genie app +After=network.target network-online.target +Requires=network-online.target + +[Service] +Type=simple +User=genie +Group=genie +ExecStart=/opt/emacs-survey/bin/server +WorkingDirectory=/opt/emacs-survey +Environment="GENIE_ENV=prod" + +[Install] +WantedBy=multi-user.target diff --git a/setup.org b/setup.org new file mode 100644 index 0000000..226300c --- /dev/null +++ b/setup.org @@ -0,0 +1,168 @@ +#+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 + 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 + 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 + +We just need to redirect to Genie for now, which makes for a rather simple +config. + +#+begin_src prog :tangle Caddyfile +emacssurvey.tecosaur.net + +reverse_proxy localhost:8000 +#+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" + 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 +User=genie +Group=genie +ExecStart=/opt/emacs-survey/bin/server +WorkingDirectory=/opt/emacs-survey +Environment="GENIE_ENV=prod" + +[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 diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..37e8854 --- /dev/null +++ b/setup.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env sh +if ! dpkg -s caddy > /dev/null; then + printf "\e[1;34mInstalling Caddy\e[m\n" + # Taken from + 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 + +JULIA_VERSION="1.8.2" + +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 + 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 + +SETUPDIR=$(dirname "$(readlink --canonicalize-existing "$0")") + +cp -f "$SETUPDIR/Caddyfile" "/etc/caddy/Caddyfile" + +if ! id genie >/dev/null; then + groupadd -f genie + useradd -r -g genie -m -d /var/lib/genie genie +fi + +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 + +printf "\e[34mInstantiating emacs-survey\e[m\n" +sudo -u genie julia --project=/opt/emacs-survey -e 'using Pkg; Pkg.instantiate()' + +if [ ! -e "/opt/emacs-survey/config/secrets.jl" ]; then + printf "\e[34mCreating genie secrets token\e[m\n" + sudo -u genie julia --project=/opt/emacs-survey -e 'using Genie; Genie.Generator.write_secrets_file()' +fi + +cp -f "$SETUPDIR/genie-app.service" /etc/systemd/system/ +systemctl daemon-reload