I ran Oddmuse 6 for a while now from a little shell script. It set up the environment variables, it checked whether the process was already running, it used nohup
to run perl6 service.p6
, it saved the PID in a file, and so on. But it didn’t use cro run
. And I still don’t know how to do it.
I would like to use cro run
because I feel that’s what I need to do in the future when I run multiple sites in parallel. So let’s try this:
#!/bin/bash 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 cro run
This script doesn’t work. All I see is this:
▶ Starting oddmuse6 (oddmuse6) 🔌 Endpoint HTTP will be at http://localhost:20000/ ♻ Restarting oddmuse6 (oddmuse6) ♻ Restarting oddmuse6 (oddmuse6) ♻ Restarting oddmuse6 (oddmuse6) ♻ Restarting oddmuse6 (oddmuse6) ♻ Restarting oddmuse6 (oddmuse6)
If I replace cro run
with perl6 service.p6
, it works.
So now I’m back to this:
#!/bin/bash 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 test -f pid && kill $(cat pid) perl6 service.p6 & echo $! > pid
Any ideas?
The service.p6
file is simple:
use Cro::HTTP::Log::File; use Cro::HTTP::Server; use Oddmuse::Routes; my $logs = open 'access.log'.IO, :w; my $errors = open 'error.log'.IO, :w; 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 => $logs, errors => $errors)] ); $http.start; $logs.say: "Listening at http://%*ENV<ODDMUSE_HOST>:%*ENV<ODDMUSE_PORT>"; react { whenever signal(SIGINT) { $logs.say: "Shutting down..."; $http.stop; done; } whenever signal(SIGHUP) { $logs.say: "Ignoring SIGHUP..."; } }
Oddmuse::Routes
is available from the Oddmuse 6 repo.
Hm, what could be the problem? Let’s look at the files:
total 80 drwxr-xr-x 6 alex alex 4096 Oct 21 11:40 . drwxr-xr-x 57 alex alex 4096 Oct 21 11:57 .. -rw-r--r-- 1 alex alex 205 Oct 7 18:42 .cro.yml~ -rw-r--r-- 1 alex alex 479 Oct 7 19:23 .cro.yml -rw-r--r-- 1 alex alex 10 Oct 7 18:42 .dockerignore -rw-r--r-- 1 alex alex 52 Oct 7 18:42 .gitignore -rw-r--r-- 1 alex alex 221 Oct 7 18:42 Dockerfile -rw-r--r-- 1 alex alex 471 Oct 7 18:42 META6.json -rw-r--r-- 1 alex alex 473 Oct 7 18:42 README.md -rw-r--r-- 1 alex alex 43 Oct 21 11:49 access.log drwxr-xr-x 2 alex alex 4096 Oct 17 10:59 css -rw-r--r-- 1 alex alex 0 Oct 21 11:49 error.log drwxr-xr-x 3 alex alex 4096 Oct 7 19:24 lib -rw------- 1 alex alex 445 Oct 21 11:46 nohup.out -rw-r--r-- 1 alex alex 6 Oct 21 11:49 pid -rwxr-xr-x 1 alex alex 149 Oct 15 10:43 run.sh~ -rwxr-xr-x 1 alex alex 318 Oct 15 10:46 run.sh -rw-r--r-- 1 alex alex 683 Oct 21 11:19 service.p6~ -rw-r--r-- 1 alex alex 779 Oct 21 11:49 service.p6 drwxr-xr-x 2 alex alex 4096 Oct 10 20:40 templates drwxr-xr-x 4 alex alex 4096 Oct 11 08:32 wiki
error.log
and access.log
are the obvious culprits! Changes in the log file will case cro
to restart. So what I’m going to do is move the log files intoa logs
subdirectory and add that to the ignore
section in .cro.yml
.
OK, so that works. I still feel strange using nohup
, though.
Shell script:
#!/bin/bash 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 # test -f pid && kill $(cat pid) # perl6 service.p6 & # echo $! > pid nohup cro run &
Service:
use Cro::HTTP::Log::File; use Cro::HTTP::Server; use Oddmuse::Routes; my $logs = open 'logs/access.log'.IO, :w; my $errors = open 'logs/error.log'.IO, :w; 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 => $logs, errors => $errors)] ); $http.start; $logs.say: "Listening at http://%*ENV<ODDMUSE_HOST>:%*ENV<ODDMUSE_PORT>"; react { whenever signal(SIGINT) { $logs.say: "Shutting down..."; $http.stop; done; } whenever signal(SIGHUP) { $logs.say: "Ignoring SIGHUP..."; } }
Me ignoring SIGHUP
in the service now has no effect because cro
doesn’t ignore SIGHUP
which is why the nohup
wrapper is needed.
OK, so now my shell script starts nohup cro run &
because cro
doesn’t daemonize itself. I guess I still find that surprising. And I wonder about the trade-offs. So the benefit is automatic restarts? I also see now that using cro
run gives me two moar
processes (one runs cro
, the other runs my process, moar
being the virtual machine this Perl 6 runs on).
If there’s nothing else that I’m missing, perhaps running the service using perl6 directly instead of via cro
isn’t such a bad idea after all. I think I’ll do that.