SystemD and Gollum Wiki

Posted on Tuesday, May 30, 2017









I want to set up my Gollum wiki server to be started/stopped/rebooted via SystemD.   Using SystemD I also want it to restart if it should crash.








@reboot and tmux


My current simple solution is using cron @reboot with a simple tmux script.  All of this is all on an Ubuntu 16.04 server.

Most folks don't know that cron supports the ability to run a command on reboot.

With that in mind I set up a quick, temporary, method to start gollum using cron and tmux until I got around to replacing it with a systemD script.

So here is what I currently have set up.

First the script


  > vi tmux_gollum_commands.sh






#!/bin/bash

#Kill the prior session if exists
tmux kill-session -t gollum-wiki

tmux new -d -s gollum-wiki
tmux send-keys 'cd ~/10x13.wiki' C-m
tmux send-keys 'gollum --config gollum-custom/config/config.rb --emoji --css --template-dir gollum-custom/templates' C-m




This simple script starts up a tmux session, tmux is a tool similar to screen, then just starts gollum in it.

This allows me to attach to the tmux session and see what is going on.



  > tmux attach -t gollum-wiki




Now I can attach to the tmux session and watch the gollum logs pass by.

To get out of this session press crtl+a then d

Now for the cronjob





  > sudo vi /etc/crontab


Here I added a simple @reboot line


@reboot patman /home/patman/tmux_gollum_commands.sh





This @reboot is nice in the since that it will run my script and start up gollum on a reboot.  But it's not so nice in other areas.  It will not recover from a failure.    The script is simple enough and I can rerun it which will kill the current tmux session if it exists and create a new one.   That OK, but I would rather have a systemD script for starting and restarting it.    Also I do not have any logging?

I am going to use systemD to fix all those issues.




Create a Gollum user and move stuff


I want to create a user called gollum who will be used to run the the gollum wiki.

First let me kill my wiki and remove the @reboot from my cronjob


  > tmux kill-session -t gollum-wiki


Then comment out the crontab


  > sudo vi /etc/crontab







Create a Gollum user which will be used to run the gollum wiki.   Also unlock the user


  > sudo useradd gollum -r -m -s /bin/bash
  > sudo password gollum
  > sudo usermod -U gollum


Normally I would set a user like this to not have a shell by using /bin/false.  But I can't do that in this case as I want my git repo to have a hook that will ssh to this machine as gollum and force a pull when the git repo is updated.

