Here’s what I needed to do in order to get the Oddmuse 6 wiki up an running.
I downloaded and compiled the latest Rakudo Star sources (2018.06).
Install cro and Oddmuse 6:
zef install --/test cro zef install Oddmuse6
🔥 When installing dependencies using `zef` as shown, you could be running into an OpenSSL issue even if you have the correct development libraries installed. On Debian, you need `libssl-dev` but apparently versions 1.1.0f and 1.1.0g won’t work. See issue #34. You could decide to ignore SSL support and opt to have a web server act as a proxy which provides SSL. That’s what I intend to do. In which case there is a terrible workaround available: run `zef install --force-test IO::Socket::Async::SSL` before you `zef install Oddmuse6`.
Create a new application. Remember that installing `cro` printed a message telling you where the binary got installed. I’m assuming you added `$HOME/rakudo/share/perl6/site/bin` to your `PATH`.
Start with a stub and accept all the defaults:
cro stub http oddmuse6 oddmuse6
Now edit `oddmuse6/services.p6` and replace `use Routes` with `use Oddmuse::Routes`.
You can delete the `oddmuse6/lib/Routes.pm6` which `cro stub` generated for you.
Your default wiki directory is `oddmuse6/wiki`, so we need to tell `cro` to ignore it. If you don’t, you’ll confuse `cro` to no end as soon as you start editing files! Add the following section section to your in `oddmuse6/.cro.yml` file:
ignore: - wiki/
Run it:
cd oddmuse6 cro run
Check it out by visiting `http://localhost:20000`. Your wiki is ready! 🙃
But this is not enough. I needed to get my own domain. My name service provider for `oddmuse.org` is Gandi so I logged in, found the entry and added a new subdomain called `next` pointing at the same IP, basically a copy of the `www` subdomain.
Next, I tell Apache about it. I’m using Dehydrated to get my `oddmuse.org` certificates from *Let’s Encrypt* and I’m just going to reuse them.
In the file `/etc/dehydrated/domains.txt` I added the new `next.oddmuse.org` domain:
oddmuse.org www.oddmuse.org next.oddmuse.org
Then I ran `/usr/bin/dehydrated -c` as root to check and possibly renew all my certificates.
I’m using Apache as my webserver. I edited `/etc/apache2/sites-enabled/500-oddmuse.org.conf` and added two new sections for `next.oddmuse.org`.
The first redirects HTTP traffic to HTTPS:
<VirtualHost *:80> ServerName next.oddmuse.org Redirect permanent / https://next.oddmuse.org/ </VirtualHost>
The second redirects all HTTPS traffic it receives back to HTTP on port 20000, which is where Oddmuse 6 is listening.
<VirtualHost *:443> ServerAdmin alex@oddmuse.org ServerName next.oddmuse.org RewriteEngine on RewriteCond "%{HTTP_USER_AGENT}" "Mastodon" RewriteRule ".*" "-" [redirect=403,last] SSLEngine on SSLCertificateFile /var/lib/dehydrated/certs/oddmuse.org/cert.pem SSLCertificateKeyFile /var/lib/dehydrated/certs/oddmuse.org/privkey.pem SSLCertificateChainFile /var/lib/dehydrated/certs/oddmuse.org/chain.pem SSLVerifyClient None ProxyPass / http://next.oddmuse.org:20000/ </VirtualHost>
Thus, all connections to the wiki are encrypted. What about people connecting to port 20000 directly? Well, I have a file called `/etc/apache2/conf-enabled/security.conf` which has a few settings including this one:
# Setting this header will prevent access via HTTP. # Requires mod_headers to be enabled. # See https://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14#section-6.1.2 # The number of seconds is the equivalent of one year. # Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
The rewrite rule for Mastodon is a simple defence against the spikes I get when I share links to my sites. In a second, all the servers seeing the link attempt to fetch a preview image and in order to avoid overloads, I just disallow these.
So now, finally, requests end up as simple HTTP on 20000. Unfortunately, the wiki is listening on `localhost`, not `next.oddmuse.org`.
So I wrote a little wrapper script to set all the options, write a PID file and all that. I called it `~/bin/oddmuse6`.
#!/bin/bash pidfile=$HOME/oddmuse6/nohup.pid if test -f $pidfile; then echo Killing $(cat $pidfile) kill -SIGTERM $(cat $pidfile) fi export ODDMUSE_MENU="Home, Changes, About" export ODDMUSE_QUESTION="Name a colour of the rainbow." export ODDMUSE_ANSWER="red, orange, yellow, green, blue, indigo, violet" export ODDMUSE_SECRET="rainbow-unicorn" export ODDMUSE_HOST="next.oddmuse.org" export ODDMUSE_PORT=20000 cd $HOME/oddmuse6 rm nohup.out nohup /home/alex/rakudo/bin/perl6 service.p6 & tail nohup.out echo $! > $pidfile
But that still isn’t enough because `ODDMUSE_HOST` and `ODDMUSE_PORT` actually don’t match the environment variables used in `oddmuse6/service.p6`. Each `cro` service gets to environment variables that determine its *host* and its *port*. Their names depend on the name you provided when you called `cro stub`. If you called it `oddmuse6` like I did in the example above, the two environment variables you need are called `ODDMUSE6_HOST` and `ODDMUSE6_PORT`. I just changed them to `ODDMUSE_HOST` and `ODDMUSE_PORT` in `service.p6`.
As you can see from the shell script, I’m not even using `cro run` to run my wiki. I’m using `perl6` directly. I’ll have to think about that. I suspect there are benefits of using `cro run` when you use multiple applications. At the moment I don’t, so `perl6` it is.
Since I’m not using `cro run` you could delete all these other files, actually. You really just need `service.p6` and the `wiki` subdirectory.
The content of `service.p6` is simple:
use Cro::HTTP::Log::File; use Cro::HTTP::Server; use Oddmuse::Routes; my Cro::Service $http = Cro::HTTP::Server.new( http => <1.1>, host => %*ENV<ODDMUSE_HOST> || die("Missing ODDMUSE_HOST in environment"), port => %*ENV<ODDMUSE_PORT> || die("Missing ODDMUSE_PORT in environment"), application => routes(), after => [ Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR) ] ); $http.start; say "Listening at http://%*ENV<ODDMUSE_HOST>:%*ENV<ODDMUSE_PORT>"; react { whenever signal(SIGINT) { say "Shutting down..."; $http.stop; done; } }
Check it out: Oddmuse 6.
#Perl 6 #Oddmuse 6