GLPI directory layout for config, files, logs and plugins

Keep GLPI's writable and secret data outside the application tree so upgrades replace code safely and the config, key and file stores survive them.

On this page

Why GLPI directory layout decides how safely you can upgrade

If your GLPI configuration, keys, uploaded files, logs and plugins live inside the application source tree, every upgrade becomes a risky file replacement. The source tree is the code that ships with a GLPI release. Writable data is everything GLPI changes while it runs: database connection settings, the glpi.key and glpicrypt.key encryption keys, uploaded documents, log files and marketplace plugins. Keeping that data outside the source tree means the application files can be replaced without overwriting the things you cannot regenerate. This matters for any production install, and for any install you expect to move to GLPI 11 or 12.

The update procedure in the GLPI installation docs starts with a backup of the database, the files and the config directory, explicitly including glpi.key and glpicrypt.key. The docs then describe replacing the application files and running php bin/console db:update. Losing or mismatching those keys can leave encrypted data unreadable, so the layout should make the config directory easy to identify, back up and restore on its own. Confirm the exact file names and backup steps against the GLPI update documentation for the version you are running before you write a runbook.

Plugin handling is the other reason layout matters. Since GLPI 11.0, plugins are suspended when a new version is detected and must be reactivated after major updates. Teams should decide before the first upgrade where marketplace plugins live, who approves them, and how their versions are tracked against the target release. Ask your plugin authors and your own change process to confirm compatibility, because a suspended plugin can change ticket routing, forms or inventory behavior until someone reactivates it. A layout that separates plugins, configuration and uploads gives you a clear rollback point for each.

Which directories to move and where each one goes

The configuration directory holds the settings that define how this GLPI instance connects to its database and handles secrets. Moving it out of the source tree means that replacing the application files during an upgrade cannot overwrite these values. The encryption keys live here too, and losing them makes encrypted data unreadable, so this location needs the same backup discipline as the database.

  • Database connection settings: Host, database name and service credentials are the first values a new deployment needs, and only the service account should be able to read them.
  • Encryption keys: The update procedure names glpi.key and glpicrypt.key as files to back up before any change. Store copies in your secrets management system and in an offline backup.
  • Downstream and local overrides: downstream.php points GLPI to the external configuration location, and local_define.php holds constants that override defaults. Confirm the file names and constants for your version before you write them.
  • Restricted write access: Make the directory readable by the web service user and keep it read-only at runtime where the design allows, so changes to database targets require an administrator.

Confirm the exact locations and supported constants in the GLPI update documentation for your installed version before you change anything.

Layout options and when each fits

This table compares the default layout, moving only the config directory, and moving config, files, logs and the marketplace out of the source tree, plus two deployment shapes that change the answer. Read each row from left to right: what leaves the source tree determines what an update replaces and what a backup must capture. The main takeaway is that moving the key files and data directories out of the tree is what makes updates and restores predictable.

LayoutWhat moves out of the treeUpgrade and backup effortBest fit
Default layoutNothing. Config, files, logs and marketplace stay inside the GLPI source tree.Each update replaces application files, so data directories must be preserved or copied by hand before and after.Trials and lab installs only, since production data sits in the path that updates overwrite.
Config directory onlyConfiguration and key files, located through downstream.php and local_define.php.Keys survive file replacement, but files, logs and marketplace still need manual handling at every update.Single servers with modest file volumes and no need to share storage.
Config, files, logs and marketplaceAll four directories, each pointed to from downstream.php or local_define.php.Replace the source tree and keep the external directories. Back up the database and every external directory, including key files.Single servers with a dedicated data volume, and the base for shared or containerized setups.
Shared storage across web nodesFiles, logs and marketplace on a mount every node reads, with config shared as well.All nodes must run the same version and be updated together. Back up the shared mount once, not per node.Several front ends behind a load balancer, with storage every node can reach.
Container with official imageConfig, files and marketplace on mounted volumes. Confirm the exact paths against the image documentation.Update by image tag while volumes persist. Back up volumes, database and keys together.Docker or container platforms where the image is replaced and state lives in volumes.

How to move GLPI directories out of the source tree

