diff --git a/.github/workflows/docker-hub.yaml b/.github/workflows/docker-hub.yaml index 200295d..685bcd0 100644 --- a/.github/workflows/docker-hub.yaml +++ b/.github/workflows/docker-hub.yaml @@ -17,7 +17,7 @@ jobs: runs-on: "ubuntu-latest" steps: - name: "Checkout" - uses: "actions/checkout@v6" + uses: "actions/checkout@v7" - name: "Update repository description" uses: "peter-evans/dockerhub-description@v5" with: diff --git a/.github/workflows/docker-publish-base.yaml b/.github/workflows/docker-publish-base.yaml index 8a82833..23fb443 100644 --- a/.github/workflows/docker-publish-base.yaml +++ b/.github/workflows/docker-publish-base.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - uses: hadolint/hadolint-action@v3.3.0 with: dockerfile: ./docker/php/Dockerfile.base @@ -30,7 +30,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 diff --git a/.github/workflows/docker-publish-nginx.yaml b/.github/workflows/docker-publish-nginx.yaml index d34b213..ed1b24a 100644 --- a/.github/workflows/docker-publish-nginx.yaml +++ b/.github/workflows/docker-publish-nginx.yaml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - uses: hadolint/hadolint-action@v3.3.0 with: dockerfile: ./docker/nginx/Dockerfile @@ -41,7 +41,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 diff --git a/.github/workflows/docker-publish-php-fpm.yaml b/.github/workflows/docker-publish-php-fpm.yaml index 9fa0157..586f545 100644 --- a/.github/workflows/docker-publish-php-fpm.yaml +++ b/.github/workflows/docker-publish-php-fpm.yaml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - uses: hadolint/hadolint-action@v3.3.0 with: dockerfile: ./docker/php/Dockerfile @@ -41,7 +41,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 diff --git a/.github/workflows/helm-publish.yaml b/.github/workflows/helm-publish.yaml index c14ee9c..54d2030 100644 --- a/.github/workflows/helm-publish.yaml +++ b/.github/workflows/helm-publish.yaml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install Helm uses: azure/setup-helm@v5 @@ -38,7 +38,7 @@ jobs: needs: lint steps: - name: Check out repository code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install Helm uses: azure/setup-helm@v5 @@ -68,10 +68,10 @@ jobs: publish: runs-on: ubuntu-latest needs: package - if: github.event.inputs.publish == 'true' + if: ${{ github.event_name == 'release' || github.event.inputs.publish == 'true' }} steps: - name: Check out repository code with full history - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: fetch-depth: 0 diff --git a/.gitignore b/.gitignore index 18998d9..dcf92ce 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ .env -*/.env \ No newline at end of file +*/.env +values-custom.yaml +*/values-custom.yaml \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index fe38fc9..21ead82 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,11 +2,12 @@ ## Overview -This repository contains Docker configurations for deploying GLPI (an IT asset management system). The project consists of: +This repository contains Docker and Kubernetes configurations for deploying GLPI (an IT asset management system). The project consists of: - PHP-FPM base image (`docker/php/Dockerfile.base`) - PHP-FPM application image (`docker/php/Dockerfile`) - Nginx reverse proxy (`docker/nginx/Dockerfile`) - Docker Compose configurations for development and production +- Helm chart for Kubernetes deployment (`kubernetes/glpi/`) ## Build Commands @@ -19,8 +20,8 @@ docker-compose -f docker-compose-build.yml build # Build specific image docker build -t eftechcombr/glpi:base -f docker/php/Dockerfile.base docker/php/ -docker build -t eftechcombr/glpi:php-fpm-11.0.6 -f docker/php/Dockerfile docker/php/ -docker build -t eftechcombr/glpi:nginx-11.0.6 -f docker/nginx/Dockerfile docker/nginx/ +docker build -t eftechcombr/glpi:php-fpm-11.0.8 -f docker/php/Dockerfile docker/php/ +docker build -t eftechcombr/glpi:nginx-11.0.8 -f docker/nginx/Dockerfile docker/nginx/ ``` ### Run Containers @@ -51,15 +52,17 @@ docker build --check docker/php/ docker build --check docker/nginx/ # Scan for secrets (via hadolint --secret) -hadolint --secret支气管 docker/php/Dockerfile.base +hadolint --secret docker/php/Dockerfile.base ``` +DeepSource is also configured for automated linting via `.deepsource.toml` (docker, secrets, and shell analyzers). + ## Code Style Guidelines ### Dockerfiles #### General Rules -- Use specific version tags for base images (e.g., `php:8.4.14-fpm-alpine3.22`, not `php:latest`) +- Use specific version tags for base images (e.g., `php:8.4.19-fpm-alpine3.22`, not `php:latest`) - Pin package versions in Alpine (e.g., `icu-dev=76.1-r1`) - Always clean up build dependencies with `apk del .build-deps` - Remove `docker-php-source delete` after installing extensions @@ -83,16 +86,16 @@ docker-php-ext-install intl mysqli gd exif bz2 zip ldap opcache bcmath ``` #### Redis Extension -Install via PECL with version pinning: +Install via PECL (version pinning recommended for reproducible builds): ```dockerfile -pecl install redis-6.2.0 +pecl install redis docker-php-ext-enable redis ``` ### Docker Compose #### Version Tagging -- Always use explicit version tags (e.g., `11.0.6`, not `latest`) +- Always use explicit version tags (e.g., `11.0.8`, not `latest`) - Keep all service image tags synchronized - Use semantic versioning @@ -162,11 +165,11 @@ trap 'echo "Error on line $LINENO"' ERR ### Images - Lowercase: `eftechcombr/glpi` - Use kebab-case: `php-fpm`, `nginx` -- Version format: `11.0.6` +- Version format: `11.0.8` ### Services (docker-compose) - Lowercase with hyphens: `mariadb`, `glpi-db-install` -- Descriptive: `glpi-db-configure`, `glpi-cache-configure` +- Descriptive: `glpi-db-configure`, `glpi-cache-configure`, `glpi-verify-dir`, `glpi-db-upgrade`, `mariadb-timezone` ### Environment Variables - Uppercase with underscores: `MARIADB_HOST`, `GLPI_VERSION` @@ -177,7 +180,7 @@ trap 'echo "Error on line $LINENO"' ERR When upgrading GLPI or PHP versions: 1. Update `docker/php/Dockerfile.base`: - - PHP version (e.g., `8.4.13` → `8.4.14`) + - PHP version (e.g., `8.4.13` → `8.4.19`) - Alpine version if needed - All pinned package versions (verify they exist in Alpine) @@ -187,23 +190,32 @@ When upgrading GLPI or PHP versions: 3. Update `docker/.env`: - `VERSION="11.0.x"` -4. Update `docker/docker-compose.yml`: +4. Update `docker/.env.example`: + - `VERSION="11.0.x"` + +5. Update `docker/docker-compose.yml`: - All image tags -5. Update `docker/docker-compose-build.yml`: +6. Update `docker/docker-compose-build.yml`: - All image tags -6. Update `docker/nginx/Dockerfile`: +7. Update `docker/nginx/Dockerfile`: - Base image tag -7. Verify with hadolint: +8. Update `kubernetes/glpi/Chart.yaml`: + - `version:` and `appVersion:` fields + +9. Update `kubernetes/glpi/values.yaml`: + - `glpi.version`, `glpi.phpfpm.image.tag`, `glpi.nginx.image.tag` + +10. Verify with hadolint: ```bash hadolint docker/php/Dockerfile.base hadolint docker/php/Dockerfile hadolint docker/nginx/Dockerfile ``` -8. Test build locally: +11. Test build locally: ```bash cd docker docker-compose -f docker-compose-build.yml build base @@ -215,10 +227,10 @@ Current pinned versions in `Dockerfile.base` (Alpine 3.22): | Package | Version | |---------|---------| -| php base | 8.4.14-fpm-alpine3.22 | +| php base | 8.4.19-fpm-alpine3.22 | | icu-dev | 76.1-r1 | -| zlib-dev | 1.3.1-r2 | -| libpng-dev | 1.6.55-r0 | +| zlib-dev | 1.3.2-r0 | +| libpng-dev | 1.6.57-r0 | | bzip2-dev | 1.0.8-r6 | | libzip-dev | 1.11.4-r0 | | openldap-dev | 2.6.8-r0 | @@ -228,7 +240,7 @@ Current pinned versions in `Dockerfile.base` (Alpine 3.22): | file | 5.46-r2 | | g++ | 14.2.0-r6 | | gcc | 14.2.0-r6 | -| musl-dev | 1.2.5-r10 | +| musl-dev | 1.2.5-r12 | | make | 4.4.1-r3 | | pkgconf | 2.4.3-r0 | | re2c | 4.2-r0 | diff --git a/README.md b/README.md index 744163a..6e6d69c 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ Manifest files for building and deploying **GLPI** using containers with Docker ## Supported Containers - [x] PHP-FPM: `php:8.4.19-fpm-alpine3.22` -- [x] Nginx: `nginxinc/nginx-unprivileged:1.29.1-alpine3.22-slim` -- [x] GLPI PHP: `eftechcombr/glpi:php-fpm-11.0.6` -- [x] GLPI Nginx: `eftechcombr/glpi:nginx-11.0.6` +- [x] Nginx: `nginxinc/nginx-unprivileged:1.27.5-alpine3.21-slim` +- [x] GLPI PHP: `eftechcombr/glpi:php-fpm-11.0.8` + - [x] GLPI Nginx: `eftechcombr/glpi:nginx-11.0.8` ## Quick Start ### Using Helm (Kubernetes) @@ -21,7 +21,7 @@ Manifest files for building and deploying **GLPI** using containers with Docker Add the GLPI Helm chart repository: ```sh -helm repo add glpi https://eftechcombr.github.io/glpi/ +helm repo add eftechcombr https://eftechcombr.github.io/glpi/ helm repo update ``` @@ -31,25 +31,25 @@ helm repo update Install GLPI using Helm: ```sh -helm install my-glpi glpi/glpi +helm install my-glpi eftechcombr/glpi ``` Or with custom values: ```sh -helm install my-glpi glpi/glpi -f custom-values.yaml +helm install my-glpi eftechcombr/glpi -f custom-values.yaml ``` #### Searching for Available Versions ```sh -helm search repo glpi --versions +helm search repo eftechcombr --versions ``` #### Upgrading the Chart ```sh -helm upgrade my-glpi glpi/glpi +helm upgrade my-glpi eftechcombr/glpi ``` #### Uninstalling the Chart @@ -64,7 +64,14 @@ helm uninstall my-glpi 2. Set up environment variables: ```sh cp docker/.env.example docker/.env +# Edit docker/.env with your desired configuration ``` +3. Start the containers: +```sh +cd docker +docker compose up -d +``` +GLPI will be accessible at http://localhost:8080 ## Credentials @@ -75,15 +82,18 @@ cp docker/.env.example docker/.env ### docker-compose - ./docker/_env ---> please rename to /docker/.env + ./docker/.env.example ---> copy to ./docker/.env and customize + + See ./docker/.env for available environment variables including: + - MARIADB_HOST, MARIADB_PORT, MARIADB_DATABASE, MARIADB_USER, MARIADB_PASSWORD + - GLPI_LANG, VERSION, CACHE_DSN + - GLPI_VAR_DIR, GLPI_CONFIG_DIR, GLPI_MARKETPLACE_DIR and other directory paths ### kubernetes - ./kubernetes/glpi-configmap.yaml - ./kubernetes/glpi-secrets.yaml - ./kubernetes/mariadb-configmap.yaml - ./kubernetes/mariadb-secret.yaml + See ./kubernetes/glpi/values.yaml for all configurable Helm chart parameters, + including GLPI, MariaDB, Redis, Ingress, and external database settings. diff --git a/docker/.env.example b/docker/.env.example index 132f170..fe46d18 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -1,5 +1,5 @@ GLPI_LANG="en_US" -VERSION="11.0.5" +VERSION="11.0.8" GLPI_MARKETPLACE_DIR=/var/www/html/marketplace GLPI_VAR_DIR=/var/lib/glpi GLPI_DOC_DIR=/var/lib/glpi diff --git a/docker/docker-compose-build.yml b/docker/docker-compose-build.yml index ae267f5..063e94e 100644 --- a/docker/docker-compose-build.yml +++ b/docker/docker-compose-build.yml @@ -23,7 +23,7 @@ services: glpi-db-upgrade: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure env_file: ./.env volumes: @@ -37,7 +37,7 @@ services: glpi-db-install: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure env_file: ./.env volumes: @@ -50,7 +50,7 @@ services: - /usr/local/bin/glpi-db-install.sh glpi-verify-dir: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -63,7 +63,7 @@ services: - /usr/local/bin/glpi-verify-dir.sh glpi-db-configure: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -76,7 +76,7 @@ services: - /usr/local/bin/glpi-db-configure.sh glpi-cache-configure: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -99,7 +99,7 @@ services: php: build: php/ - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: unless-stopped volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -116,7 +116,7 @@ services: nginx: build: nginx/ - image: eftechcombr/glpi:nginx-11.0.7 + image: eftechcombr/glpi:nginx-11.0.8 restart: unless-stopped ports: - "8080:8080" diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 063b654..b34e26c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -22,7 +22,7 @@ services: command: mariadb -h $MARIADB_HOST -u root -p$MARIADB_ROOT_PASSWORD -e "GRANT SELECT ON \`mysql\`.\`time_zone_name\` TO 'glpi'@'%'; FLUSH PRIVILEGES;" glpi-db-install: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure env_file: ./.env volumes: @@ -35,7 +35,7 @@ services: - /usr/local/bin/glpi-db-install.sh glpi-verify-dir: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -48,7 +48,7 @@ services: - /usr/local/bin/glpi-verify-dir.sh glpi-db-configure: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -60,7 +60,7 @@ services: command: - /usr/local/bin/glpi-db-configure.sh glpi-cache-configure: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: on-failure volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -73,7 +73,7 @@ services: - /usr/local/bin/glpi-cache-configure.sh php: - image: eftechcombr/glpi:php-fpm-11.0.7 + image: eftechcombr/glpi:php-fpm-11.0.8 restart: unless-stopped volumes: - glpi-marketplace:/var/www/html/marketplace:rw @@ -89,7 +89,7 @@ services: - "9000:9000" nginx: - image: eftechcombr/glpi:nginx-11.0.7 + image: eftechcombr/glpi:nginx-11.0.8 restart: unless-stopped ports: - "8080:8080" diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile index 2f7cff4..59ec210 100644 --- a/docker/nginx/Dockerfile +++ b/docker/nginx/Dockerfile @@ -1,4 +1,4 @@ -FROM eftechcombr/glpi:php-fpm-11.0.7 as BUILD +FROM eftechcombr/glpi:php-fpm-11.0.8 as BUILD # FROM nginxinc/nginx-unprivileged:1.27.5-alpine3.21-slim diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile index 548641f..5eebb7b 100644 --- a/docker/php/Dockerfile +++ b/docker/php/Dockerfile @@ -1,6 +1,6 @@ FROM eftechcombr/glpi:base -ENV VERSION=11.0.7 +ENV VERSION=11.0.8 ENV GLPI_LANG=en_US ENV CACHE_DSN=redis://redis:6379/ ENV MARIADB_HOST=mariadb-glpi diff --git a/kubernetes/glpi/Chart.yaml b/kubernetes/glpi/Chart.yaml index d0ea2b1..a85be46 100644 --- a/kubernetes/glpi/Chart.yaml +++ b/kubernetes/glpi/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: glpi description: GLPI Helm Chart - IT Asset Management and Service Desk type: application -version: 11.0.7 -appVersion: "11.0.7" +version: 11.0.8 +appVersion: "11.0.8" # Artifact Hub Metadata home: https://github.com/eftechcombr/glpi @@ -32,5 +32,31 @@ annotations: - name: support url: https://github.com/eftechcombr/glpi/issues artifacthub.io/changes: | + - kind: fixed + description: "Fix CronJob YAML indentation bug preventing deployment" + - kind: fixed + description: "Fix Ingress backend service name to match nginx service" + - kind: changed + description: "StatefulSet now uses volumeClaimTemplates for multi-replica support" + - kind: changed + description: "Use app.kubernetes.io/component labels consistently across all templates" - kind: added - description: "Initial release of GLPI 11.0.7 Helm Chart" + description: "ServiceAccount template with imagePullSecrets and scheduling values" + - kind: added + description: "External database support via externalDatabase config" + - kind: changed + description: "Added security contexts and resource limits to init containers" + - kind: changed + description: "Redis now has liveness/readiness probes and security context defaults" + - kind: changed + description: "MariaDB and Redis now run with non-root security contexts by default" + - kind: fixed + description: "Fix GLPI_DOC_DIR pointing to /var/www/html instead of var dir" + - kind: changed + description: "StatefulSet anti-affinity changed to requiredDuringScheduling" + - kind: fixed + description: "Remove deprecated alpha API annotation and status subresource fields" + - kind: fixed + description: "Fix terminationGracePeriodSeconds moved to pod template spec" + - kind: fixed + description: "Fix helm-publish workflow skipping publish on release events" diff --git a/kubernetes/glpi/README.md b/kubernetes/glpi/README.md index f7cacc8..5edb477 100644 --- a/kubernetes/glpi/README.md +++ b/kubernetes/glpi/README.md @@ -4,7 +4,7 @@ ## Prerequisites -- Kubernetes 1.19+ +- Kubernetes 1.21+ - Helm 3.2.0+ - PV provisioner support in the underlying infrastructure @@ -18,22 +18,185 @@ helm install my-glpi eftechcombr/glpi ## Configuration -The following table lists the configurable parameters of the GLPI chart and their default values. +The following table lists the configurable parameters of the GLPI chart and their default values. For a complete reference, see `values.yaml`. + +### Global Settings + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `global.namespace` | Namespace for deployment (uses release namespace if empty) | `""` | +| `global.createNamespace` | Create the Namespace resource | `false` | + +### GLPI Application | Parameter | Description | Default | |-----------|-------------|---------| +| `glpi.version` | GLPI version to deploy | `"11.0.8"` | | `glpi.language` | Default language for GLPI | `en_US` | + +### PHP-FPM Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| | `glpi.phpfpm.image.repository` | PHP-FPM image repository | `eftechcombr/glpi` | -| `glpi.phpfpm.image.tag` | PHP-FPM image tag | `php-fpm-11.0.7` | +| `glpi.phpfpm.image.tag` | PHP-FPM image tag | `php-fpm-11.0.8` | +| `glpi.phpfpm.image.pullPolicy` | PHP-FPM image pull policy | `IfNotPresent` | | `glpi.phpfpm.replicaCount` | Number of PHP-FPM pods | `1` | +| `glpi.phpfpm.resources.limits.cpu` | PHP-FPM container CPU limit | `1000m` | +| `glpi.phpfpm.resources.limits.memory` | PHP-FPM container memory limit | `512Mi` | +| `glpi.phpfpm.resources.requests.cpu` | PHP-FPM container CPU request | `250m` | +| `glpi.phpfpm.resources.requests.memory` | PHP-FPM container memory request | `256Mi` | +| `glpi.phpfpm.livenessProbe.enabled` | Enable PHP-FPM liveness probe | `true` | +| `glpi.phpfpm.readinessProbe.enabled` | Enable PHP-FPM readiness probe | `true` | + +### Nginx Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| | `glpi.nginx.image.repository` | Nginx image repository | `eftechcombr/glpi` | -| `glpi.nginx.image.tag` | Nginx image tag | `nginx-11.0.7` | -| `glpi.persistence.files.enabled` | Enable persistence for GLPI data | `true` | -| `glpi.persistence.files.size` | Size of data volume | `10Gi` | +| `glpi.nginx.image.tag` | Nginx image tag | `nginx-11.0.8` | +| `glpi.nginx.image.pullPolicy` | Nginx image pull policy | `IfNotPresent` | +| `glpi.nginx.replicaCount` | Number of Nginx pods | `1` | +| `glpi.nginx.resources.limits.cpu` | Nginx container CPU limit | `500m` | +| `glpi.nginx.resources.limits.memory` | Nginx container memory limit | `256Mi` | +| `glpi.nginx.resources.requests.cpu` | Nginx container CPU request | `100m` | +| `glpi.nginx.resources.requests.memory` | Nginx container memory request | `128Mi` | +| `glpi.nginx.livenessProbe.enabled` | Enable Nginx liveness probe | `true` | +| `glpi.nginx.readinessProbe.enabled` | Enable Nginx readiness probe | `true` | +| `glpi.nginx.service.type` | Nginx service type | `ClusterIP` | +| `glpi.nginx.service.port` | Nginx service port | `80` | +| `glpi.nginx.service.targetPort` | Nginx container target port | `8080` | + +### GLPI Paths + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `glpi.paths.marketplace` | Marketplace plugins directory | `/var/www/html/marketplace` | +| `glpi.paths.var` | Variable data directory | `/var/lib/glpi` | +| `glpi.paths.config` | Configuration directory | `/etc/glpi/config` | + +### Persistence + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `glpi.persistence.files.enabled` | Enable persistence for GLPI files | `true` | +| `glpi.persistence.files.storageClass` | Files volume storage class | `""` | +| `glpi.persistence.files.accessMode` | Files volume access mode | `ReadWriteOnce` | +| `glpi.persistence.files.size` | Files volume size | `10Gi` | +| `glpi.persistence.marketplace.enabled` | Enable persistence for marketplace | `true` | +| `glpi.persistence.marketplace.size` | Marketplace volume size | `2Gi` | +| `glpi.persistence.etc.enabled` | Enable persistence for config | `true` | +| `glpi.persistence.etc.size` | Config volume size | `50Mi` | + +### Init Jobs + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `glpi.jobs.verifyDir.enabled` | Create required GLPI directories | `true` | +| `glpi.jobs.dbInstall.enabled` | Install GLPI database schema (fresh installs) | `true` | +| `glpi.jobs.dbUpgrade.enabled` | Upgrade GLPI database schema (upgrades) | `true` | +| `glpi.jobs.dbConfigure.enabled` | Configure GLPI database connection | `true` | +| `glpi.jobs.cacheConfigure.enabled` | Configure GLPI Redis cache settings | `true` | + +### CronJob + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `glpi.cronjob.enabled` | Enable scheduled maintenance cronjob | `true` | +| `glpi.cronjob.schedule` | CronJob schedule (cron format) | `"*/2 * * * *"` | + +### GLPI Security Context + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `glpi.podSecurityContext.fsGroup` | Pod-level fsGroup (www-data) | `82` | +| `glpi.securityContext.runAsNonRoot` | Run as non-root user | `true` | +| `glpi.securityContext.runAsUser` | User ID (www-data) | `82` | +| `glpi.securityContext.capabilities.drop` | Dropped capabilities | `["ALL"]` | + +### MariaDB Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| | `mariadb.enabled` | Deploy internal MariaDB | `true` | +| `mariadb.image.repository` | MariaDB image repository | `mariadb` | +| `mariadb.image.tag` | MariaDB image tag | `"11.4"` | +| `mariadb.image.pullPolicy` | MariaDB image pull policy | `IfNotPresent` | +| `mariadb.replicaCount` | Number of MariaDB replicas | `1` | | `mariadb.auth.rootPassword` | MariaDB root password | `glpi` | +| `mariadb.auth.database` | Database name for GLPI | `glpi` | +| `mariadb.auth.username` | Username for GLPI | `glpi` | +| `mariadb.auth.password` | Password for GLPI user | `glpi` | +| `mariadb.primary.resources.limits.cpu` | MariaDB CPU limit | `1000m` | +| `mariadb.primary.resources.limits.memory` | MariaDB memory limit | `2Gi` | +| `mariadb.primary.resources.requests.cpu` | MariaDB CPU request | `250m` | +| `mariadb.primary.resources.requests.memory` | MariaDB memory request | `256Mi` | +| `mariadb.persistence.enabled` | Enable persistence for MariaDB | `true` | +| `mariadb.persistence.size` | MariaDB volume size | `10Gi` | +| `mariadb.service.type` | MariaDB service type | `ClusterIP` | +| `mariadb.service.port` | MariaDB service port | `3306` | +| `mariadb.podSecurityContext.fsGroup` | Pod-level fsGroup | `1001` | +| `mariadb.securityContext.runAsNonRoot` | Run as non-root | `true` | +| `mariadb.securityContext.runAsUser` | User ID | `1001` | + +### Redis Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| | `redis.enabled` | Deploy internal Redis for caching | `true` | -| `ingress.enabled` | Enable ingress controller | `false` | +| `redis.image.repository` | Redis image repository | `redis` | +| `redis.image.tag` | Redis image tag | `"7.0-alpine"` | +| `redis.image.pullPolicy` | Redis image pull policy | `IfNotPresent` | +| `redis.replicaCount` | Number of Redis replicas | `1` | +| `redis.resources.limits.cpu` | Redis CPU limit | `500m` | +| `redis.resources.limits.memory` | Redis memory limit | `256Mi` | +| `redis.resources.requests.cpu` | Redis CPU request | `100m` | +| `redis.resources.requests.memory` | Redis memory request | `128Mi` | +| `redis.service.type` | Redis service type | `ClusterIP` | +| `redis.service.port` | Redis service port | `6379` | +| `redis.podSecurityContext.fsGroup` | Pod-level fsGroup | `1001` | +| `redis.securityContext.runAsNonRoot` | Run as non-root | `true` | +| `redis.securityContext.runAsUser` | User ID | `999` | + +### Ingress Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `ingress.enabled` | Enable ingress | `false` | +| `ingress.className` | Ingress class name | `""` | +| `ingress.annotations` | Ingress annotations | `{}` | +| `ingress.hosts` | Ingress host rules | `[{host: glpi.example.local, paths: [{path: /, pathType: Prefix}]}]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | + +### External Database + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `externalDatabase.host` | External database hostname | `""` | +| `externalDatabase.database` | External database name | `""` | +| `externalDatabase.username` | External database username | `""` | +| `externalDatabase.password` | External database password | `""` | + +### Service Account + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `serviceAccount.create` | Create service account | `true` | +| `serviceAccount.automount` | Automount API credentials | `true` | +| `serviceAccount.name` | Service account name | `""` | + +### Other + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `imagePullSecrets` | Image pull secrets | `[]` | +| `nameOverride` | Override chart name | `""` | +| `fullnameOverride` | Override full name | `""` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Pod labels | `{}` | +| `nodeSelector` | Node selector for pod assignment | `{}` | +| `tolerations` | Pod tolerations | `[]` | +| `affinity` | Pod affinity rules | `{}` | ## Persistence @@ -46,7 +209,43 @@ If using multiple replicas for PHP-FPM, ensure your StorageClass supports `ReadW ## Database -By default, the chart deploys MariaDB. For production, it is recommended to use an external database by setting `mariadb.enabled: false` and providing connection details in `glpi.jobs.dbConfigure`. +By default, the chart deploys MariaDB. For production, it is recommended to use an external database by setting `mariadb.enabled: false` and providing connection details via the `externalDatabase` section: + +```yaml +mariadb: + enabled: false + +externalDatabase: + host: my-db-host.example.com + database: glpi + username: glpi + password: mySecurePassword +``` + +## Initialization Jobs + +The chart includes Helm hook jobs that run during install/upgrade: + +| Job | Hook | Weight | Description | +|-----|------|--------|-------------| +| `glpi-verify-dir` | post-install, post-upgrade | 5 | Create required GLPI directories | +| `mariadb-timezone` | post-install, post-upgrade | 7 | Populate MariaDB timezone data | +| `glpi-db-install` | post-install | 10 | Install GLPI database schema (fresh installs) | +| `glpi-db-upgrade` | post-upgrade | 10 | Upgrade GLPI database schema (upgrades) | +| `glpi-db-configure` | post-install, post-upgrade | 20 | Configure GLPI database connection | +| `glpi-cache-configure` | post-install, post-upgrade | 30 | Configure GLPI Redis cache settings | + +Jobs can be individually disabled via `glpi.jobs..enabled: false`. + +## Security Contexts + +All components are configured with secure defaults: +- **GLPI (PHP-FPM/Nginx)**: Runs as non-root user `www-data` (uid 82), drops all capabilities +- **MariaDB**: Runs as non-root user (uid 1001) with `fsGroup: 1001` +- **Redis**: Runs as non-root user (uid 999) with `fsGroup: 1001` + +--- --- + *Developed by [EFTech](https://eftech.com.br)* diff --git a/kubernetes/glpi/templates/_helpers.tpl b/kubernetes/glpi/templates/_helpers.tpl index 95ee5f7..2a759cd 100644 --- a/kubernetes/glpi/templates/_helpers.tpl +++ b/kubernetes/glpi/templates/_helpers.tpl @@ -52,10 +52,17 @@ app.kubernetes.io/instance: {{ .Release.Name }} Return the proper namespace */}} {{- define "glpi.namespace" -}} -{{- if .Values.global }} {{- .Values.global.namespace | default .Release.Namespace }} +{{- end }} + +{{/* +Return the service account name +*/}} +{{- define "glpi.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- .Values.serviceAccount.name | default (include "glpi.fullname" .) }} {{- else }} -{{- .Release.Namespace }} +{{- .Values.serviceAccount.name | default "default" }} {{- end }} {{- end }} diff --git a/kubernetes/glpi/templates/glpi-configmap.yaml b/kubernetes/glpi/templates/glpi-configmap.yaml index e3d527f..4232958 100644 --- a/kubernetes/glpi/templates/glpi-configmap.yaml +++ b/kubernetes/glpi/templates/glpi-configmap.yaml @@ -1,16 +1,16 @@ apiVersion: v1 kind: ConfigMap -metadata: +metadata: name: glpi-config namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} -data: +data: GLPI_LANG: {{ .Values.glpi.language | quote }} VERSION: {{ .Values.glpi.version | quote }} GLPI_MARKETPLACE_DIR: {{ .Values.glpi.paths.marketplace }} GLPI_VAR_DIR: {{ .Values.glpi.paths.var }} - GLPI_DOC_DIR: {{ .Values.glpi.paths.var }} + GLPI_DOC_DIR: /var/www/html GLPI_CRON_DIR: {{ .Values.glpi.paths.var }}/_cron GLPI_DUMP_DIR: {{ .Values.glpi.paths.var }}/_dumps GLPI_GRAPH_DIR: {{ .Values.glpi.paths.var }}/_graphs @@ -18,18 +18,23 @@ data: GLPI_LOG_DIR: {{ .Values.glpi.paths.var }}/_log GLPI_PICTURE_DIR: {{ .Values.glpi.paths.var }}/_pictures GLPI_PLUGIN_DOC_DIR: {{ .Values.glpi.paths.var }}/_plugins - GLPI_RSS_DIR: {{ .Values.glpi.paths.var }}/_rss + GLPI_RSS_DIR: {{ .Values.glpi.paths.var }}/_rss GLPI_SESSION_DIR: {{ .Values.glpi.paths.var }}/_sessions GLPI_TMP_DIR: {{ .Values.glpi.paths.var }}/_tmp GLPI_UPLOAD_DIR: {{ .Values.glpi.paths.var }}/_uploads GLPI_CACHE_DIR: {{ .Values.glpi.paths.var }}/_cache GLPI_CONFIG_DIR: {{ .Values.glpi.paths.config }} + {{- if .Values.mariadb.enabled }} MARIADB_HOST: "mariadb-headless.{{ include "glpi.namespace" . }}.svc.cluster.local" MARIADB_PORT: {{ .Values.mariadb.service.port | quote }} + {{- else }} + MARIADB_HOST: {{ .Values.externalDatabase.host | quote }} + MARIADB_PORT: {{ .Values.externalDatabase.port | quote }} + {{- end }} ---- +--- apiVersion: v1 kind: ConfigMap metadata: @@ -37,28 +42,27 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} - name: nginx-conf + name: nginx-conf data: default.conf: |- server { listen 8080; listen [::]:8080; - + server_name glpi.localhost; - + root /var/www/html/public; - + location / { try_files $uri /index.php$is_args$args; } - + location ~ ^/index\.php$ { - # the following line needs to be adapted, as it changes depending on OS distributions and PHP versions fastcgi_pass php-fpm.{{ include "glpi.namespace" . }}.svc.cluster.local:9000; - + fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; - + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } diff --git a/kubernetes/glpi/templates/glpi-cronjob.yaml b/kubernetes/glpi/templates/glpi-cronjob.yaml index 6e27b5e..f8e4132 100644 --- a/kubernetes/glpi/templates/glpi-cronjob.yaml +++ b/kubernetes/glpi/templates/glpi-cronjob.yaml @@ -1,4 +1,4 @@ -{{- if not (hasKey .Values.glpi.cronjob "enabled") | or .Values.glpi.cronjob.enabled }} +{{- if .Values.glpi.cronjob.enabled }} apiVersion: batch/v1 kind: CronJob metadata: @@ -15,35 +15,60 @@ spec: spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 12 }} + {{- end }} containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: base - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - command: - - php - - front/cron.php - volumeMounts: - - name: files - mountPath: /var/lib/glpi - - name: marketplace - mountPath: /var/www/html/marketplace - - name: etc - mountPath: /etc/glpi + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: base + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 16 }} + {{- end }} + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + command: + - php + - front/cron.php + volumeMounts: + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + - name: etc + mountPath: /etc/glpi + resources: + {{- toYaml .Values.glpi.phpfpm.resources | nindent 16 }} volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + - name: etc + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files + - name: marketplace + persistentVolumeClaim: + claimName: glpi-marketplace restartPolicy: OnFailure {{- end }} - diff --git a/kubernetes/glpi/templates/glpi-deployment.yaml b/kubernetes/glpi/templates/glpi-deployment.yaml index 04a8646..a036973 100644 --- a/kubernetes/glpi/templates/glpi-deployment.yaml +++ b/kubernetes/glpi/templates/glpi-deployment.yaml @@ -1,73 +1,105 @@ ---- +--- apiVersion: apps/v1 kind: Deployment metadata: name: php-fpm labels: {{- include "glpi.labels" . | nindent 4 }} - app: php-fpm + app.kubernetes.io/component: php-fpm namespace: {{ include "glpi.namespace" . }} spec: replicas: {{ .Values.glpi.phpfpm.replicaCount }} selector: matchLabels: {{- include "glpi.selectorLabels" . | nindent 6 }} - app: php-fpm + app.kubernetes.io/component: php-fpm template: metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} labels: {{- include "glpi.selectorLabels" . | nindent 8 }} - app: php-fpm + app.kubernetes.io/component: php-fpm + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: php - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - ports: - - containerPort: 9000 - name: fpm - volumeMounts: - - name: files - mountPath: /var/lib/glpi - - name: etc - mountPath: /etc/glpi + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: php + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + ports: + - containerPort: 9000 + name: fpm + volumeMounts: + - name: files + mountPath: /var/lib/glpi + - name: etc + mountPath: /etc/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + {{- if .Values.glpi.phpfpm.livenessProbe.enabled }} + livenessProbe: + tcpSocket: + port: {{ .Values.glpi.phpfpm.livenessProbe.tcpSocket.port }} + initialDelaySeconds: {{ .Values.glpi.phpfpm.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.glpi.phpfpm.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.glpi.phpfpm.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.glpi.phpfpm.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.glpi.phpfpm.readinessProbe.enabled }} + readinessProbe: + tcpSocket: + port: {{ .Values.glpi.phpfpm.readinessProbe.tcpSocket.port }} + initialDelaySeconds: {{ .Values.glpi.phpfpm.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.glpi.phpfpm.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.glpi.phpfpm.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.glpi.phpfpm.readinessProbe.failureThreshold }} + {{- end }} + resources: + {{- toYaml .Values.glpi.phpfpm.resources | nindent 12 }} + volumes: + - name: etc + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files - name: marketplace - mountPath: /var/www/html/marketplace - {{- if .Values.glpi.phpfpm.livenessProbe.enabled }} - livenessProbe: - tcpSocket: - port: {{ .Values.glpi.phpfpm.livenessProbe.tcpSocket.port }} - initialDelaySeconds: {{ .Values.glpi.phpfpm.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.glpi.phpfpm.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.glpi.phpfpm.livenessProbe.timeoutSeconds }} - failureThreshold: {{ .Values.glpi.phpfpm.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.glpi.phpfpm.readinessProbe.enabled }} - readinessProbe: - tcpSocket: - port: {{ .Values.glpi.phpfpm.readinessProbe.tcpSocket.port }} - initialDelaySeconds: {{ .Values.glpi.phpfpm.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.glpi.phpfpm.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.glpi.phpfpm.readinessProbe.timeoutSeconds }} - failureThreshold: {{ .Values.glpi.phpfpm.readinessProbe.failureThreshold }} - {{- end }} - resources: - {{- toYaml .Values.glpi.phpfpm.resources | nindent 10 }} - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + persistentVolumeClaim: + claimName: glpi-marketplace --- @@ -77,113 +109,144 @@ metadata: name: nginx labels: {{- include "glpi.labels" . | nindent 4 }} - app: nginx + app.kubernetes.io/component: nginx namespace: {{ include "glpi.namespace" . }} spec: replicas: {{ .Values.glpi.nginx.replicaCount }} selector: matchLabels: {{- include "glpi.selectorLabels" . | nindent 6 }} - app: nginx + app.kubernetes.io/component: nginx template: metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} labels: {{- include "glpi.selectorLabels" . | nindent 8 }} - app: nginx + app.kubernetes.io/component: nginx + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - - image: {{ include "glpi.nginx.image" . }} - imagePullPolicy: {{ .Values.glpi.nginx.image.pullPolicy }} - name: nginx - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - ports: - - containerPort: 8080 - name: http - volumeMounts: - - name: files - mountPath: /var/lib/glpi - - name: marketplace - mountPath: /var/www/html/marketplace + - image: {{ include "glpi.nginx.image" . }} + imagePullPolicy: {{ .Values.glpi.nginx.image.pullPolicy }} + name: nginx + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + ports: + - containerPort: 8080 + name: http + volumeMounts: + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + - name: etc + mountPath: /etc/glpi + - name: nginx-conf + mountPath: /etc/nginx/conf.d + {{- if .Values.glpi.nginx.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.glpi.nginx.livenessProbe.httpGet.path }} + port: {{ .Values.glpi.nginx.livenessProbe.httpGet.port }} + initialDelaySeconds: {{ .Values.glpi.nginx.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.glpi.nginx.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.glpi.nginx.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.glpi.nginx.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.glpi.nginx.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.glpi.nginx.readinessProbe.httpGet.path }} + port: {{ .Values.glpi.nginx.readinessProbe.httpGet.port }} + initialDelaySeconds: {{ .Values.glpi.nginx.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.glpi.nginx.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.glpi.nginx.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.glpi.nginx.readinessProbe.failureThreshold }} + {{- end }} + resources: + {{- toYaml .Values.glpi.nginx.resources | nindent 12 }} + volumes: - name: etc - mountPath: /etc/glpi + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files + - name: marketplace + persistentVolumeClaim: + claimName: glpi-marketplace - name: nginx-conf - mountPath: /etc/nginx/conf.d - {{- if .Values.glpi.nginx.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: {{ .Values.glpi.nginx.livenessProbe.httpGet.path }} - port: {{ .Values.glpi.nginx.livenessProbe.httpGet.port }} - initialDelaySeconds: {{ .Values.glpi.nginx.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.glpi.nginx.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.glpi.nginx.livenessProbe.timeoutSeconds }} - failureThreshold: {{ .Values.glpi.nginx.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.glpi.nginx.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: {{ .Values.glpi.nginx.readinessProbe.httpGet.path }} - port: {{ .Values.glpi.nginx.readinessProbe.httpGet.port }} - initialDelaySeconds: {{ .Values.glpi.nginx.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.glpi.nginx.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.glpi.nginx.readinessProbe.timeoutSeconds }} - failureThreshold: {{ .Values.glpi.nginx.readinessProbe.failureThreshold }} - {{- end }} - resources: - {{- toYaml .Values.glpi.nginx.resources | nindent 10 }} - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace - - name: nginx-conf - configMap: - defaultMode: 420 - name: nginx-conf + configMap: + defaultMode: 420 + name: nginx-conf ---- +--- apiVersion: v1 kind: Service -metadata: +metadata: name: php-fpm labels: {{- include "glpi.labels" . | nindent 4 }} - app: php-fpm + app.kubernetes.io/component: php-fpm namespace: {{ include "glpi.namespace" . }} spec: - ports: + type: ClusterIP + ports: - port: 9000 targetPort: 9000 selector: {{- include "glpi.selectorLabels" . | nindent 4 }} - app: php-fpm + app.kubernetes.io/component: php-fpm ---- +--- apiVersion: v1 kind: Service -metadata: +metadata: name: nginx labels: {{- include "glpi.labels" . | nindent 4 }} - app: nginx + app.kubernetes.io/component: nginx namespace: {{ include "glpi.namespace" . }} spec: type: {{ .Values.glpi.nginx.service.type }} - ports: + ports: - port: {{ .Values.glpi.nginx.service.port }} targetPort: {{ .Values.glpi.nginx.service.targetPort }} selector: {{- include "glpi.selectorLabels" . | nindent 4 }} - app: nginx - - + app.kubernetes.io/component: nginx diff --git a/kubernetes/glpi/templates/glpi-ingress.yaml b/kubernetes/glpi/templates/glpi-ingress.yaml index 968b884..56c66fe 100644 --- a/kubernetes/glpi/templates/glpi-ingress.yaml +++ b/kubernetes/glpi/templates/glpi-ingress.yaml @@ -34,7 +34,7 @@ spec: pathType: {{ .pathType }} backend: service: - name: {{ include "glpi.fullname" $ }}-nginx + name: nginx port: number: {{ $.Values.glpi.nginx.service.port }} {{- end }} diff --git a/kubernetes/glpi/templates/glpi-job.yaml b/kubernetes/glpi/templates/glpi-job.yaml index d9b042b..cd0dc84 100644 --- a/kubernetes/glpi/templates/glpi-job.yaml +++ b/kubernetes/glpi/templates/glpi-job.yaml @@ -7,48 +7,65 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: job + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "5" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: base - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - command: - - sh - - -c - - "/usr/local/bin/glpi-verify-dir.sh" - volumeMounts: - - name: files - mountPath: /var/lib/glpi + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: base + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + command: + - sh + - -c + - "/usr/local/bin/glpi-verify-dir.sh" + volumeMounts: + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + - name: etc + mountPath: /etc/glpi + volumes: + - name: etc + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files - name: marketplace - mountPath: /var/www/html/marketplace - - name: etc - mountPath: /etc/glpi - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + persistentVolumeClaim: + claimName: glpi-marketplace restartPolicy: OnFailure parallelism: 1 completions: 1 -status: {} {{- end }} {{- if .Values.glpi.jobs.dbInstall.enabled }} ---- +--- apiVersion: batch/v1 kind: Job metadata: @@ -56,48 +73,88 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: job + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + - name: wait-for-mariadb + image: busybox:1.36.1 + securityContext: + runAsNonRoot: true + runAsUser: 65534 + capabilities: + drop: + - ALL + command: + - sh + - -c + - until nc -z $MARIADB_HOST $MARIADB_PORT; do sleep 2; done + envFrom: + - configMapRef: + name: glpi-config + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 50m + memory: 32Mi containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: base - command: - - sh - - -c - - "/usr/local/bin/glpi-db-install.sh" - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - volumeMounts: - - name: files - mountPath: /var/lib/glpi - - name: marketplace - mountPath: /var/www/html/marketplace + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: base + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + command: + - sh + - -c + - "/usr/local/bin/glpi-db-install.sh" + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + volumeMounts: + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + - name: etc + mountPath: /etc/glpi + volumes: - name: etc - mountPath: /etc/glpi - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files + - name: marketplace + persistentVolumeClaim: + claimName: glpi-marketplace restartPolicy: OnFailure parallelism: 1 completions: 1 -status: {} {{- end }} {{- if .Values.glpi.jobs.dbUpgrade.enabled }} ---- +--- apiVersion: batch/v1 kind: Job metadata: @@ -105,48 +162,88 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: job + annotations: + "helm.sh/hook": post-upgrade + "helm.sh/hook-weight": "10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + - name: wait-for-mariadb + image: busybox:1.36.1 + securityContext: + runAsNonRoot: true + runAsUser: 65534 + capabilities: + drop: + - ALL + command: + - sh + - -c + - until nc -z $MARIADB_HOST $MARIADB_PORT; do sleep 2; done + envFrom: + - configMapRef: + name: glpi-config + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 50m + memory: 32Mi containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: base - command: - - sh - - -c - - "/usr/local/bin/glpi-db-upgrade.sh" - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - volumeMounts: - - name: files - mountPath: /var/lib/glpi - - name: marketplace - mountPath: /var/www/html/marketplace + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: base + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + command: + - sh + - -c + - "/usr/local/bin/glpi-db-upgrade.sh" + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + volumeMounts: + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + - name: etc + mountPath: /etc/glpi + volumes: - name: etc - mountPath: /etc/glpi - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files + - name: marketplace + persistentVolumeClaim: + claimName: glpi-marketplace restartPolicy: OnFailure parallelism: 1 completions: 1 -status: {} {{- end }} {{- if .Values.glpi.jobs.dbConfigure.enabled }} ---- +--- apiVersion: batch/v1 kind: Job metadata: @@ -154,48 +251,88 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: job + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "20" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + - name: wait-for-mariadb + image: busybox:1.36.1 + securityContext: + runAsNonRoot: true + runAsUser: 65534 + capabilities: + drop: + - ALL + command: + - sh + - -c + - until nc -z $MARIADB_HOST $MARIADB_PORT; do sleep 2; done + envFrom: + - configMapRef: + name: glpi-config + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 50m + memory: 32Mi containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: base - command: - - sh - - -c - - "/usr/local/bin/glpi-db-configure.sh" - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - volumeMounts: + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: base + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + command: + - sh + - -c + - "/usr/local/bin/glpi-db-configure.sh" + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + volumeMounts: + - name: etc + mountPath: /etc/glpi + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + volumes: - name: etc - mountPath: /etc/glpi - - name: files - mountPath: /var/lib/glpi + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files - name: marketplace - mountPath: /var/www/html/marketplace - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + persistentVolumeClaim: + claimName: glpi-marketplace restartPolicy: OnFailure parallelism: 1 completions: 1 -status: {} {{- end }} {{- if .Values.glpi.jobs.cacheConfigure.enabled }} ---- +--- apiVersion: batch/v1 kind: Job metadata: @@ -203,41 +340,58 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: job + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "30" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.glpi.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - - image: {{ include "glpi.phpfpm.image" . }} - imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} - name: base - command: - - sh - - -c - - "/usr/local/bin/glpi-cache-configure.sh" - envFrom: - - configMapRef: - name: glpi-config - - secretRef: - name: glpi-secret - volumeMounts: + - image: {{ include "glpi.phpfpm.image" . }} + imagePullPolicy: {{ .Values.glpi.phpfpm.image.pullPolicy }} + name: base + {{- with .Values.glpi.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + command: + - sh + - -c + - "/usr/local/bin/glpi-cache-configure.sh" + envFrom: + - configMapRef: + name: glpi-config + - secretRef: + name: glpi-secret + volumeMounts: + - name: etc + mountPath: /etc/glpi + - name: files + mountPath: /var/lib/glpi + - name: marketplace + mountPath: /var/www/html/marketplace + volumes: - name: etc - mountPath: /etc/glpi - - name: files - mountPath: /var/lib/glpi + persistentVolumeClaim: + claimName: glpi-etc + - name: files + persistentVolumeClaim: + claimName: glpi-files - name: marketplace - mountPath: /var/www/html/marketplace - volumes: - - name: etc - persistentVolumeClaim: - claimName: glpi-etc - - name: files - persistentVolumeClaim: - claimName: glpi-files - - name: marketplace - persistentVolumeClaim: - claimName: glpi-marketplace + persistentVolumeClaim: + claimName: glpi-marketplace restartPolicy: OnFailure parallelism: 1 completions: 1 -status: {} {{- end }} diff --git a/kubernetes/glpi/templates/glpi-secret.yaml b/kubernetes/glpi/templates/glpi-secret.yaml index f8a09ac..033805a 100644 --- a/kubernetes/glpi/templates/glpi-secret.yaml +++ b/kubernetes/glpi/templates/glpi-secret.yaml @@ -7,7 +7,12 @@ metadata: {{- include "glpi.labels" . | nindent 4 }} type: Opaque data: + {{- if .Values.mariadb.enabled }} MARIADB_DATABASE: {{ .Values.mariadb.auth.database | b64enc | quote }} MARIADB_USER: {{ .Values.mariadb.auth.username | b64enc | quote }} MARIADB_PASSWORD: {{ .Values.mariadb.auth.password | b64enc | quote }} - + {{- else if .Values.externalDatabase }} + MARIADB_DATABASE: {{ .Values.externalDatabase.database | b64enc | quote }} + MARIADB_USER: {{ .Values.externalDatabase.username | b64enc | quote }} + MARIADB_PASSWORD: {{ .Values.externalDatabase.password | b64enc | quote }} + {{- end }} diff --git a/kubernetes/glpi/templates/mariadb-configmap.yaml b/kubernetes/glpi/templates/mariadb-configmap.yaml index 71b49bd..5051908 100644 --- a/kubernetes/glpi/templates/mariadb-configmap.yaml +++ b/kubernetes/glpi/templates/mariadb-configmap.yaml @@ -1,12 +1,12 @@ {{- if .Values.mariadb.enabled }} apiVersion: v1 kind: ConfigMap -metadata: +metadata: name: mariadb-glpi-config namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} -data: +data: MARIADB_HOST: "mariadb-headless.{{ include "glpi.namespace" . }}.svc.cluster.local" MARIADB_PORT: {{ .Values.mariadb.service.port | quote }} {{- end }} diff --git a/kubernetes/glpi/templates/mariadb-job.yaml b/kubernetes/glpi/templates/mariadb-job.yaml index 840cf0f..fda2cb4 100644 --- a/kubernetes/glpi/templates/mariadb-job.yaml +++ b/kubernetes/glpi/templates/mariadb-job.yaml @@ -6,25 +6,66 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: job + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "7" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded spec: template: spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.mariadb.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + - name: wait-for-mariadb + image: busybox:1.36.1 + securityContext: + runAsNonRoot: true + runAsUser: 65534 + capabilities: + drop: + - ALL + command: + - sh + - -c + - until nc -z $MARIADB_HOST $MARIADB_PORT; do sleep 2; done + envFrom: + - configMapRef: + name: mariadb-glpi-config + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 50m + memory: 32Mi containers: - - image: {{ include "glpi.mariadb.image" . }} - imagePullPolicy: {{ .Values.mariadb.image.pullPolicy }} - name: base - command: - - sh - - -c - - "mariadb --host=${MARIADB_HOST} -u root -p${MARIADB_ROOT_PASSWORD} -e \"GRANT SELECT ON mysql.time_zone_name TO 'glpi'@'%'; FLUSH PRIVILEGES;\"" - envFrom: - - secretRef: - name: mariadb-glpi-secret - - configMapRef: - name: mariadb-glpi-config + - image: {{ include "glpi.mariadb.image" . }} + imagePullPolicy: {{ .Values.mariadb.image.pullPolicy }} + name: base + {{- with .Values.mariadb.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + command: + - sh + - -c + - | + mariadb --host=${MARIADB_HOST} -u root -p${MARIADB_ROOT_PASSWORD} \ + -e "GRANT SELECT ON mysql.time_zone_name TO '{{ .Values.mariadb.auth.username }}'@'%'; FLUSH PRIVILEGES;" + envFrom: + - secretRef: + name: mariadb-glpi-secret + - configMapRef: + name: mariadb-glpi-config restartPolicy: OnFailure parallelism: 1 completions: 1 -status: {} {{- end }} - diff --git a/kubernetes/glpi/templates/mariadb-persistentvolumeclaim.yaml b/kubernetes/glpi/templates/mariadb-persistentvolumeclaim.yaml index de2a70c..ce130f5 100644 --- a/kubernetes/glpi/templates/mariadb-persistentvolumeclaim.yaml +++ b/kubernetes/glpi/templates/mariadb-persistentvolumeclaim.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.mariadb.enabled .Values.mariadb.persistence.enabled }} +{{- if .Values.mariadb.enabled }} --- apiVersion: v1 kind: PersistentVolumeClaim @@ -6,7 +6,7 @@ metadata: name: mariadb-data namespace: {{ include "glpi.namespace" . }} labels: -{{ include "glpi.labels" . | indent 4 }} + {{- include "glpi.labels" . | nindent 4 }} spec: {{- if .Values.mariadb.persistence.storageClass }} storageClassName: {{ .Values.mariadb.persistence.storageClass }} diff --git a/kubernetes/glpi/templates/mariadb-secret.yaml b/kubernetes/glpi/templates/mariadb-secret.yaml index 9952030..44ec53e 100644 --- a/kubernetes/glpi/templates/mariadb-secret.yaml +++ b/kubernetes/glpi/templates/mariadb-secret.yaml @@ -1,17 +1,16 @@ {{- if .Values.mariadb.enabled }} ---- +--- apiVersion: v1 kind: Secret type: Opaque -metadata: +metadata: name: mariadb-glpi-secret namespace: {{ include "glpi.namespace" . }} labels: -{{ include "glpi.labels" . | indent 4 }} -data: - MARIADB_ROOT_PASSWORD: {{ .Values.mariadb.auth.rootPassword | b64enc }} - MARIADB_DATABASE: {{ .Values.mariadb.auth.database | b64enc }} - MARIADB_USER: {{ .Values.mariadb.auth.username | b64enc }} - MARIADB_PASSWORD: {{ .Values.mariadb.auth.password | b64enc }} + {{- include "glpi.labels" . | nindent 4 }} +data: + MARIADB_ROOT_PASSWORD: {{ .Values.mariadb.auth.rootPassword | b64enc | quote }} + MARIADB_DATABASE: {{ .Values.mariadb.auth.database | b64enc | quote }} + MARIADB_USER: {{ .Values.mariadb.auth.username | b64enc | quote }} + MARIADB_PASSWORD: {{ .Values.mariadb.auth.password | b64enc | quote }} {{- end }} - diff --git a/kubernetes/glpi/templates/mariadb-statefulset.yaml b/kubernetes/glpi/templates/mariadb-statefulset.yaml index 34a2012..1f7987d 100644 --- a/kubernetes/glpi/templates/mariadb-statefulset.yaml +++ b/kubernetes/glpi/templates/mariadb-statefulset.yaml @@ -4,7 +4,7 @@ apiVersion: apps/v1 kind: StatefulSet metadata: labels: -{{ include "glpi.labels" . | indent 4 }} + {{- include "glpi.labels" . | nindent 4 }} app.kubernetes.io/component: primary name: mariadb namespace: {{ include "glpi.namespace" . }} @@ -14,55 +14,86 @@ spec: revisionHistoryLimit: 10 selector: matchLabels: -{{ include "glpi.selectorLabels" . | indent 6 }} + {{- include "glpi.selectorLabels" . | nindent 6 }} role: primary serviceName: mariadb-headless template: metadata: labels: -{{ include "glpi.labels" . | indent 8 }} + {{- include "glpi.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: primary role: primary name: mariadb spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.mariadb.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} affinity: + {{- if .Values.affinity }} + {{- toYaml .Values.affinity | nindent 8 }} + {{- else }} podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: matchLabels: -{{ include "glpi.selectorLabels" . | indent 18 }} + {{- include "glpi.selectorLabels" . | nindent 18 }} app.kubernetes.io/component: primary namespaces: - - {{ include "glpi.namespace" . }} + - {{ include "glpi.namespace" . }} topologyKey: kubernetes.io/hostname - weight: 1 + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 120 containers: - - image: {{ include "glpi.mariadb.image" . }} - name: mariadb - imagePullPolicy: {{ .Values.mariadb.image.pullPolicy }} - envFrom: - - secretRef: - name: mariadb-glpi-secret - ports: - - containerPort: 3306 + - image: {{ include "glpi.mariadb.image" . }} name: mariadb - protocol: TCP - resources: -{{ toYaml .Values.mariadb.primary.resources | indent 10 }} - volumeMounts: - - name: data - mountPath: "/var/lib/mysql" - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumes: - - name: data - persistentVolumeClaim: - claimName: mariadb-data + {{- with .Values.mariadb.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + imagePullPolicy: {{ .Values.mariadb.image.pullPolicy }} + envFrom: + - secretRef: + name: mariadb-glpi-secret + ports: + - containerPort: 3306 + name: mariadb + protocol: TCP + resources: + {{- toYaml .Values.mariadb.primary.resources | nindent 12 }} + volumeMounts: + - name: data + mountPath: "/var/lib/mysql" + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File updateStrategy: type: OnDelete -status: - replicas: {{ .Values.mariadb.replicaCount }} + volumeClaimTemplates: + - metadata: + name: data + labels: + {{- include "glpi.labels" . | nindent 10 }} + spec: + accessModes: + - {{ .Values.mariadb.persistence.accessMode }} + resources: + requests: + storage: {{ .Values.mariadb.persistence.size }} + {{- if .Values.mariadb.persistence.storageClass }} + storageClassName: {{ .Values.mariadb.persistence.storageClass }} + {{- end }} --- @@ -70,29 +101,27 @@ apiVersion: v1 kind: Service metadata: labels: -{{ include "glpi.labels" . | indent 4 }} - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + {{- include "glpi.labels" . | nindent 4 }} name: mariadb-headless namespace: {{ include "glpi.namespace" . }} spec: clusterIP: None clusterIPs: - - None + - None ipFamilies: - - IPv4 + - IPv4 ipFamilyPolicy: SingleStack ports: - - name: mariadb - port: {{ .Values.mariadb.service.port }} - protocol: TCP - targetPort: {{ .Values.mariadb.service.port }} + - name: mariadb + port: {{ .Values.mariadb.service.port }} + protocol: TCP + targetPort: {{ .Values.mariadb.service.port }} publishNotReadyAddresses: true selector: -{{ include "glpi.selectorLabels" . | indent 4 }} + {{- include "glpi.selectorLabels" . | nindent 4 }} + role: primary sessionAffinity: None type: ClusterIP -status: - loadBalancer: {} --- @@ -100,27 +129,21 @@ apiVersion: v1 kind: Service metadata: labels: -{{ include "glpi.labels" . | indent 4 }} + {{- include "glpi.labels" . | nindent 4 }} name: mariadb namespace: {{ include "glpi.namespace" . }} spec: ipFamilies: - - IPv4 + - IPv4 ipFamilyPolicy: SingleStack ports: - - name: mariadb - port: {{ .Values.mariadb.service.port }} - protocol: TCP - targetPort: {{ .Values.mariadb.service.port }} + - name: mariadb + port: {{ .Values.mariadb.service.port }} + protocol: TCP + targetPort: {{ .Values.mariadb.service.port }} selector: -{{ include "glpi.selectorLabels" . | indent 4 }} + {{- include "glpi.selectorLabels" . | nindent 4 }} role: primary sessionAffinity: None type: {{ .Values.mariadb.service.type }} -status: - loadBalancer: {} {{- end }} - - - - diff --git a/kubernetes/glpi/templates/namespace.yaml b/kubernetes/glpi/templates/namespace.yaml index 92033a5..dab3e57 100644 --- a/kubernetes/glpi/templates/namespace.yaml +++ b/kubernetes/glpi/templates/namespace.yaml @@ -1,8 +1,8 @@ -{{- if .Values.global.namespace }} +{{- if .Values.global.createNamespace }} apiVersion: v1 kind: Namespace metadata: - name: {{ .Values.global.namespace }} + name: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} {{- end }} diff --git a/kubernetes/glpi/templates/redis-deployment.yaml b/kubernetes/glpi/templates/redis-deployment.yaml index b258ce6..b61d8ff 100644 --- a/kubernetes/glpi/templates/redis-deployment.yaml +++ b/kubernetes/glpi/templates/redis-deployment.yaml @@ -6,24 +6,71 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: redis spec: replicas: {{ .Values.redis.replicaCount }} selector: matchLabels: {{- include "glpi.selectorLabels" . | nindent 6 }} - app: redis + app.kubernetes.io/component: redis template: metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} labels: {{- include "glpi.selectorLabels" . | nindent 8 }} - app: redis + app.kubernetes.io/component: redis + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "glpi.serviceAccountName" . }} + {{- with .Values.redis.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - - name: redis - image: {{ include "glpi.redis.image" . }} - imagePullPolicy: {{ .Values.redis.image.pullPolicy }} - ports: - - containerPort: 6379 - resources: - {{- toYaml .Values.redis.resources | nindent 10 }} -{{- end }} \ No newline at end of file + - name: redis + {{- with .Values.redis.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: {{ include "glpi.redis.image" . }} + imagePullPolicy: {{ .Values.redis.image.pullPolicy }} + ports: + - containerPort: 6379 + livenessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + resources: + {{- toYaml .Values.redis.resources | nindent 12 }} +{{- end }} diff --git a/kubernetes/glpi/templates/redis-service.yaml b/kubernetes/glpi/templates/redis-service.yaml index 5bca60d..51b2fda 100644 --- a/kubernetes/glpi/templates/redis-service.yaml +++ b/kubernetes/glpi/templates/redis-service.yaml @@ -6,13 +6,14 @@ metadata: namespace: {{ include "glpi.namespace" . }} labels: {{- include "glpi.labels" . | nindent 4 }} + app.kubernetes.io/component: redis spec: type: {{ .Values.redis.service.type }} selector: {{- include "glpi.selectorLabels" . | nindent 4 }} - app: redis + app.kubernetes.io/component: redis ports: - protocol: TCP port: {{ .Values.redis.service.port }} - targetPort: 6379 + targetPort: {{ .Values.redis.service.targetPort }} {{- end }} diff --git a/kubernetes/glpi/templates/serviceaccount.yaml b/kubernetes/glpi/templates/serviceaccount.yaml new file mode 100644 index 0000000..e5877aa --- /dev/null +++ b/kubernetes/glpi/templates/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "glpi.serviceAccountName" . }} + namespace: {{ include "glpi.namespace" . }} + labels: + {{- include "glpi.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/kubernetes/glpi/values.yaml b/kubernetes/glpi/values.yaml index 3f6b318..2083d80 100644 --- a/kubernetes/glpi/values.yaml +++ b/kubernetes/glpi/values.yaml @@ -7,12 +7,16 @@ global: # Namespace where GLPI will be deployed # If not set, the release namespace will be used # Leave empty to use Helm's release namespace - namespace: "glpi" + namespace: "" + # Enable to create the Namespace resource (cluster-scoped) + # Set to true if your SA has cluster-wide permissions; leave false + # for namespace-scoped RBAC (e.g., FluxCD multi-tenancy) + createNamespace: false # -- GLPI Application Configuration glpi: # GLPI version to deploy - version: "11.0.7" + version: "11.0.8" # GLPI default language (e.g., en_US, fr_FR, pt_BR) language: "en_US" @@ -24,7 +28,7 @@ glpi: # Image repository for PHP-FPM repository: eftechcombr/glpi # Image tag for PHP-FPM - tag: php-fpm-11.0.7 + tag: php-fpm-11.0.8 # Image pull policy pullPolicy: IfNotPresent @@ -71,7 +75,7 @@ glpi: # Image repository for Nginx repository: eftechcombr/glpi # Image tag for Nginx - tag: nginx-11.0.7 + tag: nginx-11.0.8 # Image pull policy pullPolicy: IfNotPresent @@ -197,6 +201,24 @@ glpi: # Schedule in cron format (default: every 2 minutes) schedule: "*/2 * * * *" + # -- GLPI Pod Security Context + # Security settings applied at the pod level + podSecurityContext: + # Set fsGroup to www-data (82) for file permissions + fsGroup: 82 + + # -- GLPI Container Security Context + # Security settings applied at the container level + securityContext: + # Run as non-root user + runAsNonRoot: true + # Run as www-data user (82) + runAsUser: 82 + # Drop all capabilities + capabilities: + drop: + - ALL + # -- MariaDB Database Configuration mariadb: # Enable or disable MariaDB deployment @@ -255,6 +277,20 @@ mariadb: # Service port for database connections port: 3306 + # -- MariaDB Pod Security Context + # Security settings applied at the pod level + podSecurityContext: + fsGroup: 1001 + + # -- MariaDB Container Security Context + # Security settings applied at the container level + securityContext: + runAsNonRoot: true + runAsUser: 1001 + capabilities: + drop: + - ALL + # -- Redis Cache Configuration redis: # Enable or disable Redis deployment @@ -288,6 +324,22 @@ redis: type: ClusterIP # Service port for Redis connections port: 6379 + # Target port on the container + targetPort: 6379 + + # -- Redis Pod Security Context + # Security settings applied at the pod level + podSecurityContext: + fsGroup: 1001 + + # -- Redis Container Security Context + # Security settings applied at the container level + securityContext: + runAsNonRoot: true + runAsUser: 999 + capabilities: + drop: + - ALL # -- Ingress Configuration # Configure ingress to expose GLPI externally @@ -316,24 +368,6 @@ ingress: # - glpi.example.local tls: [] -# -- Pod Security Context -# Security settings applied at the pod level -podSecurityContext: - # Set fsGroup to www-data (33) for file permissions - fsGroup: 82 - -# -- Container Security Context -# Security settings applied at the container level -securityContext: - # Run as non-root user - runAsNonRoot: true - # Run as www-data user (33) - runAsUser: 82 - # Drop all capabilities - capabilities: - drop: - - ALL - # -- Service Account Configuration serviceAccount: # Specifies whether a service account should be created @@ -394,3 +428,17 @@ tolerations: [] # values: # - node1 affinity: {} + +# -- External Database Configuration +# Used when mariadb.enabled is false +externalDatabase: + # External database hostname or IP + host: "" + # External database port + port: 3306 + # External database name + database: "" + # External database username + username: "" + # External database password + password: ""