include setup instructions.
2 files changed, 150 insertions(+), 0 deletions(-)

M README
A => doc/setup.org
M README +8 -0
@@ 47,6 47,14 @@ Also see
 
     make help
 
+Publish on a server
+-------------------
+
+see [doc/setup.org](doc/setup.org).
+
+An example is <https://dryads-wake.1w6.org>
+
+
 Install with Guix
 -----------------
 

          
A => doc/setup.org +142 -0
@@ 0,0 1,142 @@ 
+#+title: How to setup Dryads Wake on a Server
+
+/These installation instructions are for Debian, because that’s what my small server runs on./
+
+* Install requirements
+
+- fibers: git clone https://github.com/wingo/fibers 
+- guile-websocket: git clone https://git.dthompson.us/guile-websocket.git
+- wisp: hg clone https://hg.sr.ht/~arnebab/wisp
+- dryads-wake: hg clone https://hg.sr.ht/~arnebab/dryads-wake
+
+#+begin_src bash
+sudo apt install guile-3.0 guile-3.0-dev guile-3.0-doc guile-3.0-libs
+#+end_src
+
+* nginx as SSL terminator
+
+This is the simplest possible change to make an SSL terminator for Dryads Wake.
+
+#+begin_src nginx :file "/etc/nginx/sites-enabled/default"
+server {
+
+	root /var/www/html;
+
+	# Add index.php to the list if you are using PHP
+	index index.html index.htm index.nginx-debian.html;
+
+	server_name dryads-wake.1w6.org;
+
+	# bab: dryads wake
+
+	location / {
+		proxy_pass http://localhost:9423;
+	}
+
+    # dsgvo allowed logging
+    access_log /var/log/nginx/dryads-wake-access.log anonymized;
+
+    listen [::]:443 ssl ipv6only=on; # managed by Certbot
+    listen 443 ssl; # managed by Certbot
+    ssl_certificate /etc/letsencrypt/live/dryads-wake.1w6.org/fullchain.pem; # managed by Certbot
+    ssl_certificate_key /etc/letsencrypt/live/dryads-wake.1w6.org/privkey.pem; # managed by Certbot
+    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
+    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
+
+}
+server {
+    if ($host = dryads-wake.1w6.org) {
+        return 301 https://$host$request_uri;
+    } # managed by Certbot
+
+
+	listen 80 default_server;
+	listen [::]:80 default_server;
+
+	server_name dryads-wake.1w6.org;
+    return 404; # managed by Certbot
+}
+#+end_src
+
+* Regular maintenance
+
+#+begin_src crontab
+# m h  dom mon dow   command
+0 12 * * * /usr/bin/certbot renew --quiet
+# disabled: redeploy once per week because it might have died
+0 3 * * 6 bash --login -c "~/.local/bin/update-dryads-wake.sh"
+# start every minute if needed (currently it dies after a while)
+,* * * * * bash --login -c "~/.local/bin/restart-dryads-wake-if-it-died.sh"
+#+end_src
+
+#+begin_src bash :file "~/.local/bin/update-dryads-wake.sh"
+#!/usr/bin/env bash
+# precompile to minimize downtime
+# scheme-code
+cd ~/dryads-wake && if hg incoming; then
+	hg pull -u
+	# pre-compile wisp language stuff
+	for i in */*.scm */*/*.scm; do echo 'compiling' $i; guile -L . "$i"; done
+	# pre-compile game
+	wisp -L . -c 'import : dryads-wake'
+	# replace running instance
+	pkill -f ./dryads-wake.w ; sleep 1; nohup ./dryads-wake.w --server > /tmp/dryads-wake-$(date --iso).log &
+fi
+#+end_src
+
+#+begin_src bash :file "~/.local/bin/restart-dryads-wake-if-it-died.sh"
+#!/usr/bin/env bash
+export LOGFILE="/tmp/dryads-wake-$(date --iso).log"
+echo >> "${LOGFILE}"
+whoami >> "${LOGFILE}"
+date >> "${LOGFILE}"
+sleep $((($RANDOM % 45)))
+cd ~/dryads-wake && \
+    (curl --connect-timeout 15 http://localhost:9423 | grep dryads-wake-content || pkill guile) && \
+    nohup ./dryads-wake.w --server  >> "${LOGFILE}" 2>&1 &
+#+end_src
+
+#+begin_src bash :file "~/.local/bin/redeploy-dryads-wake.sh"
+#!/usr/bin/env bash
+cd ~/dryads-wake && hg pull -u && \
+    pkill -f ./dryads-wake.w ; sleep 1; \
+    nohup ./dryads-wake.w --server > /tmp/dryads-wake-$(date --iso).log &
+#+end_src
+
+Add the Guile paths as prefix to =~/.bashrc=, so the cron has it.
+
+#+begin_src bash :file "~/.bashrc"
+# add /usr/local for guile
+export GUILE_LOAD_COMPILED_PATH=/usr/local/lib/guile/3.0/ccache:/usr/local/lib/guile/3.0/site-ccache
+export GUILE_LOAD_PATH=/usr/local/share/guile/site/3.0/
+
+# If not running interactively, don't do anything
+case $- in
+    *i*) ;;
+      *) return;;
+esac
+#+end_src
+
+Always add readline for guile:
+
+#+begin_src scheme :file "~/.guile"
+(cond ((false-if-exception (resolve-interface '(ice-9 readline)))
+       =>
+       (lambda (module)
+         ;; Enable completion and input history at the REPL.
+         ((module-ref module 'activate-readline))))
+      (else
+       (display "Consider installing the 'guile-readline' package for
+convenient interactive line editing and input history.\n\n")))
+
+(unless (getenv "INSIDE_EMACS")
+  (cond ((false-if-exception (resolve-interface '(ice-9 colorized)))
+         =>
+         (lambda (module)
+           ;; Enable completion and input history at the REPL.
+           ((module-ref module 'activate-colorized))))
+        (else
+         (display "Consider installing the 'guile-colorized' package
+for a colorful Guile experience.\n\n"))))
+#+end_src
+