This sequence relocates GLPI's configuration, files directory, logs and plugins outside the web-served application tree so that the application code can be replaced during upgrades without touching data. It ends with a tested instance and a rehearsed upgrade path that your team can repeat.

  1. Back up database, files and config

    The administrator takes a full database dump, a copy of the GLPI files directory and a copy of the config directory, including glpi.key and glpicrypt.key. Store the keys separately from the database dump, because the database alone cannot decrypt stored credentials without them. The step is done when you can restore the backup to a scratch host and read the restored instance's configuration and encrypted fields.

  2. Create directories outside the web root

    The platform engineer creates separate directories for config, files, logs and plugins on a path the web server cannot serve, then sets ownership to the web server user and restricts access to that user and the administrator group. Keep the GLPI application tree and these data paths on different parent directories so a future replacement of the application code cannot remove them. The step is done when the web server user can write to each directory and a direct HTTP request for a path inside them returns a denied or not found response.

  3. Point GLPI at the new paths

    Using the GLPI documentation for your version, the administrator creates downstream.php in the application's inc directory to define the path to the config directory, then creates local_define.php in the config directory to set the files, logs and plugins paths. Confirm the exact constant names and file locations for your release in the installation documentation before editing, since they are version-specific. The step is done when the GLPI setup check or administration page loads without path errors and reports the new locations.

  4. Move existing data into the new layout

    The administrator copies the existing files directory, log files and installed plugins into the new locations, preserving ownership and permissions, and then removes the originals from the source tree only after the next checks pass. Move plugins with their directory structure intact so GLPI can detect them. The step is done when a file-count and checksum comparison between old and new locations matches, and no GLPI path still resolves inside the application tree.

  5. Set file permissions for each directory

    The administrator applies the narrowest workable permissions: the config directory should be readable by the web server user and not writable by it after setup, the files directory and logs directory should be writable by the web server user, and plugin directories should be readable with write access limited to the deployment account. Record the expected modes in your build runbook so they can be checked after each change. The step is done when a scripted permission check against that runbook reports no differences.

  6. Verify with login, upload and log write

    The tester signs in with a test account, uploads a file attached to a ticket or asset, and triggers an action that writes to the log directory, such as a failed login. Confirm each action succeeds and the resulting file appears in the new files and logs paths, not the old ones. The step is done when all three checks pass and the web server access log shows no successful request for the data paths.

  7. Rehearse an upgrade on a copy

    The engineer restores the backup to a staging host using the new layout, replaces the application files with the target release, and runs the database update command from the GLPI update documentation. Plugins are suspended after a new version is detected, so reactivate them only after confirming each one supports the target release. The step is done when the upgraded staging instance passes the login, upload and log checks, and the team has recorded the sequence and time it took to repeat it.

File permissions for each directory

Each GLPI directory has a different job, so each needs a different permission. The web server user should read the code and configuration it needs, write only where GLPI stores runtime data, and have no write access to the application code it runs. Confirm the exact modes against your distribution and PHP-FPM pool user before you apply them.

Config directory

The config directory holds database connection settings and the key files such as glpi.key and glpicrypt.key. The web user needs read access so GLPI can start, but the files should not be readable by other local users or served over HTTP. Losing or changing the key files can make stored secrets unreadable, so restrict access and back them up under the same controls as the database. Confirm the owner and mode on each key file in your own environment.

Files directory

The files directory stores uploads, attachments and generated documents, so the web user needs write access here. It must sit outside the web root so that stored documents are only delivered through GLPI's own access checks, not by a direct URL. Check that your web server configuration denies direct requests to this path, and that the directory is excluded from any world-readable shared mount.

Log directory

The log directory receives GLPI and PHP-level entries that you will need during incident review and upgrades. The web user needs write access, but the logs themselves should not be readable by unrelated accounts because they can contain user names and request details. Set up log rotation so the directory does not fill the disk, and confirm the rotation user can read and rename files that the web user writes.

Marketplace directory

The marketplace directory holds plugins installed through the GLPI interface. Keep it read-only to the web user during normal operation, and grant write access only for the window in which you install or update a plugin, then remove it. This limits what a compromised web process can plant in the application. Confirm with your change process who opens and closes that window.

Source tree

The application code should be owned by a deployment account and readable by the web user, but not writable by it where your layout allows. Read-only code makes unauthorized changes harder and makes it easier to show which files changed during an update. Where the layout forces writes, document each path and review it during hardening. Confirm which paths GLPI needs to write in your release before you lock the rest.

Update and maintenance access

Upgrades replace application files and run database updates, so the account doing that work needs more access than the web user for a short period. Keep that account separate from the PHP-FPM or web server user, and revert permissions after the update. Plugins are suspended after a new version is detected, so plan reactivation as part of the same change window.

