Running a Jooma CMS on K3s.
K3S v1.24.8+k3s1 on Ubuntu 20.04 (AMD64). Disabled servicelb and traefik. Installed metalLB and traefik after initial installation. Using local-path storage class.
This config cannot scale - replicas: above 1 will not work if you are using more than one node. A ReadWriteOnce volume can only be mounted to a single pod (unless the pods are running on the same node). Get the files on GitHub (https://github.com/lars-c/K3s-Joomla)
Loadbalancer: metalLB is configured with an IP pool of 192.168.1.150-192.168.1.159. Pool is called 'first-pool'.
kubectl get ipaddresspool -n metallb-system
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
first-pool true false ["192.168.1.150-192.168.1.159"]
Environment variables:
Joomla: JOOMLA_DB_HOST, JOOMLA_DB_NAME and JOOMLA_DB_PASSWORD.
MySQL: MYSQL_PASSWORD, MYSQL_DATABASE and TZ
JOOMLA_DB_HOST configmap joomla_db_host joomla-mysql
JOOMLA_DB_NAME configmap mysql_database joomla_12
JOOMLA_DB_PASSWORD secret/mysql-secret password cGFzc3dvcmQ=
MYSQL_PASSWORD secret/mysql-secret password cGFzc3dvcmQ=
MYSQL_DATABASE configmap mysql_database configmap joomla_12
TZ configmap mysql_timezone configmap Europe/Copenhagen
Only MYSQL_PASSWORD/JOOMLA_DB_PASSWORD is mandatory.
Docker-compose.yaml file (edited) (https://hub.docker.com/_/joomla)
version: '3.1'
services:
joomla:
image: joomla
restart: always
links:
- joomladb:mysql
ports:
- 8080:80
environment:
JOOMLA_DB_HOST: joomladb
JOOMLA_DB_PASSWORD: example
joomladb:
image: mysql:5.6
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
As I use the same docker image, I will need to handle the following values:
Two services: Joomla and MySQL.
Joomla:
Image: joomla:php8.1-apache.
Links: Handle the service dependency with environment variables (and services).
Ports: Pod/container expect traffic on port 80.
Environment variables: handle with configmap or secrets.
Joomladb:
Image: mysql:5.7.
Environment variables: Passwords is best handled with a secrets.
Docker-compose example file do not include volumes. One way to handle volumes in a joomla docker-compose file:
version: '3.1'
services:
joomla:
image: joomla
volumes:
- joomla_data:/var/www/html
restart: always
links:
- joomladb:mysql
ports:
- 8080:80
environment:
JOOMLA_DB_HOST: joomladb
JOOMLA_DB_PASSWORD: example
joomladb:
image: mysql:5.6
volumes:
- mysql_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
joomal_data:
driver: local
mysql_data:
driver: local
Need to handle permanent storage for '/var/www/html' inside the joomla container/pod. Likewise for MySQL for the '/var/lib/mysql' path.
MySQL
1. Namespace
2. Service
3. ConfigMap
4. Secret
5. Storage
6. Deployment
Joomla
1. Service
2. Storage
6. Deployment
1. Namespace (MySQL)
Just the 'joomla' namespace (same for both services)
---
apiVersion: v1
kind: Namespace
metadata:
name: joomla
labels:
name: joomla
2. Service (MySQL)
Default MySQL port. The name of this service (joomla-mysql) is what the Joomla service will use.
---
apiVersion: v1
kind: Service
metadata:
name: joomla-mysql
namespace: joomla
labels:
app: joomla
spec:
ports:
- port: 3306
selector:
app: joomla
tier: mysql
clusterIP: None
3. configMap (Both)
The Joomla service need to know the name of the MySQL service (joomla_db_host). Database name (mysql_database) and database time zone (mysql_timezone) is optional.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: joomla
namespace: joomla
data:
joomla_db_host: "joomla-mysql"
mysql_database: "joomla_12"
mysql_timezone: "Europe/Copenhagen"
4. Secret (Both)
Database password Password must be base64 encoded. From a Ubuntu/WSL terminal:
echo -n password | base64
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
namespace: joomla
type: Opaque
data:
password: cGFzc3dvcmQ=
5. Storage (MySQL)
A persistent volume claim (PVC) for the MySQL deployment.
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: joomla-mysql-pv-claim
namespace: joomla
labels:
app: joomla
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
6. Deployment (MySQL)
Image: mysql:5.7
MYSQL_DATABASE, MYSQL_ROOT_PASSWORD and TZ is described in more details above. Only MYSQL_ROOT_PASSWORD is mandatory.
Ports: Pod use default MySQL port 3306.
Volumes: Using the above PersistentVolumeClaim 'joomla-mysql-pv-claim' for adding permanent storage for "/var/lib/mysql" inside the MySQL container/pod.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: joomla-mysql
namespace: joomla
labels:
app: joomla
spec:
selector:
matchLabels:
app: joomla
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: joomla
tier: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: joomla
key: mysql_database
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
- name: TZ
valueFrom:
configMapKeyRef:
name: joomla
key: mysql_timezone
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: joomla-mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: joomla-mysql-persistent-storage
persistentVolumeClaim:
claimName: joomla-mysql-pv-claim
1. Service (Joomla)
The Joomla pod expect trafic on port 80. Address-pool 'first-pool' defined. The choosen loadbalancer IP (192.168.1.152) is somewhere inside the defined 'first-pool' of IP adresses.
---
apiVersion: v1
kind: Service
metadata:
name: joomla
namespace: joomla
labels:
app: joomla
annotations:
metallb.universe.tf/address-pool: first-pool
spec:
ports:
- port: 80
selector:
app: joomla
type: LoadBalancer
loadBalancerIP: 192.168.1.152
2. Storage (Joomla)
Using storage class 'local-path' here.
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: joomla-pv-claim
namespace: joomla
labels:
app: joomla
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
6. Deployment (Joomla)
Image: Using php8.1-apache (Joomla official image)
JOOMLA_DB_HOST, JOOMLA_DB_NAME and JOOMLA_DB_PASSWORD are described above.
Joomla container use port 80 (TCP).
volumeMounts: Added a volumeMounts for path "/var/www/html" and finially created a volume.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: joomla
namespace: joomla
labels:
app: joomla
spec:
selector:
matchLabels:
app: joomla
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: joomla
tier: frontend
spec:
containers:
- image: joomla:php8.1-apache
name: joomla
env:
- name: JOOMLA_DB_HOST
valueFrom:
configMapKeyRef:
name: joomla
key: joomla_db_host
- name: JOOMLA_DB_NAME
valueFrom:
configMapKeyRef:
name: joomla
key: mysql_database
- name: JOOMLA_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- containerPort: 80
name: joomla
volumeMounts:
- name: joomla-persistent-storage
mountPath: /var/www/html
volumes:
- name: joomla-persistent-storage
persistentVolumeClaim:
claimName: joomla-pv-claim
Tiny, flawed fragments,
Fingers weave them with delight,
Beauty blooms as one.