Setting up Firefly3#

*Firefly III is a self-hosted personal finance manager.

It helps you track expenses, income, budgets, and accounts, giving you detailed insight into your spending while keeping all financial data under your control.*

I wanted to show a few services, but for the most part after K3s is up and online the services are self explanitory through code. Each service is likely to vary in its own way, but I wanted to present a few.

hostPath v Local#

One of the biggest differences between this service and the others is the use of hostPath within the PersistentVolume.

Below is one of the better explanations I have seen with a table explaining the differences:

hostPath is a simple, node-specific mount that bypasses scheduler awareness, so Kubernetes does not enforce where Pods land relative to the data. In contrast, a local PersistentVolume is modeled as a node-bound resource, requiring node affinity so the scheduler can place Pods on the correct node. This makes local suitable for multi-node clusters, while hostPath is primarily a single-node or development convenience.

AspecthostPathlocal PersistentVolume
Scheduler awarenessNoYes
Node affinity requiredNoYes
Multi-node safetyNoYes (with constraints)
Typical usageDev / single-node / debuggingProduction local storage
Data locality handlingManualEnforced by scheduler

Based on the above information I will likely swap the other PersistentVolumes to this configuration as this setup will only be running on one host.

To Note and To Fix#

One of the things I want to fix is environment settings for the domain name. I need to be able to pass in the variables for the domain.

This will be something to fix in the near future.

#
# NAMESPACE
#
apiVersion: v1
kind: Namespace
metadata:
  name: firefly
---
#
# VOLUMES
#
apiVersion: v1
kind: PersistentVolume
metadata:
  name: firefly-upload-pv
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /var/lib/firefly-iii/upload
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: firefly-db-pv
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /var/lib/firefly-iii/db
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: firefly-upload-pvc
  namespace: firefly
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: firefly-db-pvc
  namespace: firefly
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
#
# MARIADB
#
---
apiVersion: v1
kind: Service
metadata:
  name: firefly-db
  namespace: firefly
spec:
  clusterIP: None
  selector:
    app: firefly-db
  ports:
    - port: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: firefly-db
  namespace: firefly
spec:
  replicas: 1
  selector:
    matchLabels:
      app: firefly-db
  template:
    metadata:
      labels:
        app: firefly-db
    spec:
      containers:
        - name: mariadb
          image: mariadb:lts
          env:
            - name: MYSQL_RANDOM_ROOT_PASSWORD
              value: "yes"
            - name: MYSQL_USER
              value: "firefly"
            - name: MYSQL_PASSWORD
              value: "secret_firefly_password"
            - name: MYSQL_DATABASE
              value: "firefly"
          ports:
            - containerPort: 3306
          volumeMounts:
            - name: db-data
              mountPath: /var/lib/mysql
      volumes:
        - name: db-data
          persistentVolumeClaim:
            claimName: firefly-db-pvc
#
# FIREFLY III
#
---
apiVersion: v1
kind: Service
metadata:
  name: firefly
  namespace: firefly
spec:
  type: ClusterIP
  selector:
    app: firefly
  ports:
    - port: 8080
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: firefly
  namespace: firefly
spec:
  replicas: 1
  selector:
    matchLabels:
      app: firefly
  template:
    metadata:
      labels:
        app: firefly
    spec:
      containers:
        - name: firefly
          image: fireflyiii/core:latest
          env:
            - name: DB_DATABASE
              value: "firefly"
            - name: DB_USERNAME
              value: "firefly"
            - name: DB_PASSWORD
              value: "secret_firefly_password"
            - name: DB_HOST
              value: "firefly-db"
            - name: APP_KEY
              value: "app_key_here_pretty_sure_this_has_to_be_32"
            - name: APP_URL
              value: "https://test-f3.jmoore53.dev:10443"
            - name: TRUSTED_PROXIES
              value: "**"
            - name: COOKIE_SECURE
              value: "true"
          ports:
            - containerPort: 8080
          volumeMounts:
            - name: upload
              mountPath: /var/www/html/storage/upload
      volumes:
        - name: upload
          persistentVolumeClaim:
            claimName: firefly-upload-pvc
#
# CRON
#
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: firefly-cron
  namespace: firefly
spec:
  schedule: "0 3 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: cron
              image: alpine
              command:
                - sh
                - -c
                - |
                  apk add --no-cache tzdata wget &&
                  ln -sf /usr/share/zoneinfo/$TZ /etc/localtime &&
                  wget -qO- http://firefly:8080/api/v1/cron/v62pmPVSqUd26YceR87xHjYJMklyHdEX


#
# MIDDLEWARE
#
#apiVersion: traefik.io/v1alpha1
#kind: Middleware
#metadata:
#  name: https-redirect
#  namespace: firefly
#spec:
#  redirectScheme:
#    scheme: https
#    permanent: true

#
# INGRESS
#
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: firefly
  namespace: firefly
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls:
      "true"
      #    traefik.ingress.kubernetes.io/router.middlewares: firefly-https-redirect@kubernetescrd
spec:
  tls:
    - hosts:
        - test-f3.jmoore53.dev
      secretName: boot-unlock-tls
  rules:
    - host: test-f3.jmoore53.dev
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: firefly
                port:
                  number: 8080