Official Project Page: Cachet
Contents |
---|
Installing On Ubuntu 20 |
Page Design |
API Examples |
API NodeRED |
Timezone |
References |
I don't see many people complaining about the installation instructions, so maybe it's just me, but I tried multiple times with the official instructions, and with guides on various blog posts, and then tried the Docker version. Basically nothing worked as expected. However, the guide on https://websiteforstudents.com/install-cachet-status-platform-on-ubuntu-16-04-18-04-with-apache2-mariadb-and-php-7-2/ does appear to work ok, and I've summarised my steps below.
Started with a clean Ubuntu 20 LTS install. I created a single sudo user and ran the usual updates. Took a snapshot here, in case I needed to revert the setup, again!
There's a useful guide here: https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-ubuntu-20-04 and do remember to enable the services (Apache and MariaDB) as you presumably want them to auto start after a reboot.
sudo apt update
sudo apt install apache2
curl localhost
^- the default Apache page should be served
They are probably already installed, but just in case:
sudo apt install curl git
sudo apt-get install mariadb-server mariadb-client
sudo mysql_secure_installation
Secure the database as you wish.
sudo mysql -u root -p
exit;
^- confirm you can login
There is a variety of conflicting advice around PHP versions. I tried 7.2, as per this guide, and it appears to work ok.
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php7.2 libapache2-mod-php7.2 php7.2-common php7.2-mysql php7.2-gmp php7.2-curl php7.2-intl php7.2-mbstring php7.2-xmlrpc php7.2-gd php7.2-bcmath php7.2-imap php7.2-xml php7.2-cli php7.2-zip
Made the following suggested edits sudo nano /etc/php/7.2/apache2/php.ini
.
file_uploads = On
allow_url_fopen = On
short_open_tag = On
memory_limit = 256M
upload_max_filesize = 100M
max_execution_time = 360
date.timezone = Europe/London
Restart Apache and (if you want to) confirm that PHP is ok.
sudo systemctl restart apache2
sudo nano /var/www/html/phpinfo.php
Add <?php phpinfo( ); ?>
to the top of the file and curl localhost/phpinfo.php
. It should be served as html.
sudo mysql -u root -p
CREATE DATABASE cachetdb;
CREATE USER 'cachetdbuser'@'localhost' IDENTIFIED BY '****';
GRANT ALL ON cachetdb.* TO 'cachetdbuser'@'localhost' IDENTIFIED BY '****' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
cd /var/www/html
sudo git clone -b 2.4 --single-branch https://github.com/cachethq/Cachet.git cachet
sudo cp /var/www/html/cachet/.env.example /var/www/html/cachet/.env
^- I'd normally install higher than the default html folder, but after all the preceeding hassle I was following their guide exactly...
Edit the env file, sudo nano /var/www/html/cachet/.env
.
DB_HOST=localhost
DB_DATABASE=cachetdb
DB_USERNAME=cachetdbuser
DB_PASSWORD=****
I believe it's bad practice to run Composer with sudo, there may be a warning? I accepted it with a 'Y'.
cd /var/www/html/cachet
sudo composer install --no-dev -o
Answer "no" to the two prompts on the Cachet install.
sudo php artisan key:generate
sudo php artisan cachet:install
^- if you want to check, the key should now be written into the .env
file.
Reset ownerships and permissions.
sudo chown -R www-data:www-data /var/www/html/cachet/
sudo chmod -R 755 /var/www/html/cachet/
^- Surely this is far too generous?! These were recommended by the install guide, but in production I'd question this owenership, and I think only the cache
and storage
folders need to be writable. Possibly also database
, if you're using sqlite.
Create a conf file.
sudo nano /etc/apache2/sites-available/cachet.conf
Their suggestion:
<VirtualHost *:80>
ServerAdmin cachet@example.com
DocumentRoot /var/www/html/cachet/public
ServerName cachet.example.com
ServerAlias cachet.example.com
<Directory /var/www/html/cachet/public>
Options FollowSymlinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/html/cachet/public>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php [PT,L]
</Directory>
</VirtualHost>
Enable the site.
sudo a2ensite cachet.conf
sudo a2enmod rewrite
sudo systemctl restart apache2
And secure the site.
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --apache
You should now be able to complete the setup in your browser.
Cache Driver - database
Queue Driver - none
Session Driver - database
^- the following driver selection works, but may not be optimal?
The file /var/www/cachet/resources/views/index.blade.php
contains the Laravel blade template for the main page layout. For example, if you need the page sections to appear in a different order.
@extends('layout.master')
@section('content')
@include('partials.modules.messages')
@include('partials.modules.status')
@include('partials.about-app')
@include('partials.modules.components')
@include('partials.modules.metrics')
@include('partials.modules.stickied')
@include('partials.modules.scheduled')
@include('partials.modules.timeline')
@stop
@section('bottom-content')
@include('partials.footer')
@stop
^- eg/ if you wanted the "about" panel to display above the "status" message, etc.
Highlight the "Maintenance" section:
.section-scheduled {
border: 1px solid #3929a8;
border-radius: 4px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
Update status of a component:
curl -X PUT -H "Content-Type: application/json" -H "X-Cachet-Token: API-KEY-HERE" -d '{"status":1}' "https://cachet.example.com/api/v1/components/1"
^- in this example, set component 1 to status of 'operational'
/api/v1/components
list all components/api/v1/components/1
query specific component/api/v1/components/groups
list all component groups/api/v1/components/groups/1
components in specified group
"id": 1,
"name": "Component Name",
"description": "Description goes here",
"link": "",
"status": 1,
"order": 0,
"group_id": 1,
"enabled": true,
"meta": null,
"created_at": "2021-07-29 18:51:27",
"updated_at": "2021-08-03 12:19:47",
"deleted_at": null,
"status_name": "Operational",
"tags": []
"id": 1,
"name": "Group Name",
"order": 0,
"visible": 1,
"collapsed": 0,
"created_at": "2021-07-29 18:58:49",
"updated_at": "2021-07-30 15:57:42",
"enabled_components": [],
"lowest_human_status": "Operational"
/api/v1/incidents
list all incidents/api/v1/incidents/1
query specific incident/api/v1/incidents/1/updates
list updates on specified incident/api/v1/incidents/1/updates/1
query specific update on specified incident
/api/v1/metrics
list all metrics/api/v1/metrics/1
query a specific metric
If you make a POST request to
https://cachet.example.com/api/v1/metrics/1/points
supplying the API key and the data{"value":75}
(for example) you're able to successfully log the data-point, but there appears to be an issue with UTC vs BST.
- (Don't know if this can be queried via their API?)
/api/v1/version
replies with version number/api/v1/ping
replies with "pong"api/v1/subscribers
(requires authentication)
Testing a simple flow, with four nodes.
- Inject
- Function
- HTTP Request
- Debug
The function can be used to set the URL, the two required headers, and the data object should be written to msg.payload.
msg.url = "https://cachet.example.com/api/v1/components/1";
msg.payload = {};
msg.payload = {"status":1};
msg.headers = {};
msg.headers['Content-Type'] = 'application/json';
msg.headers['X-Cachet-Token'] = 'API-KEY-HERE';
return msg;
Set the HTTP Request node to PUT
and to return a Parsed JSON Object
. In this example, the status
of component 1 becomes set to operational
.
Some notes on diagnosing Cachet timezone graph display issue.
Regardless of timezone, the graph insists on displaying in UTC, rather than BST. If you change your timezone to Australia, the display of the graph shifts forward half a day, as you'd expect, but events are always shown as UTC. (Surely most 'end-users' want to see something more meaningful?)
Use timezonectl
or check /etc/timezone
.
timedatectl
Local time: Tue 2021-08-10 10:12:34 UTC
Universal time: Tue 2021-08-10 10:12:34 UTC
RTC time: Tue 2021-08-10 10:12:35
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
List available timezones with timedatectl list-timezones
. In this case, I should be in the Europe/London
timezone.
sudo timedatectl set-timezone Europe/London
With this change alone, data-points still being logged 1 hour out; UTC, not BST.
Looking at MariaDB.
sudo mysql -u root -p
Select now();
^- responds with UTC time
MariaDB [(none)]> show global variables like 'time_zone';
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| time_zone | SYSTEM |
+---------------+--------+
1 row in set (0.004 sec)
Set to SYSTEM
so maybe just needs a restart?
sudo systemctl restart mariadb
sudo mysql -u root -p
Select now();
^- responds with BST
This represents an improvement. Now (for example) the URL https://cachet.example.com/api/v1/metrics/2/points
reponds with data-points that have the correct timestamps. But, on the Cachet dashboard page, the graph still draws the points as if it were using UTC time.
In the .env
the value APP_TIMEZONE
is set to UTC
. ALtering this to Europe/London
seemed logical, but appears to prevent any new data-points from being logged. Setting it to BST
allows data to be logged again, but the graph still displays them as UTC
. Same with Etc/GMT+1
.
APP_TIMEZONE=UTC
The customisation settings within the Cachet dashboard are showing "London" with the correct (BST) time being shown, but this setting doesn't affect the display of the points on the graph.
- Issues including
metrics UTC
-> https://github.com/CachetHQ/Cachet/issues?q=is%3Aissue+metrics+UTC - Issues including
timezone
-> https://github.com/CachetHQ/Cachet/issues?q=is%3Aissue+timezone
I can't see any clean solution to this for now. There's a certain logic to UTC time and maybe it's "by design", but personally I think it feels like a bit of an oversight?
^- it would appear that no data was received after 8am?
{"id":45,"metric_id":2,"value":41,"counter":1,"created_at":"2021-08-13 08:33:30","updated_at":"2021-08-13 08:33:21","calculated_value":41}
^- but the latest datapoint was sent at 8:33am
In summary, the points are correct. The last few values I sent (I'm POST'ing a random %'age value every hour) are 41, 82, 93, 29... you can see them correctly on the graph, but everything is offset by an hour.
- https://oipwg.github.io/cachetapi/CachetAPI.html (node.js API reference)
- https://github.com/CachetHQ/Cachet/blob/2.4/docs/api/api-documentation.md (official docs, incomplete)