My current gollum wiki is set up to auto sync with a remote git repo (back and forth see http://www.whiteboardcoder.com/2017/04/gollum-auto-sync-to-remote-git-repo.html [1] )

So I need to set that up.  First I need to login as the gollum user and create ssh keys.  I can log in as the gollum user if I am already on the machine and set which shell I want to use.




  > sudo su gollum
  > cd






  > ssh-keygen -t rsa -b 4096




Now I need to copy the .ssh/id_rsa.pub information and put add it the ~/.ssh/authorized_keys on my git server


  > cat .ssh/id_rsa.pub



Also because of the way I have it set up my git repo needs to have ssh access back to my gollum server (since it updates the gollum wiki when it is pushed to)

From the git server


  > cat .ssh/id_rsa.pub


Then add that to the ~/.ssh/authorized_keys on the gollum server




Confirm that is working…
(from gollum to git server)


  > ssh git@git-server




Now from git to Gollum server



  > ssh gollum@192.168.0.77




Perfect that is all working





Move repo and update hooks


Now I need to move stuff around and update hooks I made earlier

First I am going to clone my wiki repo as a the gollum user  (this is not my actual IP address)


  > git clone git@127.0.0.1:/gitstuff/10x13.wiki


Now let me tweak it


  > cd 10x13.wiki


Set a few configs


  > git config push.default simple
  > git config user.name "Gollum Wiki"
  > git config user.email gollum@10x13.com


Now I need to reset my hooks on the gollum server and on my git server.



From the gollum server create the .git/hooks/post-commit  (remember hooks are not part of a git repo itself)


  > vi .git/hooks/post-commit


Place the following in it.


#!/bin/bash

#Simple push to origin master
git push origin master




Make it executable


  > chmod a+x .git/hooks/post-commit




Now to the git server.  I need to update the hook there.  (this is a hook I made in another post http://www.whiteboardcoder.com/2017/04/gollum-auto-sync-to-remote-git-repo.html [1] )


  > vi hooks/post-receive


I just needed to update the user

#!/bin/bash

#Set user to login to gollum server as
USER="gollum"
GOLLUM_ADDR="192.168.0.77"
GOLLUM_DIR="~/10x13.wiki"

#First check to see if the Commited SHA on the GOLLUM server and here are a match
LOCAL_SHA=$(git rev-parse --verify HEAD)
GOLLUM_SHA=$(ssh $USER@$GOLLUM_ADDR "cd $GOLLUM_DIR; git rev-parse --verify HEAD")

#If they do not match then GOLLUM server needs to do a pull
if [ $LOCAL_SHA != $GOLLUM_SHA ]; then
  ssh $USER@$GOLLUM_ADDR "cd $GOLLUM_DIR; git pull origin master"
fi






Before I head on I am going to run a few local test to make sure the hooks are working correctly.  Like running gollum by hand and making sure the hook is pushing up.

Make a simple change on the gollum server add it to git and commit it. (Should auto push it)


  > git add --all
  > git commit -m "simple change"






Then check it by running


  > git log -n 1


On gollum and git server







Cool I have a match!


Now test it the other wau

Cloning the repo to my local machine


  > git clone git@127.0.0.1:/gitstuff/10x13.wiki


Now let me tweak it


  > cd 10x13.wiki


Make a simple change and add it, commit it and push it up


  > git add --all
  > git commit -m "Git repo to gollum test"
  > git push





Then check it by running


  > git log -n 1


On gollum and git server







Wahoo worked



SystemD script


Now create a systemd script


  > sudo vi /lib/systemd/system/gollum.service


And place the following in it.


[Unit]
Description=Gollum Server
Requires=network.target
After=network.target
ConditionPathExists=/home/gollum/10x13.wiki

[Service]
Type=simple
PIDFile=/var/run/gollum.pid
User=gollum
Group=gollum
WorkingDirectory=/home/gollum/10x13.wiki
ExecStart=/usr/local/bin/gollum

[Install]
WantedBy=multi-user.target
Alias=gollum.service




Make it executable, enable it, and start it.


  > sudo chmod a+x /lib/systemd/system/gollum.service
  > sudo systemctl enable gollum.service
  > sudo systemctl start gollum



 



Wahoo working

But I am not getting my custom settings yet.




Custom start up script


In the wiki make a simple start up script


  > mkdir bin
  > vi bin/gollum.sh


And put the following in it.


#!/bin/bash

CONFIG="gollum-custom/config/config.rb"
TEMPLATE_DIR="gollum-custom/templates"

gollum --config $CONFIG --emoji --css --template-dir $TEMPLATE_DIR


Then make it executable


  > chmod u+x bin/gollum.sh




Now update the systemd service


  > sudo vi /lib/systemd/system/gollum.service


And place the following in it.


[Unit]
Description=Gollum Server
Requires=network.target
After=network.target
ConditionPathExists=/home/gollum/10x13.wiki

[Service]
Type=simple
PIDFile=/var/run/gollum.pid
User=gollum
Group=gollum
WorkingDirectory=/home/gollum/10x13.wiki
ExecStart=/home/gollum/10x13.wiki/bin/gollum.sh

[Install]
WantedBy=multi-user.target
Alias=gollum.service


Just update the ExecStart


Since the service has been updated it needs to be reloaded


  > sudo systemctl daemon-reload


Now restart


  > sudo systemctl restart gollum.service





Working !





SystemD Recovery


What about recovery?  If Gollum crashes I want it to Autorestart

Let me kill the process (simulate a crash)


  > sudo ps -Af | grep gollum | grep emoji






  > sudo kill 2604





How do I fix this?




  > sudo vi /lib/systemd/system/gollum.service


And place the following in it.


[Unit]
Description=Gollum Server
Requires=network.target
After=network.target
ConditionPathExists=/home/gollum/10x13.wiki

[Service]
Type=simple
PIDFile=/var/run/gollum.pid
User=gollum
Group=gollum
WorkingDirectory=/home/gollum/10x13.wiki
ExecStart=/home/gollum/10x13.wiki/bin/gollum.sh
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
Alias=gollum.service



Reload


  > sudo systemctl daemon-reload


Now restart


  > sudo systemctl restart gollum.service


Now if I simulate a crash


  > sudo ps -Af | grep gollum | grep emoji






  > sudo kill 2750






  > sudo ps -Af | grep gollum | grep emoji





After three seconds it restart J






Logging and logrotate


The last thing I want to take care of is logging.

Out of the box it looks like its logging to /var/log/syslog


  > tail -f /var/log/syslog


Also if I uses systemctl status I see all the logs


  > sudo systemctl status gollum.service






Hmmm.

I think the simple answer is to edit the gollum.sh script I made to output to a log.

I need to add gollum user to the syslog group


  > sudo usermod -a -G syslog gollum


Edit the script


  > vi bin/gollum.sh




#!/bin/bash

CONFIG="gollum-custom/config/config.rb"
TEMPLATE_DIR="gollum-custom/templates"
LOG="/var/log/gollum.log"

gollum --config $CONFIG --emoji --css --template-dir $TEMPLATE_DIR >> $LOG 2>&1


Now restart


  > sudo systemctl restart gollum.service

Now I can tail the log



  > tail -f /var/log/gollum.log




Also systemctl should look cleaner now



  > sudo systemctl status gollum.service




Much Better.




Logrotate


To be safe I am going to add a logrotate to rotate this file daily and to keep 30 days worth of files.



  > sudo vi /etc/logrotate.d/gollum

And put the following in it.



/var/log/gollum.log {
        daily
        dateext
        dateformat _%Y-%m-%d
        missingok
        create 640 gollum gollum
        rotate 90
        compress
        notifempty
}


Test it


  > sudo logrotate -d /etc/logrotate.conf






Looks good.


Another test


  > sudo logrotate -vf /etc/logrotate.d/gollum

 



Oh little error need to specify user/group




  > sudo vi /etc/logrotate.d/gollum

And put the following in it.



/var/log/gollum.log {
        su gollum gollum
        daily
        dateext
        dateformat _%Y-%m-%d
        missingok
        create 640 gollum gollum
        rotate 90
        compress
        notifempty
}




Test again


  > sudo logrotate -vf /etc/logrotate.d/gollum

 


Still failed

Oh need gollum syslog




  > sudo vi /etc/logrotate.d/gollum

And put the following in it.



/var/log/gollum.log {
        su gollum syslog
        daily
        dateext
        dateformat _%Y-%m-%d
        missingok
        create 640 gollum gollum
        rotate 90
        compress
        notifempty
}




Test again


  > sudo logrotate -vf /etc/logrotate.d/gollum




But now I am no longer logging to the file.  I think I need to add a thing to the logrotate to restart the gollum (not ideal but it will do)




  > sudo vi /etc/logrotate.d/gollum

And put the following in it.



/var/log/gollum.log {
        su gollum syslog
        daily
        dateext
        dateformat _%Y-%m-%d
        missingok
        create 640 gollum syslog
        rotate 90
        compress
        notifempty
        postrotate
           /bin/systemctl restart gollum.service
        endscript
}




Test again


  > sudo logrotate -vf /etc/logrotate.d/gollum

 


OK I think that got it.

Let me remove all the gollum logs and reboot the box.




  > sudo rm /var/log/gollum.log*
  > sudo reboot now






Looks good!

OK I think I got it.


References


[1]        Gollum auto sync to remote git repo

No comments:

Post a Comment