Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This repository contains build files for docker images available in [Github Cont
## Summary

- [How to use this image](#how-to-use-this-image)
- [Docker Secrets](#docker-secrets)
- [Timezones support](#timezones-support)
- [Volumes](#volumes)
- [Custom PHP configuration](#custom-php-configuration)
Expand Down Expand Up @@ -98,6 +99,77 @@ If so, when accessing the web interface, installation wizard will ask you to pro
- User: `glpi`
- Password: `glpi`

### Docker Secrets

For improved security, sensitive environment variables can be loaded from files instead of being passed directly. This follows the `_FILE` convention used by official Docker images (MySQL, MariaDB, PostgreSQL).

The following variables support the `_FILE` suffix:

| Variable | `_FILE` variant | Description |
|:---------|:----------------|:------------|
| `GLPI_DB_HOST` | `GLPI_DB_HOST_FILE` | Database hostname |
| `GLPI_DB_PORT` | `GLPI_DB_PORT_FILE` | Database port |
| `GLPI_DB_NAME` | `GLPI_DB_NAME_FILE` | Database name |
| `GLPI_DB_USER` | `GLPI_DB_USER_FILE` | Database user |
| `GLPI_DB_PASSWORD` | `GLPI_DB_PASSWORD_FILE` | Database password |

The resolution order is:
1. `VAR_FILE` — reads the content of the file pointed to by the variable
2. `/run/secrets/VAR` — automatic detection of Docker Swarm / Kubernetes / Podman secrets
3. `VAR` — standard environment variable (default behavior)

> **Note:** Setting both `VAR` and `VAR_FILE` at the same time will result in an error.

#### Example with Docker Compose

1. Create a file containing your database password:

```bash
echo "my_secure_password" > ./db_password.txt
```

2. Reference it in your `docker-compose.yml`:

```yaml
services:
glpi:
image: "glpi/glpi:latest"
environment:
GLPI_DB_HOST: db
GLPI_DB_PORT: 3306
GLPI_DB_NAME: glpi
GLPI_DB_USER: glpi
GLPI_DB_PASSWORD_FILE: /run/secrets/db_password
volumes:
- glpi_data:/var/glpi
- ./db_password.txt:/run/secrets/db_password:ro
depends_on:
- db
ports:
- "80:80"
```

#### Example with Docker Swarm

```yaml
services:
glpi:
image: "glpi/glpi:latest"
secrets:
- db_password
environment:
GLPI_DB_HOST: db
GLPI_DB_PORT: 3306
GLPI_DB_NAME: glpi
GLPI_DB_USER: glpi
# No need to set GLPI_DB_PASSWORD or GLPI_DB_PASSWORD_FILE.
# The secret is automatically detected at /run/secrets/GLPI_DB_PASSWORD.

secrets:
db_password:
file: ./db_password.txt
```
Comment on lines +133 to +171
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think docker-compose could also have secrets.
So the section Example with Docker Swarm is a bit misleading,
We could propose both, and I'd say even more the swarm one should be the first proposed as it's cleaner.

In the example we could also explain various secrets possible settings like :

...
secrets:
  # Various secret source is possible
  db_password: 
    file: ./db_password.txt # From a file
    # environment: DB_PWD # From an env var
    # external: true # External secret


### Timezones support

If you want to initialize the timezones support for GLPI, we need to first GRANT the glpi user to access the `mysql.time_zone` table. So with the docker container running, you can run the following command:
Expand Down
2 changes: 2 additions & 0 deletions glpi/files/opt/glpi/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
set -e -u -o pipefail

# Load secrets from files (_FILE suffix, /run/secrets/, etc.)
source /opt/glpi/entrypoint/load-secrets.sh

/opt/glpi/entrypoint/init-volumes-directories.sh
/opt/glpi/entrypoint/forward-logs.sh
Expand Down
66 changes: 66 additions & 0 deletions glpi/files/opt/glpi/entrypoint/load-secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash
set -e -u -o pipefail

# Docker secrets support for GLPI
# Resolves sensitive environment variables from files (Docker secrets, Kubernetes secrets, or _FILE suffix).
#
# Priority order:
# 1. VAR_FILE environment variable (points to a file containing the value)
# 2. /run/secrets/VAR file (Docker Swarm / Kubernetes / Podman)
# 3. Existing environment variable value (default behavior)

# file_env - Read an environment variable from a file, following the Docker _FILE convention.
# Usage: file_env VAR [DEFAULT]
#
# Based on the pattern used by official Docker images (mysql, mariadb, postgres).
file_env() {
local var="$1"
local default="${2:-}"

local file_var="${var}_FILE"
local val="$default"

# Get current values
local current_val="${!var:-}"
local file_val="${!file_var:-}"

if [ -n "$current_val" ] && [ -n "$file_val" ]; then
echo "ERROR: Both $var and $file_var are set. These are mutually exclusive."
exit 1
fi

if [ -n "$file_val" ]; then
# _FILE variable is set, read from the specified file
if [ ! -f "$file_val" ]; then
echo "ERROR: Secret file '$file_val' specified in $file_var does not exist."
exit 1
fi
if [ ! -r "$file_val" ]; then
echo "ERROR: Secret file '$file_val' specified in $file_var is not readable."
exit 1
fi
val="$(< "$file_val")"
unset "$file_var"
elif [ -f "/run/secrets/$var" ]; then
# Docker Swarm / Kubernetes / Podman secret
val="$(< "/run/secrets/$var")"
elif [ -n "$current_val" ]; then
# Use existing environment variable
val="$current_val"
fi

export "$var"="$val"
}

# List of environment variables that support secret file resolution
secret_vars=(
GLPI_DB_HOST
GLPI_DB_PORT
GLPI_DB_NAME
GLPI_DB_USER
GLPI_DB_PASSWORD
)

for var in "${secret_vars[@]}"; do
file_env "$var"
done