How the layout changes GLPI upgrades and plugin reactivation

Moving configuration, the files directory, logs and the marketplace out of the source tree makes GLPI upgrades safer because the application files can be replaced without touching data or secrets. The update procedure in the GLPI installation documentation expects you to back up the database, the files and the config directory, including glpi.key and glpicrypt.key, then replace the application files and run php bin/console db:update. If downstream.php points to an external config directory and local_define.php holds the path overrides, the code swap is a simple replacement of the source tree. Confirm that both files survive the swap and that the paths they reference still resolve on the new release.

Plugins need separate attention. Since GLPI 11.0, plugins are suspended after a new version is detected and must be reactivated after major updates. Plan a reactivation pass into the change window, and check each plugin against its own release notes before enabling it, since a plugin built for one major version may not load on the next. Test after any path move: log in, open a ticket with an attachment to confirm the files directory is writable, check that the log directory receives entries, open the marketplace page, and run the automatic actions once to confirm the cron user can read the config directory.

A rollback needs the same inventory. Keep the pre-upgrade database dump, a copy of the old application tree, and the external config and files directories as they were before db:update ran. Note that a database rollback is needed if the schema changed, so the old application tree alone is not enough. Ask your vendor or the plugin authors to confirm which plugin versions support the target release, and rehearse the restore on a non-production copy before the change window.

Security and operational risks of directory placement

Moving GLPI's config, files, logs and plugins out of the web tree removes several common exposure paths, but each move creates its own failure mode. The cards below pair each risk with the control that addresses it and the check that proves the control still works after updates, restores and multi-server changes.

Keys stored under the web root

The glpi.key and glpicrypt.key files protect encrypted data in the database, and a copy reachable through the browser would expose that material to anyone who can guess its path. Control: keep the config directory outside the document root, and point GLPI at it through downstream.php or local_define.php so the web server never needs to serve it. Verify: request the config path and the key file names directly over HTTP and confirm each returns a denial or a not-found response.

Uploaded files served directly

Ticket attachments, documents and inventory files land in the files directory, and a web server that maps that path to a URL can serve executable or HTML uploads to other users. Control: place the files directory outside the public directory, deny web access to it, and let GLPI stream downloads through its own permission checks. Verify: upload a test file to a ticket, then fetch its storage path directly and confirm the request fails.

World-readable configuration

A config file readable by every local account exposes database credentials and encryption settings to anyone who gets a shell on the host. Control: set the web server user as the owner of the config and key files, give them mode 0640 or stricter, and keep the deployment user separate from the runtime user. Verify: list the files as the runtime user and as an unrelated local account, and confirm the second account cannot read them.

Log growth filling disks

GLPI writes application and SQL logs to a logs directory, and a debug setting or a failing integration can grow those files faster than anyone reads them. Control: place logs on a volume with its own capacity alert, rotate them with logrotate, and keep debug logging off outside investigations. Verify: check the logs directory size after a week of normal activity and confirm a rotation rule runs and that the alert fires at the threshold you set.

Backups that miss the key files

A database and files backup restores ticket data, yet without glpi.key and glpicrypt.key the encrypted values in the database cannot be read after recovery. Control: include the config directory in every backup job and store the key files with the same retention and access rules as the database dump. Verify: restore a backup to a clean host, start GLPI, and confirm stored credentials and encrypted fields still decrypt.

Shared storage permission drift

In multi-server installs, the files and plugins directories often sit on shared storage, and ownership or mode changes on one node can break uploads or plugin loading on the others. Control: define one owner and group for the shared paths, mount them with the same options on every node, and reapply permissions from a single deployment step. Verify: run the same write and read test as the web user from each server and compare results after every update.

Questions teams ask before moving GLPI directories

What does moving GLPI directories cost in effort, and what drives it?

The effort depends mostly on how much GLPI has been customized and how the instance is run today. The move itself is a bounded task: relocating the config directory, the files directory, logs and the marketplace, then pointing GLPI at them through downstream.php and local_define.php. The cost grows with the number of installed plugins (each one may write to paths or assume locations that change), the volume of existing file attachments and documents, and whether GLPI runs in a container, where storage is usually a volume mount, or on bare metal, where the web tree and permissions are managed by hand. Ask any partner for a quote that lists each of these inputs separately, along with the test copy, the validation steps and the rollback plan.

