Ever since I bought my domain hexf.me
I have always wanted to use it for a blog, to use it as an information outlet, to teach people.
Previously I used solutions such as Hugo and Jekyll with some CI work flow to upload my pages, but while it was a nice use of Git and CI/CD, it wasnt very practical.
When I set out to revamp my website, I had a few goals in mind.
Firstly, I wanted it to not require a database, as that is extra.
Secondly, I wanted it to have an easy place for me to write with technologies I already know, like Markdown.
Finally, I wanted it to be extensible and allow me to use LDAP to authenticate to join my SSO network.
I went looking for quite a while, but eventually fell in love with Grav. Grav provides everything I need, it is a flat-file CMS which allows me to write in Markdown and has a wonderful assortment of plugins like an LDAP authentication plugin. Grav has an admin panel plugin which allows me to write blog posts, and update the page content all from the browser, which is great.
After selecting Grav, I moved onto writing up the role in my ansible playbook.
Grav is a very simple role, basically it downloads all the php extension we require, downloads and installs Grav into /var/www/grav
and finally installs NGINX config and restarts NGINX, simple as that.
---
- name: Install php7.4-fpm and extensions
apt:
state: present
name:
- php7.4-fpm
- unzip
- php7.4-curl
- php7.4-ctype
- php7.4-dom
- php7.4-gd
- php7.4-json
- php7.4-mbstring
- php7.4-simplexml
- php7.4-xml
- php7.4-zip
- php7.4-apcu
- php7.4-opcache
- php7.4-yaml
- php7.4-ldap
when: ansible_facts['os_family']|lower == "debian"
- name: Make dir for Grav
file:
state: directory
path: /var/www/grav/
owner: www-data
group: www-data
mode: 'u=rwX,g=rX,o=rX'
- name: Check if Grav is installed
stat:
path: /var/www/grav/grav-admin/
register: grav_admin
- name: Download & Extract Grav
unarchive:
src: https://getgrav.org/download/core/grav-admin/latest
dest: /var/www/grav/
remote_src: yes
owner: www-data
group: www-data
mode: 'u=rwX,g=rX,o=rX'
when: grav_admin.stat.exists == False
- name: Grav NGINX config
template:
src: server_grav.conf.j2
dest: /etc/nginx/conf/server_grav.conf
owner: root
group: root
mode: '0744'
notify: restart nginx
As Grav depends on NGINX, It would be appropriate to talk about the NGINX role.
The main task for NGINX is very simple, it calls upon 2 other task files, debian.yaml
and nginx_config.yaml
---
- name: Debian Based Systems
import_tasks: debian.yaml
when: ansible_facts['os_family']|lower == "debian"
- name: Configure NGINX
import_tasks: nginx_config.yaml
debian.yaml
is responsible for installing nginx
and fcgiwrap
. We use fcgiwrap for later our git deployment, to install cgit
, more on this later.
---
- name: "Install nginx"
apt:
name: nginx
state: present
- name: "Install fcgiwrap"
apt:
name: fcgiwrap
state: present
The nginx_config.yaml
basically just templates our nginx
config files
---
- name: "Write Main Config"
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0744'
notify: restart nginx
- name: "Create folder for sub-configs"
file:
path: /etc/nginx/conf
state: directory
mode: '0755'
- name: "Base Server Config"
template:
src: _base_server.conf.j2
dest: /etc/nginx/conf/_base_server.conf
owner: root
group: root
mode: '0744'
- name: "Catchall Server Config"
template:
src: server_catchall.conf.j2
dest: /etc/nginx/conf/server_catchall.conf
owner: root
group: root
mode: '0744'
notify: restart nginx
The config templates are just standard NGINX configuration
#nginx.conf.j2
worker_processes 1;
user www-data www-data;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
index index.html index.htm index.php;
error_log syslog:server=unix:/dev/log warn;
access_log syslog:server=unix:/dev/log;
ssl_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;
include conf/server*.conf;
}
#_base_server.conf.j2
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
listen 80;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
server {
server_name _;
server_name_in_redirect off;
root /var/www/default/htdocs;
# include conf/_base_server.conf;
listen 80 default_server;
}
Now, the nginx
role depends on certbot
for LetsEncrypt certificates, but previously I explained that, so I won't go into it here.
The next task is actually setting up Grav.
For this you just web browse to your server and will be greeted with a screen asking you to put in credentials.
Then its just a matter of digging through all the menus in the Configuration
and Themes
tabs to configure your website.
After that, open the pages section and get writing!
In conclusion, Grav is a wonderful PHP based flat-file CMS for building your own website with, blogging and much more.