wwwgmo/README.md
2025-06-20 08:45:33 +02:00

609 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# wwwgmo stack
## Description
Examples site with nginx, phpfpm, mysql, phpmyadmin, elasticsearch and kibana
## Build environment
|**folders**|**description**|
|:---|:---|
|docker.sh|files to build the docker image|
|docker/mariadb|env file|
|docker/nginx|config file|
|docker/php-fpm|files to create docker image|
|src|site source|
## Docker
### Global environment variables
Copy file ALL `.env.dist` to `.env`
Complete or modify the values according to your needs
### Build
#### Install plugin php for elasticsearch
```bash
./docker.sh install
```
#### Build image
```bash
./docker.sh build
```
or
```bash
./docker.sh build-no-cache
```
### Start
```bash
./docker.sh start
```
#### Check
```bash
docker exec wwwgmo-mariadb mysql -uroot -p<MYSQL_ROOT_PASSWORD> mysql -e 'SELECT user,host FROM mysql.user;'
```
```bash
docker exec wwwgmo-elasticsearch curl -u elastic:<ELASTIC_PASSWORD> http://wwwgmo-elasticsearch:9200/_cluster/health?pretty
```
```bash
docker exec wwwgmo-php-fpm curl -s -u elastic:<ELASTIC_PASSWORD> http://wwwgmo-elasticsearch:9200/_cluster/health?pretty
```
#### Access
http://<server_name>:<NGINX_PORT>
## kubernetes
|**folders**|**description**|
|:---|:---|
|deploy.sh|files to deploy on k8s or k3s (see ./deploy.s -h)|
|helm|Chart root folder|
|Chart.yaml|Charts file|
|values-configs.yml|configs file use for kubernetes manifest|
|values-secrets.yaml|secrets file for kubernetes manifet (Must be encrypted with sops in a production environment)|
|templates/elasticsearch|manifests for elasticsearch|
|templates/kibana|manifests for kibana|
|templates/mariadb|manifests for mariadb|
|templates/phpmyadmin|manifests for phpmyadmin|
|templates/php-fpm|manifest for php-fpm|
### Secret registry (regcred)
You need credential to pull an image from private registry.
Create or modify the secret
```bash
kubectl create secret docker-registry secret-regcred --dry-run=client \
--docker-server=https://index.docker.io/v1/ \
--docker-username=<username> \
--docker-password=<secret> \
--docker-email=<adress@sample.com> -o yaml > helm/template/secret-regcred.yaml
```
### Certificats
```bash
cat certs/gmolab.net.key | base64 -w0
```
copy the base64 result into file `values-secrets.yaml` in ssl_key key
```bash
cat certs/gmolab.net.crt | base64 -w0
```
copy the base64 result into file `values-config.yaml` in ssl_crt key
### Docker image version
In the `helm/Chart.yaml` file, the `appVersion` value must match the version of the docker image (see DOCKER_IMAGE_VERSION in the `.env` file and SITE_VERSION in the `docker/php-fpm/.env` file)
## Deployment by script
This is the recommended way
>This script builds the docker image based on the Kubernetes VM architecture (AMD64 or ARM64). At each deployment the minor version of the image is incremented by 1.
```bash
./deploy.md -n wwwgmo -k k3s
```
## Manual deployment
### Set kubesystem config
```bash
rm -f $HOME/.kube/config
```
for **k3s**
```bash
ln -s $HOME/.kube/k3s $HOST/.kube/config
```
for **k8s**
```bash
ln -s $HOST/.kube/k8s $HOST/.kube/config
```
### Set namespace and kube system
```bash
export NS=wwwgmo
export KUBE_SYS=k3s|k8s
```
### Test template
```bash
helm template $NS --set kube=$KUBE_SYS ./helm --values=./helm/values-configs.yaml --values=./helm/values-secrets.yaml --namespace $NS
```
### Chart deployment
```bash
helm upgrade $NS --set kube=$KUBE_SYS ./helm --install --atomic --cleanup-on-fail --values=./helm/values-configs.yaml --values=./helm/values-secrets.yaml --namespace $NS --create-namespace
```
## Remove
```bash
helm uninstall $NS -n $NS
kubectl delete namespaces $NS
```
## NOTES
### Cronjob
When we deploy manually (I do not why) you must trig manually the cronjob to make a DB backup to termine correctly the helm command
```bash
kubectl create job -n $NS --from=cronjob/cronjob-mariadb-backupdb dbbackup-$(date +%Y-%m-%d-%H-%M-%S)
```
## Database
Not necessary because created during deployment. We leave the procedure below for information
First export NS environment variable
```bash
export NS=<your_namespace>
```
You can use `createDBOnKube.sh` or create manually with below commands
#### Create user
```bash
kubectl -n $NS exec statefulset-mariadb-0 --container mariadb -- /bin/bash -c "/usr/bin/mysql -u root -p<rootPass> -e \"CREATE USER 'gmo_db'@'%' IDENTIFIED BY '<dbPass>';\""
```
#### Check user
```bash
kubectl -n $NS exec statefulset-mariadb-0 --container mariadb -- /bin/bash -c "/usr/bin/mysql -u root -p<rootPass> -e 'SELECT user,host FROM mysql.user;'"
```
#### Create database
```bash
kubectl -n $NS exec statefulset-mariadb-0 --container mariadb -- /bin/bash -c "/usr/bin/mysql -u root -p<rootPass> -e \"CREATE DATABASE gmo_db;\""
```
#### Check database
```bash
kubectl -n $NS exec statefulset-mariadb-0 --container mariadb -- /bin/bash -c "/usr/bin/mysql -u root -p<rootPass> -e 'SHOW DATABASES;'"
```
#### Grants access
```bash
kubectl -n $NS exec statefulset-mariadb-0 --container mariadb -- /bin/bash -c "/usr/bin/mysql -u root -p<rootpass> -e \"GRANT ALL PRIVILEGES ON gmo_db.* TO 'gmo_db'@'%';FLUSH PRIVILEGES;\""
```
#### Check grants
```bash
kubectl -n $NS exec statefulset-mariadb-0 --container mariadb -- /bin/bash -c "/usr/bin/mysql -u root -p<rootPass> -e \"SHOW GRANTS FOR 'gmo_db'@'%';\""
```
## Troubeshooting
### How to Fix "Pods stuck in Terminating status" Error
```bash
kubectl get pods --all-namespaces | grep Terminating | while read line; do
pod_name=$(echo $line | awk '{print $2}' ) \
name_space=$(echo $line | awk '{print $1}' ); \
kubectl delete pods $pod_name -n $name_space --grace-period=0 --force
done
```
## Sources
[Elasticsearch-PHP](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html)
[Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)
[MariaDB Statefulset](https://mariadb.org/create-statefulset-mariadb-application-in-k8s/)
[PHP-FPM, nginx, kubernetes and docker](https://matthewpalmer.net/kubernetes-app-developer/articles/php-fpm-nginx-kubernetes.html)
https://www.elastic.co/guide/en/elasticsearch/reference/8.18/docker.html
## Changelog
### 3.25 (2024-04-14)
**New features:**
* added elasticsearch and kibana
* added option `install` to script `docker.sh` to install php elasticserch module
* created `deploy.sh` script
**Fixed bugs:**
* problem with display environment var in php site
**Updated:**
* added new features in README.md
* added Changelog part in README.md
---
### 2.5 (2024-03-29)
**Fixed bugs:**
* fixed somes bugs
**New features:**
* posibility to deploy on k3s or k8s
**Updated:**
* updated README.md
---
### 1.0 (2024-03-01)
* Created from scratch
Ignorer et passer au contenu
Vous avez dit :
J'ai l'erreur suivante lorsque j'exécute mon ficher docker-compose.yml:
[2025-06-19T16:58:29.674+00:00][ERROR][elasticsearch-service] Unable to retrieve version information from Elasticsearch nodes. security_exception
Root causes:
security_exception: missing authentication credentials for REST request [/_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip]
Mon fichier docker-compose.yml
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.18.2
container_name: elasticsearch
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.type=single-node
- bootstrap.memory_lock=true
- xpack.security.enabled=true
- ELASTIC_PASSWORD=changeme
- xpack.security.http.ssl.enabled=false
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ulimits:
memlock:
soft: -1
hard: -1
ports:
- "9200:9200"
- "9300:9300"
volumes:
# - esdata:/usr/share/elasticsearch/data
- wwwgmo-elasticsearch:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.18.2
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- xpack.security.enabled=false
ports:
- "5601:5601"
ChatGPT a dit :
Lerreur que vous rencontrez est causée par lactivation de la sécurité dans Elasticsearch (xpack.security.enabled=true) sans fournir didentifiants dauthentification lors de la tentative daccès à l'API REST.
🔍 Détail de l'erreur :
security_exception: missing authentication credentials for REST request [/_nodes?...]
Cela signifie que Kibana ou un autre service tente de communiquer avec Elasticsearch sans credentials, alors que ce dernier requiert une authentification.
✅ Solution 1 : Aligner la sécurité entre Kibana et Elasticsearch
Actuellement :
Elasticsearch a xpack.security.enabled=true
Kibana a xpack.security.enabled=false
Ce nest pas compatible. Kibana doit être configuré pour utiliser les identifiants quand Elasticsearch a la sécurité activée.
🛠 Modifier la section kibana comme suit :
kibana:
image: docker.elastic.co/kibana/kibana:8.18.2
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=changeme
ports:
- "5601:5601"
⚠️ Important : On utilise ici ELASTICSEARCH_USERNAME=elastic et ELASTICSEARCH_PASSWORD=changeme, car vous avez défini ce mot de passe dans la variable d'environnement ELASTIC_PASSWORD côté Elasticsearch.
✅ Solution 2 : Désactiver complètement la sécurité (pour développement uniquement)
Si vous êtes en environnement de test ou de développement local, vous pouvez désactiver la sécurité côté Elasticsearch.
environment:
- xpack.security.enabled=false
Dans ce cas, gardez aussi Kibana sans sécurité :
- xpack.security.enabled=false
⚠️ Pas recommandé en production : cette approche désactive les protections daccès aux données.
🧪 Astuce : Tester si tout fonctionne
Une fois les containers relancés, testez laccès à Elasticsearch :
curl -u elastic:changeme http://localhost:9200
Et pour Kibana : ouvrez http://localhost:5601 dans un navigateur.
Souhaitez-vous :
Garder la sécurité activée et intégrer les credentials dans tous les services ?
Ou désactiver la sécurité pour un usage local plus simple ?
Vous avez dit :
Garder la sécurité activée et intégrer les credentials dans tous les services
ChatGPT a dit :
Parfait ! Si vous souhaitez garder la sécurité activée, alors il faut que tous les services clients (comme Kibana) sauthentifient auprès dElasticsearch.
Voici comment ajuster correctement votre docker-compose.yml pour intégrer les identifiants.
✅ Fichier docker-compose.yml corrigé
version: "3.8"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.18.2
container_name: elasticsearch
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.type=single-node
- bootstrap.memory_lock=true
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=false
- ELASTIC_PASSWORD=changeme
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ulimits:
memlock:
soft: -1
hard: -1
ports:
- "9200:9200"
- "9300:9300"
volumes:
- wwwgmo-elasticsearch:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.18.2
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=changeme
ports:
- "5601:5601"
volumes:
wwwgmo-elasticsearch:
🔐 Authentification à l'API Elasticsearch (test via curl)
Une fois vos conteneurs démarrés, testez si l'accès avec mot de passe fonctionne :
curl -u elastic:changeme http://localhost:9200
Réponse attendue :
{
"name": "es01",
"cluster_name": "es-docker-cluster",
"cluster_uuid": "...",
"version": {
"number": "8.18.2",
...
},
"tagline": "You Know, for Search"
}
✅ Accès à Kibana
Ouvrez http://localhost:5601 dans votre navigateur. Kibana devrait démarrer sans vous afficher d'erreur liée à la connexion Elasticsearch.
✅ Recommandation de sécurité (optionnelle)
Pour un environnement plus sûr :
Créez un nouvel utilisateur avec des permissions spécifiques pour Kibana, via lAPI ou linterface dadmin de Kibana.
Évitez d'utiliser elastic en production, car cest un super admin.
Souhaitez-vous un exemple de script pour créer un utilisateur avec rôle personnalisé ?
Vous avez dit :
Error: [config validation of [elasticsearch].username]: value of "elastic" is forbidden. This is a superuser account that cannot write to system indices that Kibana needs to function. Use a service account token instead. Learn more: https://www.elastic.co/guide/en/elasticsearch/reference/8.0/service-accounts.html
at ensureValidConfiguration (/usr/share/kibana/node_modules/@kbn/core-config-server-internal/src/ensure_valid_configuration.js:44:11)
at Server.preboot (/usr/share/kibana/node_modules/@kbn/core-root-server-internal/src/server.js:181:7)
at Root.preboot (/usr/share/kibana/node_modules/@kbn/core-root-server-internal/src/root/index.js:48:14)
at bootstrap (/usr/share/kibana/node_modules/@kbn/core-root-server-internal/src/bootstrap.js:96:29)
at Command.<anonymous> (/usr/share/kibana/src/cli/serve/serve.js:235:5)
ChatGPT a dit :
Merci pour ce message derreur très clair — Kibana refuse catégoriquement d'utiliser l'utilisateur elastic à partir d'Elasticsearch 8, car :
❌ elastic est un super-utilisateur. Il ne peut pas être utilisé pour que Kibana écrive dans les indices système, ce qui est nécessaire pour qu'il fonctionne correctement.
✅ Solution recommandée : utiliser un service account token
🔐 Étapes pour créer un Service Account Token pour Kibana :
Lancer Elasticsearch avec sécurité activée
Gardez xpack.security.enabled=true
Assurez-vous que le conteneur Elasticsearch fonctionne
Créer un Service Account Token pour Kibana
Ouvrez un terminal et exécutez :
docker exec -it elasticsearch \
bin/elasticsearch-service-tokens create kibana kibana-token
Cela génère un token dans ce format :
AAEAAWVsYXN0aWMvY2liYW5hL2tpYmFuYS10b2tlbjoxR3VOSVZzUjZsb3pk...
Mettre à jour votre docker-compose.yml pour Kibana
Supprimez ELASTICSEARCH_USERNAME et ELASTICSEARCH_PASSWORD, et utilisez ELASTICSEARCH_SERVICEACCOUNTTOKEN à la place :
kibana:
image: docker.elastic.co/kibana/kibana:8.18.2
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_SERVICEACCOUNTTOKEN=AAEAAWVsYXN0aWMvY2liYW5hL2tpYmFuYS10b2tlbjoxR3VOSVZzUjZsb3pk...
ports:
- "5601:5601"
(remplace le token par celui généré précédemment)
🔄 Ensuite :
Redémarre les services :
docker-compose down
docker-compose up -d
Va sur http://localhost:5601 pour voir Kibana se connecter correctement.
🔎 Besoin d'aller plus loin ?
Si tu préfères créer un utilisateur dédié à Kibana au lieu dun token de service, je peux aussi te guider pas à pas avec elasticsearch-users ou via l'API REST.
Souhaites-tu cette alternative ?
Vous avez dit :
oui
ChatGPT a dit :
Parfait ! Voici comment créer un utilisateur dédié à Kibana, via l'API REST d'Elasticsearch, avec des rôles appropriés pour permettre à Kibana de fonctionner sans utiliser le super-utilisateur elastic.
🎯 Objectif
Créer un utilisateur, par exemple kibana_system_user, qui a le rôle kibana_system (prérequis minimum pour que Kibana fonctionne).
✅ Étapes détaillées
1. 🔐 Authentifiez-vous avec le super-utilisateur elastic
Exécute cette commande pour vérifier que tu peux parler à Elasticsearch :
curl -u elastic:changeme http://localhost:9200
2. 👤 Créer un nouvel utilisateur kibana_system_user
curl -X POST http://localhost:9200/_security/user/kibana_system_user \
-u elastic:changeme \
-H "Content-Type: application/json" \
-d '{
"password" : "kibanapassword",
"roles" : [ "kibana_system" ],
"full_name" : "Kibana System User",
"email" : "kibana@example.com"
}'
⚠️ Le mot de passe ici est kibanapassword. Tu peux le changer selon tes préférences.
3. 🔧 Modifier docker-compose.yml pour Kibana
Mets à jour la section Kibana avec ces variables denvironnement :
kibana:
image: docker.elastic.co/kibana/kibana:8.18.2
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=kibana_system_user
- ELASTICSEARCH_PASSWORD=kibanapassword
ports:
- "5601:5601"
4. 🔄 Redémarre les services
docker-compose down
docker-compose up -d
5. ✅ Accès à Kibana
Rends-toi sur http://localhost:5601. Kibana devrait démarrer sans erreur de permission, car il utilise désormais un utilisateur restreint, mais autorisé à accéder aux indices système nécessaires.
✅ Résumé
Élément Valeur
Utilisateur Elasticsearch kibana_system_user
Rôle attribué kibana_system
Mot de passe kibanapassword (ou autre)
Avantage Bonne pratique, sécurisé
Souhaites-tu aussi créer un utilisateur pour ingester des données dans Elasticsearch via une application ?
Vous avez dit :
et tout ca dans un fichier docker-compose
ChatGPT a dit :
Parfait, je vais taider à tout intégrer dans un seul docker-compose.yml, avec :
Elasticsearch sécurisé
Création automatique de lutilisateur kibana_system_user avec le rôle kibana_system
Kibana configuré pour utiliser cet utilisateur
⚠️ Important :
Elasticsearch ne permet pas nativement la création d'utilisateurs via le docker-compose.yml, donc on doit ajouter un script d'initialisation personnalisé monté dans le conteneur, qui s'exécute au démarrage.
✅ Structure du projet recommandée :
project/
├── docker-compose.yml
├── elasticsearch/
│ └── create_kibana_user.sh
🔧 elasticsearch/create_kibana_user.sh (script d'init)
#!/bin/bash
# Attendre qu'Elasticsearch soit démarré
echo "⏳ Attente du démarrage d'Elasticsearch..."
until curl -u elastic:changeme -s http://localhost:9200 >/dev/null; do
sleep 2
done
echo "✅ Elasticsearch est prêt. Création de l'utilisateur Kibana..."
# Créer un utilisateur pour Kibana
curl -X POST http://localhost:9200/_security/user/kibana_system_user \
-u elastic:changeme \
-H "Content-Type: application/json" \
-d '{
"password" : "kibanapassword",
"roles" : [ "kibana_system" ],
"full_name" : "Kibana System User"
}'
echo "✅ Utilisateur Kibana créé avec succès."
Donne les permissions au script :
chmod +x elasticsearch/create_kibana_user.sh
📦 docker-compose.yml complet
version: "3.8"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.18.2
container_name: elasticsearch
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.type=single-node
- bootstrap.memory_lock=true
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=false
- ELASTIC_PASSWORD=changeme
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ulimits:
memlock:
soft: -1
hard: -1
ports:
- "9200:9200"
- "9300:9300"
volumes:
- wwwgmo-elasticsearch:/usr/share/elasticsearch/data
- ./elasticsearch/create_kibana_user.sh:/usr/local/bin/create_kibana_user.sh
command: >
bash -c "
/bin/tini -g -- /usr/local/bin/docker-entrypoint.sh &
pid=$!;
sleep 20;
bash /usr/local/bin/create_kibana_user.sh;
wait $pid
"
kibana:
image: docker.elastic.co/kibana/kibana:8.18.2
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=kibana_system_user
- ELASTICSEARCH_PASSWORD=kibanapassword
ports:
- "5601:5601"
volumes:
wwwgmo-elasticsearch:
✅ Lancer le tout
Dans ton terminal :
docker-compose down -v
docker-compose up --build
✅ Résultat attendu
Elasticsearch démarre avec la sécurité activée
Un script crée automatiquement un utilisateur kibana_system_user
Kibana l'utilise pour se connecter
Tout est prêt et fonctionnel sans intervention manuelle
Souhaites-tu que je taide à ajouter aussi un utilisateur applicatif (ex: my_app_user) avec accès en lecture/écriture ?
Joindre
Rechercher
Voix
ChatGPT peut faire des erreurs. Envisagez de vérifier les informations importantes.