Can our own team move GLPI directories without a partner?

Often yes, if you have someone comfortable with Linux file permissions, the web server configuration and PHP, and you can run a full copy of the instance first. The work requires knowing which user the web server and PHP-FPM run as, how to read and write the config directory and files directory safely, and how to confirm that the application still starts and that attachments still load after the change. Teams without that skill set usually want a partner to review the plan or do the work on a staging copy. Either way, the first step is a test copy built from a recent backup, not the production system.

How long does a GLPI directory move take, and what sets the duration?

No duration is supplied for this work, so confirm it in a quote rather than assuming one. The main variables are the number of plugins to test, the size of the files directory (copying large volumes takes time and needs a maintenance window), the number of web servers or containers sharing the storage, and how many environments you must validate, such as staging, production and any disaster recovery copy. Ask the partner to state which of these they have assumed and which steps are blocked until a window is available.

What should we provide to a partner before they quote the move?

Give the partner a clear picture of the current installation so the quote reflects real inputs. Useful items include the GLPI version and PHP version, the web server and whether it runs in Docker or on a Linux host, the database type and version, the list of installed plugins with their versions, the current paths for config, files, logs and marketplace, the size of the files directory, and the backup method in use. Also provide access to a non-production copy, the backup and recovery expectations, and the maintenance windows you can accept.

How do directory changes interact with a GLPI upgrade?

Plan the directory move as a separate, tested change, not something folded into an upgrade. The GLPI update procedure requires backing up the database, the files and the config directory, including glpi.key and glpicrypt.key, before replacing application files and running php bin/console db:update. If the config and files paths move at the same time, the backup and restore steps must still point at the correct locations. Since GLPI 11.0, plugins are suspended after a new version is detected and must be reactivated after major updates, so check plugin compatibility on the target version before the production change, and confirm the upgrade sequence with the vendor documentation for your exact target release.

Which file permissions must be right after the move, and what breaks if they are not?

The web server user must be able to read the GLPI application code and the public directory, and must be able to write to the files and log locations GLPI uses at runtime, while the config directory should be readable by the application but not writable by the web user during normal operation. If permissions are too broad, sensitive keys and settings are exposed. If they are too narrow, uploads fail, logs stop being written and the marketplace cannot install or update plugins. Test each path after the change by uploading a document, triggering a log entry, and checking a plugin action, then confirm the exact ownership model against the official install documentation for your version.

What is the main risk when moving GLPI directories, and how do we limit it?

The main risk is losing access to encrypted data or existing attachments because a key or path was not carried over correctly. Keys such as glpi.key and glpicrypt.key must stay with the config directory and be included in every backup. Limit the risk by taking a full backup before the change, rehearsing the move on a copy, recording the old and new paths, keeping the previous layout available for rollback until the new one has been checked, and agreeing in writing who signs off the validation results.

How DeployOpen scopes and delivers GLPI directory layout work

DeployOpen starts every GLPI directory layout engagement with a written, fixed scope that names the paths to move, the web root that will serve only the public directory, and the systems that depend on each path. The scope lists which files will hold downstream.php and local_define.php, where the config directory and the files directory will live, which log and marketplace locations will be used, and which service accounts will own each path. Before any change, we ask for the current install path, the PHP and database versions in use, the web server configuration, and the backup method. Those inputs decide whether the work is a fresh layout or a move of an existing instance, and they drive the quote far more than the number of users does.

Delivery follows a set sequence in your own infrastructure: back up the database, the files and the config directory, including glpi.key and glpicrypt.key, then relocate directories, set ownership and permissions for each path, and verify that the web server still serves only the public directory. Each change is tested against a non-production copy first, and the plugin state is checked afterward, since GLPI 11.0 suspends plugins when it detects a new version. DeployOpen documents the final paths, permissions, cron and log locations in a runbook that your operations team keeps. Handover covers a walkthrough and a verification checklist that your staff can repeat after future updates.

Ongoing work such as upgrades to later GLPI releases, plugin reviews and permission audits can be placed under a retainer, which is billed on an agreed cadence rather than per incident. Ask any partner, including DeployOpen, to confirm in writing what the retainer covers, how long a response may take, and who holds administrative access after handover. Confirm with your own security team which backup retention and encryption standards apply to the config and key files before the scope is signed, because those choices belong to your organization and shape the work.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.