MariaDB database server
You can use MariaDB instead of MySQL as database server for Ghost
Ghost indicates in its official documentation to use MySQL, but MariaDB is a perfectly compatible and open source alternative you can use as Ghost’s database.
MariaDB Kustomize subproject’s folders
Since the MariaDB database is just another component of your Ghost platform, you have to put its corresponding folders within the ghost/components path you already created in the previous chapter about the Valkey cache server.
$ mkdir -p $HOME/k8sprjs/ghost/components/db-mariadb/{configs,resources,secrets}Like the Valkey server, MariaDB also has configurations, secrets and resources in its Kustomize setup.
MariaDB configuration files
The MariaDB deployment requires a number of adjustments that are better handled in different configuration files.
Configuration file my.cnf
The my.cnf file is the default configuration file for MariaDB, where you can adjust its parameters to better fit your setup:
Create a
my.cnffile in theconfigsfolder:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/configs/my.cnfSet the following configuration in your
configs/my.cnffile:[client] default-character-set = utf8mb4 [server] # General parameters skip_name_resolve = ON max_connections = 50 thread_cache_size = 50 character_set_server = utf8mb4 collation_server = utf8mb4_general_ci tmp_table_size = 64M # InnoDB storage engine parameters innodb_buffer_pool_size = 256M innodb_io_capacity = 2000 innodb_io_capacity_max = 3000 innodb_log_buffer_size = 32M innodb_log_file_size = 256MThis
my.cnffile makes the MariaDB instance fit for the resources-constrained environment of the K3s agent node in which the database is going to run:The
skip_name_resolveforces MariaDB to use only IPs for connections, avoiding wasting time in resolving hostnames first. Since MariaDB is going to be served through a KubernetesServiceobject, the name resolution is handled by the K3s cluster itself thanks to its CoreDNS service. Ghost will call that MariaDBServiceto use its database.The values set in the
max_connectionsandthread_cache_sizeparameters are considered for a low usage scenario where just a very small number of clients are expected to access the database.The character set
utf8mb4specified in thedefault-character-set,character_set_serverandcollation_serverparameters is the most adequate one for modern applications like Ghost. The main advantage ofutf8mb4is that it accommodates a much wider set of characters thanutf8or others. As a downside, be aware thatutf8mb4databases take up more storage space since their characters are “bigger”.The
tmp_table_sizelimits how large temporary tables can grow in memory.The engine used by default in MariaDB is InnoDB, and has its own set of parameters grouped together in the
my.cnffile for clarity:The
innodb_buffer_pool_sizeparameter sets the size of the buffer pool in memory, which is recommended to be around the 80% of the memory available for the MariaDB server.The
innodb_io_capacityandinnodb_io_capacity_maxparameters are related to the I/O capacity of the underlying storage. Here they are increased from their default values to fit better the SSD volume used for storing Ghost’s MariaDB database.The
innodb_log_buffer_sizeparameter affect how MariaDB’s redo log feature works. The bigger the buffer, the larger the transactions that MariaDB can execute without hitting storage before committing them.The
innodb_log_file_sizelimits the size of MariaDB’s redo log file.
Properties file dbnames.properties
There are a few names you need to specify in your database setup. Those names are values that are better loaded as variables in your MariaDB server container rather than being hardcoded in the MariaDB server configuration:
Create a
dbnames.propertiesfile under theconfigspath:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/configs/dbnames.propertiesCopy the following parameter lines into
configs/dbnames.properties:ghost-db-name=ghost-db ghost-username=ghostdb prometheus-exporter-username=promexpThe three key-value pairs above mean this:
ghost-db-name
Name for the Ghost database.ghost-username:
Name for the user associated to the Ghost database.prometheus-exporter-username
Name for the Prometheus metrics exporter user.
Initializer shell script initdb.sh
The Prometheus metrics exporter system you are going to include in your MariaDB server deployment requires its own user to access certain statistical data from the MariaDB instance. You have already configured its name as a variable in the previous dbnames.properties file, but you also need to create the user within the MariaDB installation. The problem is that MariaDB can only create one user in its initial run, but you also have to create the user Ghost needs to work with its own database.
To solve this conflict, you can use a initializer shell script that creates that extra user you need in the MariaDB database:
Create a
initdb.shfile in theconfigsdirectory:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/configs/initdb.shFill the
configs/initdb.shfile with the following shell script:#!/bin/sh echo ">>> Creating user for MariaDB Prometheus metrics exporter" mysql -u root -p$MYSQL_ROOT_PASSWORD --execute \ "CREATE USER '${MARIADB_PROMETHEUS_EXPORTER_USERNAME}'@'localhost' IDENTIFIED BY '${MARIADB_PROMETHEUS_EXPORTER_PASSWORD}' WITH MAX_USER_CONNECTIONS 3; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO '${MARIADB_PROMETHEUS_EXPORTER_USERNAME}'@'localhost'; FLUSH privileges;"This is an SQL script, executed by a MariaDB-provided
mysqlshell command, that creates the required user for the Prometheus metrics exporter. Notice how, instead of putting raw values, environment variables (MARIADB_PROMETHEUS_EXPORTER_USERNAMEandMARIADB_PROMETHEUS_EXPORTER_PASSWORD) are used as placeholders for the username and password values for the Prometheus metrics exporter’s user. Those variables are to be declared within theStatefulSetresource manifest you will declare later in this chapter.
MariaDB passwords
There is a number of passwords you need to set up in the MariaDB installation:
- For the MariaDB root user.
- For the Ghost database user.
- For the Prometheus metrics exporter user.
For convenience, declare all of these passwords as variables in the same properties file, so they can be turned into a Secret resource later:
Create a
dbusers.pwdfile under thesecretspath:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/secrets/dbusers.pwdSpecify your passwords as key-value pairs in
secrets/dbusers.pwd:root-password=l0nG.Pl4in_T3xt_sEkRet_p4s5wORD-FoR_rOo7_uZ3r! ghost-user-password=l0nG.Pl4in_T3xt_sEkRet_p4s5wORD-FoR_6h0sT_uZ3r! prometheus-exporter-password=l0nG.Pl4in_T3xt_sEkRet_p4s5wORD-FoR_3xP0rTeR_uZ3r!Warning
The passwords have to be put in
dbusers.pwdas plain unencrypted text
Be careful of who can access thisdbusers.pwdfile.
MariaDB persistent storage claim
As you saw when declaring Valkey’s storage, you need to declare a PersistentVolumeClaim to enable access to the persistent volume (to be declared in the last part of this Ghost deployment procedure) storing the MariaDB instance’s data:
Create a
db-mariadb.persistentvolumeclaim.yamlfile under theresourcesfolder:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/resources/db-mariadb.persistentvolumeclaim.yamlDeclare Ghost’s
PersistentVolumeClaimin theresources/db-mariadb.persistentvolumeclaim.yamlfile:# Ghost MariaDB claim of persistent storage apiVersion: v1 kind: PersistentVolumeClaim metadata: name: db-mariadb spec: accessModes: - ReadWriteOnce storageClassName: local-path volumeName: ghost-ssd-db resources: requests: storage: 6.5GThis persistent volume claim is exactly like the one for the Valkey server, although with its own
metadata.name, different claimed volume inspec.volumeNameand adjusted capacity inspec.resources.requests.storage.
MariaDB StatefulSet
Since MariaDB is a program whose main purpose is to store state (meaning data), its deployment must be declared as a StatefulSet:
Create a
db-mariadb.statefulset.yamlin theresourcespath:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/resources/db-mariadb.statefulset.yamlDeclare the
StatefulSetfor your Ghost’s MariaDB server inresources/db-mariadb.statefulset.yaml:# Ghost MariaDB StatefulSet for a sidecar server pod apiVersion: apps/v1 kind: StatefulSet metadata: name: db-mariadb spec: replicas: 1 serviceName: db-mariadb template: spec: containers: - name: server image: mariadb:11.8-noble ports: - name: server containerPort: 3306 env: - name: MYSQL_DATABASE valueFrom: configMapKeyRef: name: db-mariadb-config key: ghost-db-name - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: db-mariadb-passwords key: root-password - name: MYSQL_USER valueFrom: configMapKeyRef: name: db-mariadb-config key: ghost-username - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: db-mariadb-passwords key: ghost-user-password - name: MARIADB_PROMETHEUS_EXPORTER_USERNAME valueFrom: configMapKeyRef: name: db-mariadb-config key: prometheus-exporter-username - name: MARIADB_PROMETHEUS_EXPORTER_PASSWORD valueFrom: secretKeyRef: name: db-mariadb-passwords key: prometheus-exporter-password resources: requests: cpu: "0.75" memory: 256Mi volumeMounts: - name: mariadb-config subPath: my.cnf mountPath: /etc/mysql/my.cnf readOnly: true - name: mariadb-config subPath: initdb.sh mountPath: /docker-entrypoint-initdb.d/initdb.sh readOnly: true - name: mariadb-storage mountPath: /var/lib/mysql - name: metrics image: prom/mysqld-exporter:v0.18.0 ports: - name: metrics containerPort: 9104 args: - --collect.auto_increment.columns - --collect.binlog_size - --collect.engine_innodb_status - --collect.global_status - --collect.global_variables - --collect.info_schema.clientstats - --collect.info_schema.innodb_metrics - --collect.info_schema.innodb_tablespaces - --collect.info_schema.innodb_cmp - --collect.info_schema.innodb_cmpmem - --collect.info_schema.processlist - --collect.info_schema.query_response_time - --collect.info_schema.tables - --collect.info_schema.tablestats - --collect.info_schema.schemastats - --collect.info_schema.userstats - --collect.perf_schema.eventsstatements - --collect.perf_schema.eventsstatementssum - --collect.perf_schema.eventswaits - --collect.perf_schema.file_events - --collect.perf_schema.file_instances - --collect.perf_schema.indexiowaits - --collect.perf_schema.tableiowaits - --collect.perf_schema.tablelocks - --collect.perf_schema.replication_group_member_stats - --collect.perf_schema.replication_applier_status_by_worker - --collect.slave_hosts - --mysqld.address=localhost:3306 - --mysqld.username=$(MARIADB_PROMETHEUS_EXPORTER_USERNAME) env: - name: MARIADB_PROMETHEUS_EXPORTER_USERNAME valueFrom: configMapKeyRef: name: db-mariadb-config key: prometheus-exporter-username - name: MYSQLD_EXPORTER_PASSWORD valueFrom: secretKeyRef: name: db-mariadb-passwords key: prometheus-exporter-password resources: requests: cpu: "0.25" memory: 16Mi volumes: - name: mariadb-storage persistentVolumeClaim: claimName: db-mariadb - name: mariadb-config configMap: name: db-mariadb-config defaultMode: 444 items: - key: initdb.sh path: initdb.sh - key: my.cnf path: my.cnfIf you compare this
StatefulSetwith Valkey’s you will find many similarities, but also several differences:template.spec.containers
Like in the Valkey case, two containers are set in the pod as sidecars.Container
serverholds the MariaDB server instance:The
imageof MariaDB here is based on the Noble Numbat version (24.04 LTS) of Ubuntu.The
envsection contains several environment parameters. The ones with theMYSQL_prefix are directly recognized by the MariaDB server. TheMARIADB_PROMETHEUS_EXPORTER_USERNAMEandMARIADB_PROMETHEUS_EXPORTER_PASSWORDare meant only for theinitdb.shinitializer script. Notice how the values of these environment parameters are taken from adb-mariadb-passwordsecret and adb-mariadb-configconfig map you will declare later in the corresponding Kustomize declaration for this MariaDB subproject.The
volumeMountscontains three mount points:MountPath
/etc/mysql/my.cnf
The default path where MariaDB has itsmy.cnffile. Thismy.cnffile is the one you created before, and you will put it later in thedb-mariadbconfig map resource.MountPath
/docker-entrypoint-initdb.d/initdb.sh
The path/docker-entrypoint-initdb.dis a special one within the MariaDB container, prepared to execute (in alphabetical order) any shell or SQL scripts you put in here just the first time this container is executed. This way you can initialize databases or create extra users, as yourinitdb.shscript does. You will also includeinitdb.shin thedb-mariadbconfig map resource.MountPath
/var/lib/mysql
This is the default data folder of MariaDB. It is where the volumemariadb-storage’s filesystem is going to be mounted into.
Container
metricsis for the Prometheus metrics exporter service related to the MariaDB server:The
imageof this metrics exporter service does not clearly states what Linux distribution is based on.In
argsare set a number of parameters meant for the command launching the Prometheus metrics exporter service in the container. Pay attention to the last two arguments:mysqld.addressindicates the URL and port of the MariaDB server instance to the Prometheus metrics exporter. In this case, it specifies the default address for clarity.mysqld.usernameis for specifying the username the exporter has to use to connect with the MariaDB instance. Here, its value is provided by theMARIADB_PROMETHEUS_EXPORTER_USERNAMEenvironment variable declared in theenvsection of thismetricscontainer, not by the one set in the previousservercontainer. They have the same name just because their purpose also happens to be the same, although in different containers.
In the
envlist you have two environment variables. On one hand, theMARIADB_PROMETHEUS_EXPORTER_USERNAME, already explained in the description of themysqld.usernameargument. On the other, theMYSQLD_EXPORTER_PASSWORDis the environment parameter where the Prometheus metrics exporter expects to find its MariaDB user’s password.
template.spec.volumes
Declares the storage volumes to be used in the pod described in this template:With name
mariadb-storage
ThePersistentVolumeClaimnameddb-mariadbis enabled as a volume calledmariadb-storage.With name
mariadb-config
Themy.cnfandinitdb.shfiles are enabled here as volumes. The files will have the permission mode444by default in the container that mounts them.
MariaDB Service
The previous StatefulSet requires a Service named db-mariadb to run, so you need to declare it:
Create a file named
db-mariadb.service.yamlunderresources:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/resources/db-mariadb.service.yamlDeclare the
Serviceexposing your Ghost’s MariaDB instance inresources/db-mariadb.service.yaml:# Ghost MariaDB headless service apiVersion: v1 kind: Service metadata: name: db-mariadb annotations: prometheus.io/scrape: "true" prometheus.io/port: "9104" spec: type: ClusterIP clusterIP: None ports: - port: 3306 targetPort: server protocol: TCP name: server - port: 9104 targetPort: metrics protocol: TCP name: metricsSee that this
Serviceis headless since thespec.clusterIPisNone, implying that you have to call it by its FQDN. Also, this service’sportnumbers correspond with the ones configured ascontainerPortsin the MariaDB’sStatefulSet, although thetargetPortparameters makes them independent from the configuration set in the pod’s containers.
MariaDB Service’s FQDN
According to what is explained for the Valkey headless service’s FQDN, the absolute FQDN for this MariaDB headless service will be:
db-mariadb.ghost.svc.homelab.cluster.Your Ghost platform will invoke its MariaDB service with this absolute FQDN for best performance.
MariaDB Kustomize project
Now you have to create the main kustomization.yaml file describing your Ghost MariaDB Kustomize subproject:
Under
db-mariadb, create akustomization.yamlfile:$ touch $HOME/k8sprjs/ghost/components/db-mariadb/kustomization.yamlDeclare the
Kustomizationfor your Ghost’s MariaDB instance inkustomization.yaml:# Ghost MariaDB setup apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization labels: - pairs: app: db-mariadb includeSelectors: true includeTemplates: true resources: - resources/db-mariadb.persistentvolumeclaim.yaml - resources/db-mariadb.service.yaml - resources/db-mariadb.statefulset.yaml replicas: - name: db-mariadb count: 1 images: - name: mariadb newTag: 11.8-noble - name: prom/mysqld-exporter newTag: v0.18.0 configMapGenerator: - name: db-mariadb-config envs: - configs/dbnames.properties files: - configs/initdb.sh - configs/my.cnf secretGenerator: - name: db-mariadb-passwords envs: - secrets/dbusers.pwdThis
kustomization.yamlis very similar to the one you did for the Valkey instance, with the main difference being in the generator sections:The
configMapGeneratorsets up oneConfigMapresource calleddb-mariadb-config. When generated, it will map the two archives specified underfilesand all the key-value pairs included in the file referenced inenvs.The
secretGeneratorprepares oneSecretresource nameddb-mariadb-passwordsthat only contains the key-value sets within the file pointed at in itsenvssection.
Checking the Kustomize YAML output
At this point, you can verify with kubectl that the Kustomize project for Ghost’s MariaDB in stance gives you the proper YAML output:
Execute
kubectl kustomizeand pipe the YAML output to thelesscommand or other text editor, or dump it into a file:$ kubectl kustomize $HOME/k8sprjs/ghost/components/db-mariadb | lessCheck if your Kustomize YAML output is like the one below:
apiVersion: v1 data: ghost-db-name: ghost-db ghost-username: ghostdb initdb.sh: |- #!/bin/sh echo ">>> Creating user for MariaDB Prometheus metrics exporter" mysql -u root -p$MYSQL_ROOT_PASSWORD --execute \ "CREATE USER '${MARIADB_PROMETHEUS_EXPORTER_USERNAME}'@'localhost' IDENTIFIED BY '${MARIADB_PROMETHEUS_EXPORTER_PASSWORD}' WITH MAX_USER_CONNECTIONS 3; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO '${MARIADB_PROMETHEUS_EXPORTER_USERNAME}'@'localhost'; FLUSH privileges;" my.cnf: |- [client] default-character-set = utf8mb4 [server] # General parameters skip_name_resolve = ON max_connections = 50 thread_cache_size = 50 character_set_server = utf8mb4 collation_server = utf8mb4_general_ci tmp_table_size = 64M # InnoDB storage engine parameters innodb_buffer_pool_size = 256M innodb_io_capacity = 2000 innodb_io_capacity_max = 3000 innodb_log_buffer_size = 32M innodb_log_file_size = 256M prometheus-exporter-username: promexp kind: ConfigMap metadata: labels: app: db-mariadb name: db-mariadb-config-t9c84t7h62 --- apiVersion: v1 data: ghost-user-password: bDBuRy5QbDRpbl9UM3h0X3NFa1JldF9wNHM1d09SRC1Gb1JfNmgwc1RfdVozciE= prometheus-exporter-password: bDBuRy5QbDRpbl9UM3h0X3NFa1JldF9wNHM1d09SRC1Gb1JfM3hQMHJUZVJfdVozciE= root-password: bDBuRy5QbDRpbl9UM3h0X3NFa1JldF9wNHM1d09SRC1Gb1Jfck9vN191WjNyIQ== kind: Secret metadata: labels: app: db-mariadb name: db-mariadb-passwords-dtt9d6h2b9 type: Opaque --- apiVersion: v1 kind: Service metadata: annotations: prometheus.io/port: "9104" prometheus.io/scrape: "true" labels: app: db-mariadb name: db-mariadb spec: clusterIP: None ports: - name: server port: 3306 protocol: TCP targetPort: server - name: metrics port: 9104 protocol: TCP targetPort: metrics selector: app: db-mariadb type: ClusterIP --- apiVersion: v1 kind: PersistentVolumeClaim metadata: labels: app: db-mariadb name: db-mariadb spec: accessModes: - ReadWriteOnce resources: requests: storage: 6.5G storageClassName: local-path volumeName: ghost-ssd-db --- apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: db-mariadb name: db-mariadb spec: replicas: 1 selector: matchLabels: app: db-mariadb serviceName: db-mariadb template: metadata: labels: app: db-mariadb spec: containers: - env: - name: MYSQL_DATABASE valueFrom: configMapKeyRef: key: ghost-db-name name: db-mariadb-config-t9c84t7h62 - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: key: root-password name: db-mariadb-passwords-dtt9d6h2b9 - name: MYSQL_USER valueFrom: configMapKeyRef: key: ghost-username name: db-mariadb-config-t9c84t7h62 - name: MYSQL_PASSWORD valueFrom: secretKeyRef: key: ghost-user-password name: db-mariadb-passwords-dtt9d6h2b9 - name: MARIADB_PROMETHEUS_EXPORTER_USERNAME valueFrom: configMapKeyRef: key: prometheus-exporter-username name: db-mariadb-config-t9c84t7h62 - name: MARIADB_PROMETHEUS_EXPORTER_PASSWORD valueFrom: secretKeyRef: key: prometheus-exporter-password name: db-mariadb-passwords-dtt9d6h2b9 image: mariadb:11.8-noble name: server ports: - containerPort: 3306 name: server resources: requests: cpu: "0.75" memory: 256Mi volumeMounts: - mountPath: /etc/mysql/my.cnf name: mariadb-config readOnly: true subPath: my.cnf - mountPath: /docker-entrypoint-initdb.d/initdb.sh name: mariadb-config readOnly: true subPath: initdb.sh - mountPath: /var/lib/mysql name: mariadb-storage - args: - --collect.auto_increment.columns - --collect.binlog_size - --collect.engine_innodb_status - --collect.global_status - --collect.global_variables - --collect.info_schema.clientstats - --collect.info_schema.innodb_metrics - --collect.info_schema.innodb_tablespaces - --collect.info_schema.innodb_cmp - --collect.info_schema.innodb_cmpmem - --collect.info_schema.processlist - --collect.info_schema.query_response_time - --collect.info_schema.tables - --collect.info_schema.tablestats - --collect.info_schema.schemastats - --collect.info_schema.userstats - --collect.perf_schema.eventsstatements - --collect.perf_schema.eventsstatementssum - --collect.perf_schema.eventswaits - --collect.perf_schema.file_events - --collect.perf_schema.file_instances - --collect.perf_schema.indexiowaits - --collect.perf_schema.tableiowaits - --collect.perf_schema.tablelocks - --collect.perf_schema.replication_group_member_stats - --collect.perf_schema.replication_applier_status_by_worker - --collect.slave_hosts - --mysqld.address=localhost:3306 - --mysqld.username=$(MARIADB_PROMETHEUS_EXPORTER_USERNAME) env: - name: MARIADB_PROMETHEUS_EXPORTER_USERNAME valueFrom: configMapKeyRef: key: prometheus-exporter-username name: db-mariadb-config-t9c84t7h62 - name: MYSQLD_EXPORTER_PASSWORD valueFrom: secretKeyRef: key: prometheus-exporter-password name: db-mariadb-passwords-dtt9d6h2b9 image: prom/mysqld-exporter:v0.18.0 name: metrics ports: - containerPort: 9104 name: metrics resources: requests: cpu: "0.25" memory: 16Mi volumes: - name: mariadb-storage persistentVolumeClaim: claimName: db-mariadb - configMap: defaultMode: 444 items: - key: initdb.sh path: initdb.sh - key: my.cnf path: my.cnf name: db-mariadb-config-t9c84t7h62 name: mariadb-configPay particular attention to the
ConfigMapandSecretresources declared in the output:Their names have a hash as a suffix appended to their names.
The
db-mariadb-configconfig map has theinitdb.shandmy.cnfloaded in it (filenames as keys and their full contents as values), and the key-value pairs found indbnames.propertiesare set independently.The
db-mariadb-passwordssecret has the values set in thedbusers.pwdfile obfuscated in base64 encoding.
Remember that, if you dumped the Kustomize output into a YAML file, you can validate it with
kubeconform.
Do not deploy this MariaDB project on its own
This MariaDB setup is missing the persistent volume for storing data that you must not confuse with the claim you have configured for your MariaDB server. That PV and other elements are going to be declared in the main Kustomize project you will declare in the final part of this Ghost deployment procedure. Until then, do not deploy this MariaDB subproject.
Relevant system paths
Folders in kubectl client system
$HOME/k8sprjs/ghost/components/db-mariadb$HOME/k8sprjs/ghost/components/db-mariadb/configs$HOME/k8sprjs/ghost/components/db-mariadb/resources$HOME/k8sprjs/ghost/components/db-mariadb/secrets
Files in kubectl client system
$HOME/k8sprjs/ghost/components/db-mariadb/kustomization.yaml$HOME/k8sprjs/ghost/components/db-mariadb/configs/dbnames.properties$HOME/k8sprjs/ghost/components/db-mariadb/configs/initdb.sh$HOME/k8sprjs/ghost/components/db-mariadb/configs/my.cnf$HOME/k8sprjs/ghost/components/db-mariadb/resources/db-mariadb.persistentvolumeclaim.yaml$HOME/k8sprjs/ghost/components/db-mariadb/resources/db-mariadb.service.yaml$HOME/k8sprjs/ghost/components/db-mariadb/resources/db-mariadb.statefulset.yaml$HOME/k8sprjs/ghost/components/db-mariadb/secrets/dbusers.pwd
References
MariaDB
MySQL Server Exporter
Kubernetes
ConfigMaps
Storage
Kubernetes Blog. 2018. Local Persistent Volumes for Kubernetes Goes Beta
Kubernetes Documentation. Reference. Kubernetes API. Config and Storage Resources
StatefulSets
Environment variables
Other Kubernetes-related contents
About Kubernetes storage
StackOverflow. Kubernetes size definitions: What’s the difference of “Gi” and “G”?
GitHub. Helm. Issue. distinguish unset and empty values for storageClassName