aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/docs/adyxax.org/miniflux/_index.md14
-rw-r--r--content/docs/adyxax.org/miniflux/install.md274
2 files changed, 288 insertions, 0 deletions
diff --git a/content/docs/adyxax.org/miniflux/_index.md b/content/docs/adyxax.org/miniflux/_index.md
new file mode 100644
index 0000000..aeea409
--- /dev/null
+++ b/content/docs/adyxax.org/miniflux/_index.md
@@ -0,0 +1,14 @@
+---
+title: "miniflux"
+description: miniflux.adyxax.org rss feed reader
+---
+
+## Introduction
+
+miniflux.adyxax.org is a [miniflux](https://miniflux.app/) instance that I have been using for about 5 years. It is a rss feed reader and aggregator written as a golang web application. It is a reliable piece of software and I never encountered any issue with it.
+
+## Captain's log
+
+- 2021-10-05 : migrated this instance to myth.adyxax.org
+
+## Docs
diff --git a/content/docs/adyxax.org/miniflux/install.md b/content/docs/adyxax.org/miniflux/install.md
new file mode 100644
index 0000000..1863c8c
--- /dev/null
+++ b/content/docs/adyxax.org/miniflux/install.md
@@ -0,0 +1,274 @@
+---
+title: "Installation"
+description: Installation notes of miniflux.adyxax.org on k3s
+tags:
+- k3s
+- kubernetes
+- miniflux
+- postgresql
+---
+
+## Introduction
+
+Please refer to [the official website](https://miniflux.app/) documentation's for an up to date installation guide. This page only lists what I had to do at the time to setup miniflux and adapt it to my particular setup. I updated these instructions after migrating from a traditional hosting to kubernetes.
+
+## Preparing the postgresql database
+
+I have a postgresql running in its own namespace from bitnami images. To provision the miniflux database I :
+```sh
+export POSTGRES_PASSWORD=$(k get secret -n postgresql postgresql-secrets -o jsonpath="{.data.postgresql-password}"|
+ base64 --decode)
+k run client --rm -ti -n postgresql --image docker.io/bitnami/postgresql:13.4.0-debian-10-r52 \
+ --env="PGPASSWORD=$POSTGRES_PASSWORD" --command -- psql --host postgresql -U postgres
+CREATE ROLE miniflux WITH LOGIN PASSWORD 'secret';
+CREATE DATABASE miniflux WITH OWNER miniflux TEMPLATE template0 ENCODING UTF8 LC_COLLATE
+ 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';
+\c miniflux
+create extension hstore;
+```
+
+Optionally import a dump of the database by running in another shell :
+```sh
+k -n postgresql cp miniflux.sql-20211005 client:/tmp/
+```
+
+Then in the psql shell :
+```sh
+\c miniflux
+\i /tmp/miniflux.sql-20211005
+```
+
+## Kubernetes manifests in terraform
+
+This app is part of an experiment of mine to migrate stuff from traditional hosting to kubernetes. I first wrote manifests by hand then imported them with terraform. I do not like it annd find it too complex/overkill but that is managed this way for now.
+
+### DNS CNAME
+
+Since all configuration regarding this application is in terraform, so is the dns :
+```hcl
+resource "cloudflare_record" "miniflux-cname" {
+ zone_id = lookup(data.cloudflare_zones.adyxax-org.zones[0], "id")
+ name = "miniflux"
+ value = "myth.adyxax.org"
+ type = "CNAME"
+ proxied = false
+}
+```
+
+### Namespace
+
+The basic terraform object works for simple things so here it is :
+```hcl
+resource "kubernetes_namespace" "myth-miniflux" {
+ provider = kubernetes.myth
+ metadata {
+ name = "miniflux"
+ }
+}
+```
+
+### Secret
+
+Here is the kubernetes secret that tells miniflux how to connect the database. The password comes from `terraform.tfvars`, you might need to update the service url with the format `<svc>.<namespace>.svc.cluster.local` :
+```hcl
+resource "kubernetes_secret" "myth-miniflux-secrets" {
+ provider = kubernetes.myth
+ metadata {
+ name = "miniflux-secrets"
+ namespace = kubernetes_namespace.myth-miniflux.id
+ }
+ data = {
+ ADMIN_PASSWORD = var.miniflux-admin-password
+ DATABASE_URL = join("", [ "postgres://miniflux:${var.miniflux-postgres-password}",
+ "@postgresql.postgresql.svc.cluster.local/miniflux?sslmode=disable"])
+ }
+ type = "Opaque"
+}
+```
+
+### Deployment
+
+I could not write the deployment with the `kubernetes_deployment` terraform ressource, so it is a row manifest which imports a yaml syntax in hcl. It is horrible to look at but works. Change the image tag to the latest stable version of miniflux before deploying :
+```hcl
+resource "kubernetes_manifest" "myth-deployment-miniflux" {
+ provider = kubernetes.myth
+ manifest = {
+ "apiVersion" = "apps/v1"
+ "kind" = "Deployment"
+ "metadata" = {
+ "name" = "miniflux"
+ "namespace" = kubernetes_namespace.myth-miniflux.id
+ }
+ "spec" = {
+ "replicas" = 1
+ "selector" = {
+ "matchLabels" = {
+ "app" = "miniflux"
+ }
+ }
+ "strategy" = {
+ "type" = "RollingUpdate"
+ "rollingUpdate" = {
+ "maxSurge" = 1
+ "maxUnavailable" = 0
+ }
+ }
+ "template" = {
+ "metadata" = {
+ "labels" = {
+ "app" = "miniflux"
+ }
+ }
+ "spec" = {
+ "containers" = [
+ {
+ "env" = [
+ {
+ "name" = "DATABASE_URL"
+ "valueFrom" = {
+ "secretKeyRef" = {
+ "key" = "DATABASE_URL"
+ "name" = "miniflux-secrets"
+ }
+ }
+ },
+ {
+ "name" = "RUN_MIGRATIONS"
+ "value" = "1"
+ },
+ {
+ "name" = "ADMIN_USERNAME"
+ "value" = "admin"
+ },
+ {
+ "name" = "ADMIN_PASSWORD"
+ "valueFrom" = {
+ "secretKeyRef" = {
+ "key" = "ADMIN_PASSWORD"
+ "name" = "miniflux-secrets"
+ }
+ }
+ },
+ ]
+ "image" = "miniflux/miniflux:2.0.33"
+ "livenessProbe" = {
+ "httpGet" = {
+ "path" = "/"
+ "port" = 8080
+ }
+ "initialDelaySeconds" = 5
+ "timeoutSeconds" = 5
+ }
+ "name" = "miniflux"
+ "ports" = [
+ {
+ "containerPort" = 8080
+ },
+ ]
+ "readinessProbe" = {
+ "httpGet" = {
+ "path" = "/"
+ "port" = 8080
+ }
+ "initialDelaySeconds" = 5
+ "timeoutSeconds" = 5
+ }
+ "lifecycle" = {
+ "preStop" = {
+ "exec" = {
+ "command" = ["/bin/sh", "-c", "sleep 10"]
+ }
+ }
+ }
+ },
+ ]
+ "terminationGracePeriodSeconds" = 1
+ }
+ }
+ }
+ }
+}
+```
+
+### Service
+
+```hcl
+resource "kubernetes_manifest" "myth-service-miniflux" {
+ provider = kubernetes.myth
+ manifest = {
+ "apiVersion" = "v1"
+ "kind" = "Service"
+ "metadata" = {
+ "name" = "miniflux"
+ "namespace" = kubernetes_namespace.myth-miniflux.id
+ }
+ "spec" = {
+ "ports" = [
+ {
+ "port" = 80
+ "protocol" = "TCP"
+ "targetPort" = 8080
+ },
+ ]
+ "selector" = {
+ "app" = "miniflux"
+ }
+ "type" = "ClusterIP"
+ }
+ }
+}
+```
+
+### Ingress
+
+```hcl
+resource "kubernetes_manifest" "myth-ingress-miniflux" {
+ provider = kubernetes.myth
+ manifest = {
+ "apiVersion" = "networking.k8s.io/v1"
+ "kind" = "Ingress"
+ "metadata" = {
+ "name" = "miniflux"
+ "namespace" = kubernetes_namespace.myth-miniflux.id
+ }
+ "spec" = {
+ "ingressClassName" = "nginx"
+ "rules" = [
+ {
+ "host" = "miniflux.adyxax.org"
+ "http" = {
+ "paths" = [
+ {
+ "path" = "/"
+ "pathType" = "Prefix"
+ "backend" = {
+ "service" = {
+ "name" = "miniflux"
+ "port" = {
+ "number" = 80
+ }
+ }
+ }
+ },
+ ]
+ }
+ },
+ ]
+ "tls" = [
+ {
+ "secretName" = "wildcard-adyxax-org"
+ },
+ ]
+ }
+ }
+}
+```
+
+### Certificate
+
+For now I do not manage my certificates with terraform but manually. Once every three months I run :
+```sh
+acme.sh --config-home "$HOME/.acme.sh" --server letsencrypt --dns dns_cf --issue -d adyxax.org -d *.adyxax.org --force
+kubectl -n miniflux create secret tls wildcard-adyxax-org --cert=$HOME/.acme.sh/adyxax.org/fullchain.cer \
+ --key=$HOME/.acme.sh/adyxax.org/adyxax.org.key -o yaml --save-config --dry-run=client | kubectl apply -f -
+```