This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new ffee7d268b Issue #8113 : Document Hop Web Docker persistence and 
upgrades (#8122)
ffee7d268b is described below

commit ffee7d268b8318b1caac0f9ff5e2458cd2a4d504
Author: Matt Casters <[email protected]>
AuthorDate: Thu Aug 27 14:12:04 2026 +0200

    Issue #8113 : Document Hop Web Docker persistence and upgrades (#8122)
    
    Explain which folders to persist outside apache/hop-web, how to
    configure HOP_CONFIG_FOLDER, and how auth and project access survive
    image upgrades.
---
 .../modules/ROOT/pages/hopweb/developer-guide.adoc |   7 +-
 docs/hop-tech-manual/modules/ROOT/nav.adoc         |   1 +
 .../modules/ROOT/pages/docker-container.adoc       |  17 +
 .../modules/ROOT/pages/hop-web-docker.adoc         | 349 +++++++++++++++++++++
 docs/hop-tech-manual/modules/ROOT/pages/index.adoc |   1 +
 .../modules/ROOT/pages/hop-gui/hop-web.adoc        |  44 ++-
 .../modules/ROOT/pages/hop-gui/index.adoc          |   3 +-
 .../ROOT/pages/installation-configuration.adoc     |   4 +-
 .../modules/ROOT/pages/projects/index.adoc         |   2 +
 9 files changed, 421 insertions(+), 7 deletions(-)

diff --git a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/developer-guide.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/developer-guide.adoc
index e415fea97d..9219cb6e5f 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/developer-guide.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/developer-guide.adoc
@@ -114,6 +114,11 @@ The main configuration of Hop is done through a single 
configuration file called
 It is possible to set pass this standard Hop environment variable 
`HOP_CONFIG_FOLDER` to the docker container.
 You can point it to a mounted volume for example:
 
-`docker run -p 8080:8080 -v /host/path/to/config:/config -e 
HOP_CONFIG_FOLDER=/config hop-web`
+`docker run -p 8080:8080 -v /host/path/to/config:/hop/config -e 
HOP_CONFIG_FOLDER=/hop/config hop-web`
+
+Prefer a dedicated path such as `/hop/config` rather than `/config`.
+The Hop Web image uses `/config` for an optional Tomcat `tomcat-users.xml` / 
`web.xml` overlay.
 
 In the same way you can set the standard variable `HOP_AUDIT_FOLDER` to store 
GUI auditing and logging information.
+
+For the operator-facing volume layout, Compose example, and upgrade procedure, 
see xref:tech-manual::hop-web-docker.adoc[Hop Web in Docker: persistence and 
upgrades].
diff --git a/docs/hop-tech-manual/modules/ROOT/nav.adoc 
b/docs/hop-tech-manual/modules/ROOT/nav.adoc
index 16beffdbbf..48b9c1304f 100644
--- a/docs/hop-tech-manual/modules/ROOT/nav.adoc
+++ b/docs/hop-tech-manual/modules/ROOT/nav.adoc
@@ -16,6 +16,7 @@ under the License.
 ////
 * xref:getting-started.adoc[Getting started]
 * xref:docker-container.adoc[Docker container]
+* xref:hop-web-docker.adoc[Hop Web in Docker]
 * xref:disable-ui-elements.adoc[Disable UI elements]
 * xref:hop-vs-kettle/index.adoc[Kettle/PDI and Hop]
 ** xref:hop-vs-kettle/hop-vs-kettle.adoc[Hop vs Kettle]
diff --git a/docs/hop-tech-manual/modules/ROOT/pages/docker-container.adoc 
b/docs/hop-tech-manual/modules/ROOT/pages/docker-container.adoc
index 337c40cd72..067e9f4a8b 100644
--- a/docs/hop-tech-manual/modules/ROOT/pages/docker-container.adoc
+++ b/docs/hop-tech-manual/modules/ROOT/pages/docker-container.adoc
@@ -31,6 +31,9 @@ It's a **Hop Docker image** supporting both **short-lived** 
and **long-lived** s
 A short-lived setup executes a pipeline or workflow and stops right after.
 A long-lived setup starts a Hop server and waits for work.
 
+This page describes `apache/hop` (hop-run and Hop Server).
+For the Hop Web GUI image (`apache/hop-web`), including which folders to 
persist across upgrades, see xref:hop-web-docker.adoc[Hop Web in Docker: 
persistence and upgrades].
+
 == Operating system
 
 The docker container runs a minimal Linux system called 
https://hub.docker.com/_/alpine[Alpine].
@@ -48,6 +51,7 @@ The Linux user used to execute in the container is `hop` and 
the group is `hop`
 |```/files```
 | This volume has read-write permissions for Linux user `hop`.
 You can use it for example to mount a folder that contains the **hop and 
project config** as well as the **workflows and pipelines**.
+Do not persist project files only under `/opt/hop`; that tree is replaced when 
you pull a new image.
 
 |```/home/hop```
 | The initial working directory location of the docker container.
@@ -70,6 +74,18 @@ Use one of: `None`, `Error`, `Minimal`, `Basic`, `Detailed`, 
`Debug` or `Rowleve
 |`/opt/hop/hop.err.log`
 | The file path to the Hop log file.
 
+|```HOP_CONFIG_FOLDER```
+|
+| Folder that contains `hop-config.json` (project and environment 
registrations, GUI settings).
+Leave unset to use the image default (`config/` under the Hop install).
+Point this at a mounted volume if the configuration must survive replacing the 
container.
+See xref:hop-web-docker.adoc[Hop Web in Docker] for the Hop Web layout; the 
same variable applies here.
+
+|```HOP_AUDIT_FOLDER```
+|
+| Folder for GUI / execution audit data.
+Point this at a mounted volume to keep it across container recreation.
+
 |```HOP_PROJECT_NAME```
 |
 | Name of the Hop project to create in the container.
@@ -392,6 +408,7 @@ In this example, a project is created in the container and 
exposed in the Hop Py
 
 NOTE: The option to run commands is available from Hop version 2.18.
 
+[[DownloadingJDBCDrivers]]
 == Downloading JDBC drivers
 
 Apache Hop ships the JDBC drivers it is allowed to redistribute (PostgreSQL, 
MS SQL Server, Snowflake, ...). Drivers with a restricted license - Oracle, 
MySQL, MariaDB, IBM DB2 and others - are *not* bundled and have to be added to 
the `lib/jdbc` folder yourself.
diff --git a/docs/hop-tech-manual/modules/ROOT/pages/hop-web-docker.adoc 
b/docs/hop-tech-manual/modules/ROOT/pages/hop-web-docker.adoc
new file mode 100644
index 0000000000..7513a5e3aa
--- /dev/null
+++ b/docs/hop-tech-manual/modules/ROOT/pages/hop-web-docker.adoc
@@ -0,0 +1,349 @@
+////
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+////
+:description: Recommended volume mounts, environment variables, and upgrade 
procedure for the official apache/hop-web Docker image. Persist projects and 
HOP_CONFIG_FOLDER outside the image.
+:openvar: ${
+:closevar: }
+:TOC:
+
+[[HopWebDocker]]
+= Hop Web in Docker: persistence and upgrades
+
+The official Hop Web image is 
https://hub.docker.com/r/apache/hop-web[`apache/hop-web`].
+It is a long-lived GUI: people design pipelines and workflows in the browser, 
so **project files, Hop configuration, and security files are operator data**.
+They must live on the host or on a volume, not only inside the container 
filesystem.
+
+This page answers how to run that image in an upgrade-friendly way:
+
+* which folders to **preserve** when you pull a new tag
+* which content should **always come from the new image**
+* how to add **JDBC drivers** (and why you should not persist `plugins/`)
+* which **volume mounts** to use, with a small Compose example
+
+The xref:manual::hop-gui/hop-web.adoc[Hop Web user manual] covers starting the 
image, authentication modes, and the Security UI.
+The xref:docker-container.adoc[Docker container] page covers the sibling 
`apache/hop` image (hop-run and Hop Server).
+
+== Two images, two persistence models
+
+[cols="1,2,2"]
+|===
+| Image | Role | Where the project lives
+
+| `apache/hop-web`
+| Hop Gui in a browser (authoring)
+| **Outside** the image: a host folder or a volume.
+The baked-in `default` and `samples` projects are only a starter layout.
+
+| `apache/hop`
+| hop-run (short-lived) or Hop Server (long-lived)
+| Often **in a derived image** for production execution.
+That is xref:manual::hop-server/deploy-project-image.adoc[Project in a Docker 
image], not a Hop Web upgrade procedure.
+|===
+
+Do not `docker commit` a Hop Web container that has work saved in it, and do 
not treat the image's own `config/projects/` tree as your project home.
+
+== What always comes from the new image
+
+Replace the container (new tag) to pick these up.
+Do **not** bind-mount over them:
+
+[cols="2,3"]
+|===
+| Content | Typical path in `apache/hop-web`
+
+| Tomcat 10 and the JRE
+| image base
+
+| Hop Web application (RAP UI, servlets)
+| `/usr/local/tomcat/webapps/ROOT` (except the config tree you choose to 
persist)
+
+| Plugin tree
+| `/usr/local/tomcat/plugins` (`HOP_PLUGIN_BASE_FOLDERS`).
+The official image already copies the standard Hop plugin set.
+
+| Bundled JDBC drivers
+| `/usr/local/tomcat/jdbc-drivers`
+
+| Starter `default` and `samples` projects
+| `{openvar}HOP_CONFIG_FOLDER{closevar}/projects/` in the *image* config.
+Fine for a throwaway `docker run`.
+Not a place to save work.
+|===
+
+Pin an image tag (`apache/hop-web:2.20.0`, or the release you actually run).
+Do not use `latest` in production.
+
+== What to persist
+
+The Hop Web image passes `HOP_CONFIG_FOLDER` and `HOP_AUDIT_FOLDER` into the 
JVM as system properties (`CATALINA_OPTS` in `docker/web.Dockerfile`).
+Override those variables and mount volumes at the paths you choose.
+
+Recommended container paths below are conventions for this page and the 
Compose example; any path is fine as long as env vars and mounts match.
+
+[cols="1,2,2,3"]
+|===
+| Persist | Image default | Recommended container path | Holds
+
+| `{openvar}HOP_CONFIG_FOLDER{closevar}`
+| `/usr/local/tomcat/webapps/ROOT/config`
+| `/hop/config`
+| `hop-config.json` (GUI preferences, **project and environment 
registrations**), and `security/` (see <<hop-web-docker-auth>>)
+
+| Project homes
+| `{openvar}HOP_CONFIG_FOLDER{closevar}/projects/default` and `.../samples`
+| `/hop/projects/<name>`
+| `project-config.json`, `metadata/`, pipelines (`.hpl`), workflows (`.hwf`), 
and the rest of the project
+
+| Environment JSON
+| none
+| `/hop/config/environments/` or next to the project when the file is 
non-secret
+| Hostnames, paths, 
xref:manual::metadata-types/variable-resolver/index.adoc[resolvers].
+Keep secrets out of git.
+
+| `{openvar}HOP_AUDIT_FOLDER{closevar}`
+| `/tmp/hop-web-audit`
+| `/hop/audit`
+| Per-user UI state under `users/<username>/`
+
+| Extra JDBC (optional)
+| bundled drivers only
+| `/hop/jdbc` *or* download on start
+| Restricted drivers (Oracle, MySQL, MariaDB, DB2, …).
+See <<JDBCDriversAndPlugins>>.
+|===
+
+`hop-config.json` stores **project names and home paths**.
+It does not store the pipelines.
+If `projectHome` still points at 
`{openvar}HOP_CONFIG_FOLDER{closevar}/projects/samples`, you are editing 
starter samples inside config.
+Register real projects with homes under `/hop/projects/…`.
+
+The entrypoint (`docker/resources/run-web.sh`) can register one project on 
every start from `HOP_PROJECT_NAME` and `HOP_PROJECT_FOLDER`.
+That is enough for a single-project demo.
+It does **not** keep GUI settings, extra projects, users, or project-access 
rules.
+A shared Hop Web instance should persist the whole `HOP_CONFIG_FOLDER`.
+
+== Configure with environment variables
+
+Point Hop at the persisted layout.
+Do not copy files into the image and commit a new layer for day-to-day work.
+
+[cols="2,3"]
+|===
+| Variable | Role
+
+| `HOP_CONFIG_FOLDER`
+| Directory that contains `hop-config.json` and `security/`.
+Set to the config volume, for example `/hop/config`.
+
+| `HOP_AUDIT_FOLDER`
+| Per-user audit / UI state.
+Set to the audit volume, for example `/hop/audit`.
+
+| `HOP_PROJECT_NAME` / `HOP_PROJECT_FOLDER`
+| Optional.
+The entrypoint registers this project in `hop-config.json` when the folder 
exists.
+Use together with a mount at `HOP_PROJECT_FOLDER`.
+
+| `HOP_PROJECT_CONFIG_FILE_NAME`
+| Project config file name (default `project-config.json`).
+
+| `HOP_PARENT_PROJECT_NAME` / `HOP_PARENT_PROJECT_FOLDER`
+| Optional one-level parent project.
+See xref:manual::hop-gui/hop-web.adoc[Hop Web].
+
+| `HOP_ENVIRONMENT_NAME` / `HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS`
+| Optional lifecycle environment registered on start.
+Paths are **inside** the container.
+
+| `HOP_SHARED_JDBC_FOLDERS`
+| Comma-separated JDBC directories.
+Keep `/usr/local/tomcat/jdbc-drivers` and add `/hop/jdbc` when you mount extra 
jars.
+
+| `HOP_DRIVERS_DOWNLOAD` / `HOP_DRIVERS_ACCEPT_LICENSE`
+| Download restricted drivers on start.
+See xref:docker-container.adoc#DownloadingJDBCDrivers[Downloading JDBC 
drivers].
+
+| `HOP_WEB_SECURITY_MODE` and related `HOP_WEB_*` variables
+| Authentication bootstrap.
+See xref:manual::hop-gui/hop-web.adoc#hop-web-authentication[Hop Web 
authentication].
+|===
+
+.Permissions
+The process user is `hop` (UID and GID **501** in `docker/web.Dockerfile`).
+Bind-mounted host directories must be writable by that user.
+Named volumes created by Docker usually already are.
+
+.Do not
+* Bind-mount over `/usr/local/tomcat/plugins`.
+* Mount an **empty** directory onto the *default* config path 
(`/usr/local/tomcat/webapps/ROOT/config`) unless you intend to hide the image 
`hop-config.json` and the starter projects.
+Prefer a separate path (`/hop/config`) so the image tree stays available for 
reference.
+* Use the `/config` mount (Tomcat `tomcat-users.xml` / `web.xml` overlay) for 
environment JSON or project files.
+That path is only for 
xref:manual::hop-gui/hop-web.adoc#hop-web-authentication[EXTERNAL] container 
authentication.
+
+[[JDBCDriversAndPlugins]]
+== JDBC drivers and plugins
+
+=== Plugins
+
+The official `apache/hop-web` and `apache/hop` images already include the 
standard Hop plugin set.
+A new image tag is how you pick up plugin fixes and additions.
+
+Do not persist `plugins/` on a volume: an old tree mixed with a new image is a 
common upgrade failure.
+
+Custom or xref:manual::hop-tools/hop-marketplace.adoc[marketplace] extras that 
are not in the image can be:
+
+* installed in a small derived image (`FROM apache/hop-web`, then `hop 
marketplace apply` or `COPY` the plugin), or
+* re-applied after you recreate the container (`hop marketplace apply -f …` in 
the new container).
+
+Plugin installs in Hop Web affect the shared server installation for every 
user; they are not per-session.
+
+=== JDBC
+
+Apache Hop does not redistribute drivers with a restricted license (Oracle, 
MySQL, MariaDB, IBM DB2, and others).
+Use one of:
+
+. **Download on start** — set `HOP_DRIVERS_DOWNLOAD` (and 
`HOP_DRIVERS_ACCEPT_LICENSE=true` for restricted drivers).
+Jars are written into `HOP_SHARED_JDBC_FOLDERS`.
+They are ephemeral unless that folder is itself a volume.
+See xref:docker-container.adoc#DownloadingJDBCDrivers[Downloading JDBC 
drivers].
+
+. **Mount extra jars** — put vendor jars on the host and mount them at 
`/hop/jdbc`:
++
+[source,bash]
+----
+HOP_SHARED_JDBC_FOLDERS=/usr/local/tomcat/jdbc-drivers,/hop/jdbc
+----
++
+Keep the image's `/usr/local/tomcat/jdbc-drivers` on that list so bundled 
drivers still load.
+
+[[hop-web-docker-auth]]
+== Authentication, authorization, and project mapping
+
+From Hop 2.20, Hop Web can authenticate users and map them to built-in roles 
(Admin, User, Operator, Read-only), and the Projects plugin can **restrict 
which projects a user may open**.
+
+Full behaviour, login modes (`NONE`, `EXTERNAL`, `BASIC`, `OAUTH2`), and the 
Security UI are documented in 
xref:manual::hop-gui/hop-web.adoc#hop-web-authentication[Hop Web 
authentication].
+For upgrades, the important fact is **where those files live**.
+
+All of the following sit under 
`{openvar}HOP_CONFIG_FOLDER{closevar}/security/`:
+
+[cols="1,3"]
+|===
+| File | Purpose
+
+| `security-config.json`
+| Authentication mode, OAuth settings, container/IdP role → Hop role mappings, 
login welcome message
+
+| `users.json`
+| Hop-managed BASIC users (PBKDF2 hashes)
+
+| `projects-access.json`
+| Project access rules (user, Hop role, or IdP/LDAP group → project names or 
all projects)
+|===
+
+Persist `{openvar}HOP_CONFIG_FOLDER{closevar}` and you keep project 
registrations, users, and “who may open which project” across image upgrades.
+
+Configure project mapping in the GUI: **Configuration → Security → Projects** 
(xref:manual::hop-gui/hop-web.adoc#hop-web-project-access[project access]).
+Enable filtering, add rules (`user` / `role` / `group`), and either allow all 
projects for that subject or list names.
+Security administrators (`security.manage`) always see every project.
+When no rule matches, `defaultAllowAll` decides whether the user sees all 
projects or none.
+
+Put Hop Web behind TLS in any shared deployment.
+Do not use the seeded demo users (`HOP_WEB_SEED_DEMO_USERS`) outside local 
development.
+
+== Recommended mounts and Compose example
+
+[cols="1,2,3"]
+|===
+| Host / volume | Container path | Why
+
+| Named volume `hop-config`
+| `/hop/config`
+| Survives `docker compose down` without `-v`.
+Holds `hop-config.json` and `security/`.
+
+| Bind mount `./projects`
+| `/hop/projects`
+| Git working tree on the host.
+Commit pipelines from the host, not from inside the image.
+
+| Named volume `hop-audit`
+| `/hop/audit`
+| Last opened files and similar per-user UI state
+
+| Bind mount `./jdbc` (optional)
+| `/hop/jdbc`
+| Extra JDBC jars.
+Skip this mount if you use `HOP_DRIVERS_DOWNLOAD`.
+|===
+
+The same layout works under Kubernetes: persist those four paths with 
PersistentVolumeClaims or ConfigMaps/Secrets for environment JSON.
+The Helm chart does not yet declare them for you.
+
+.Upgrade-friendly Hop Web
+[source,yaml]
+----
+services:
+  hop-web:
+    image: apache/hop-web:<tag>
+    ports:
+      - "8080:8080"
+    environment:
+      HOP_CONFIG_FOLDER: /hop/config
+      HOP_AUDIT_FOLDER: /hop/audit
+      HOP_PROJECT_NAME: my-project
+      HOP_PROJECT_FOLDER: /hop/projects/my-project
+      HOP_SHARED_JDBC_FOLDERS: /usr/local/tomcat/jdbc-drivers,/hop/jdbc
+      HOP_WEB_SECURITY_MODE: BASIC
+      HOP_WEB_ADMIN_USER: admin
+      HOP_WEB_ADMIN_PASSWORD: {openvar}HOP_WEB_ADMIN_PASSWORD{closevar}
+    volumes:
+      - hop-config:/hop/config
+      - hop-audit:/hop/audit
+      - ./projects:/hop/projects
+      - ./jdbc:/hop/jdbc
+
+volumes:
+  hop-config:
+  hop-audit:
+----
+
+Replace `<tag>` with a released Hop version.
+Create `./projects/my-project` (with `project-config.json`) on the host before 
the first start, and ensure it is writable by UID 501.
+Set `HOP_WEB_ADMIN_PASSWORD` in the environment or a Compose `.env` file; do 
not commit it.
+
+For OAuth or Tomcat EXTERNAL authentication, keep this volume layout and 
follow xref:manual::hop-gui/hop-web.adoc#hop-web-authentication[Hop Web 
authentication] for the extra settings.
+If you use EXTERNAL, mount `tomcat-users.xml` and `web.xml` at `/config/` and 
do not put project files there.
+
+== Upgrade procedure
+
+. Commit or back up `./projects` (and keep the Compose file and secrets).
+. Change the image tag in Compose to the new Hop version.
+. `docker compose pull`
+. `docker compose up -d` — same volumes and environment variables.
+. Open http://localhost:8080/ui, confirm the project switcher, and (if 
authentication is enabled) sign in and check project access.
+
+Do **not** copy `plugins/`, `webapps/ROOT`, or `/opt/hop` out of the old 
container into the new one.
+
+Hop configuration from a previous 2.x version is expected to load.
+If you added marketplace plugins that are not in the new image, re-apply the 
install spec after the container is up.
+
+== See also
+
+* xref:manual::hop-gui/hop-web.adoc[Hop Web] — start the image, roles, BASIC / 
OAuth / EXTERNAL
+* xref:docker-container.adoc[Docker container] — `apache/hop` (hop-run and Hop 
Server)
+* xref:manual::installation-configuration.adoc[Installation and configuration] 
— desktop `HOP_CONFIG_FOLDER` (same idea, no container)
+* xref:manual::projects/index.adoc[Projects and environments]
+* xref:manual::hop-server/deploy-project-image.adoc[Project in a Docker image] 
— baking a project into `apache/hop` for execution
diff --git a/docs/hop-tech-manual/modules/ROOT/pages/index.adoc 
b/docs/hop-tech-manual/modules/ROOT/pages/index.adoc
index ab0d2418e4..db38a444ae 100644
--- a/docs/hop-tech-manual/modules/ROOT/pages/index.adoc
+++ b/docs/hop-tech-manual/modules/ROOT/pages/index.adoc
@@ -18,5 +18,6 @@ under the License.
 
 * xref:getting-started.adoc[Getting started]
 * xref:docker-container.adoc[Docker container]
+* xref:hop-web-docker.adoc[Hop Web in Docker]
 * xref:hop-logo-and-icons.adoc[Hop logo and icons]
 * xref:hop-vs-kettle/index.adoc[Kettle/PDI and Hop]
diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-gui/hop-web.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/hop-gui/hop-web.adoc
index 678311cfb7..757f6e28de 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/hop-gui/hop-web.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/hop-gui/hop-web.adoc
@@ -79,6 +79,16 @@ When using an environment a project has to be created too
 |```HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS```
 | This is a comma separated list of paths to environment config files 
(including filename and file extension).
 
+|```HOP_CONFIG_FOLDER```
+| Directory for `hop-config.json` and `security/`.
+Point this at a volume so project registrations and users survive replacing 
the container.
+Default in the image is `/usr/local/tomcat/webapps/ROOT/config`.
+
+|```HOP_AUDIT_FOLDER```
+| Per-user UI audit data (`users/<username>/`).
+Default in the image is `/tmp/hop-web-audit`.
+Mount a volume at the same path to keep it across restarts.
+
 |===
 
 Example `docker run` command to start Hop Web with a project and environment:
@@ -89,25 +99,46 @@ docker run -it --rm \
   --env HOP_PROJECT_FOLDER=/project \
   --env HOP_PROJECT_NAME=web-samples \
   --env HOP_ENVIRONMENT_NAME=web-samples-test \
-  --env HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS=/config/web-samples-test.json \
+  --env 
HOP_ENVIRONMENT_CONFIG_FILE_NAME_PATHS=/project-env/web-samples-test.json \
   --name hop-web-test-container \
   -p 8080:8080 \
   -v <PATH_TO_YOUR_PROJECT>:/project \
-  -v <PATH_TO_YOUR_ENVIRONMENT>:/config \
-  hop-web
+  -v <PATH_TO_YOUR_ENVIRONMENT>:/project-env \
+  apache/hop-web
 ----
 
+Do not mount environment JSON at `/config`.
+That path is reserved for Tomcat `tomcat-users.xml` / `web.xml` when you use 
<<hop-web-authentication,EXTERNAL authentication>>.
+
+This example still keeps `hop-config.json` and GUI settings inside the 
container.
+For a layout that survives replacing the image, persist `HOP_CONFIG_FOLDER` 
and the project home on volumes — see below.
+
+[[hop-web-upgrade]]
+== Upgrade-friendly deployment
+
+The `default` and `samples` projects that ship in the image are a starter 
layout.
+Save real pipelines and workflows on the host or on a volume, not under the 
image's own `config/projects/` tree.
+
+Set `HOP_CONFIG_FOLDER` and `HOP_AUDIT_FOLDER` to mounted paths so project 
registrations, security files, and UI audit data survive `docker pull` of a new 
`apache/hop-web` tag.
+The official image already includes the standard plugin set; extra JDBC 
drivers belong on a separate folder or `HOP_DRIVERS_DOWNLOAD`.
+
+The full persist/replace table, Compose example, and upgrade steps are in the 
xref:tech-manual::hop-web-docker.adoc[Hop Web in Docker] technical 
documentation.
+
 == Using the Hop CLI tools in Hop Web.
 
 Hop Web contains the default xref:hop-tools/index.adoc[Hop tools] like 
xref:hop-tools/hop-conf/hop-conf.adoc[hop-conf], 
xref:hop-run/index.adoc[hop-run] etc.
 
 The tools are available in `/usr/local/tomcat/webapps/ROOT` in a running Hop 
Web container.
 
+[[hop-web-authentication]]
 == Authentication
 
 Hop Web runs on a Tomcat server by default and ships with **no 
authentication** (open access).
 For any shared or production deployment you should put an authentication layer 
in front of it.
 
+TIP: Persist `HOP_CONFIG_FOLDER/security/` (or the whole config folder) across 
container upgrades so users, role mappings, and 
xref:tech-manual::hop-web-docker.adoc[project access rules] are not lost.
+See xref:tech-manual::hop-web-docker.adoc[Hop Web in Docker: persistence and 
upgrades].
+
 There are two complementary layers:
 
 * **Authentication (who are you?)** — Hop-managed BASIC form login, 
OAuth2/OIDC, servlet container / reverse proxy (`EXTERNAL`), or open access 
(`NONE`).
@@ -323,6 +354,9 @@ docker run -it --rm -p 8080:8080 \
   apache/hop-web
 ----
 
+This volume keeps `users.json` only.
+To keep project registrations, GUI settings, and 
xref:#hop-web-project-access[project access] rules as well, persist the whole 
`HOP_CONFIG_FOLDER` as shown in xref:tech-manual::hop-web-docker.adoc[Hop Web 
in Docker].
+
 Or from a local source build:
 
 [source,bash]
@@ -346,8 +380,10 @@ image:hop-web-security-configuration-ui.png[Hop Web 
Security configuration (Conf
 
 Save writes `security-config.json` and, for BASIC, `users.json` under 
`HOP_CONFIG_FOLDER/security/`.
 Project access rules are stored in `projects-access.json` in the same folder.
-Existing browser sessions keep their roles until re-login.
+
+[[hop-web-project-access]]
 When project access control is enabled, the project switcher and startup 
project load only show allowed projects; security administrators always retain 
full access. Desktop / unrestricted sessions are not filtered.
+Keep this `security/` directory on the same persisted `HOP_CONFIG_FOLDER` 
volume as `hop-config.json` so upgrades do not drop users or project mappings.
 
 Do **not** combine Hop-managed BASIC with a Tomcat `<security-constraint>` on 
the same deployment; pick one AuthN path.
 
diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-gui/index.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/hop-gui/index.adoc
index bd93500113..178ee81603 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/hop-gui/index.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/hop-gui/index.adoc
@@ -37,4 +37,5 @@ Covered here are:
 * xref:hop-gui/perspective-search.adoc[Search]: Search Everywhere (`CTRL-F`), 
limits, and results panel
 * xref:hop-gui/hop-gui-git.adoc[Working with git]: Manage files in the git 
version control system
 * xref:hop-gui/shortcuts.adoc[Keyboard Shortcuts]: a list of the keyboard 
shortcuts that are available in Hop Gui.
-* xref:hop-gui/hop-web.adoc[Hop Web]: a web version of Hop Gui that provides 
the exact same functionality and user experience as the desktop version
+* xref:hop-gui/hop-web.adoc[Hop Web]: a web version of Hop Gui that provides 
the exact same functionality and user experience as the desktop version.
+For Docker volume mounts and upgrades, see 
xref:tech-manual::hop-web-docker.adoc[Hop Web in Docker].
diff --git 
a/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc
index bf589404e5..79aef31148 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc
@@ -28,7 +28,7 @@ This page covers everything you need to know to install and 
run Apache Hop on yo
 
 Hop is designed to be as flexible and lightweight as possible, and is intended 
to blend in with your architecture, not the other way around. This makes the 
basic installation process extremely easy, but there's a lot of configuration 
that can be applied to make Hop behave exactly the way you want it to.
 
-TIP: Take a look at the xref:tech-manual::docker-container.adoc[Docker] page 
for instructions to run Hop in containers and Kubernetes environments.
+TIP: Take a look at the xref:tech-manual::docker-container.adoc[Docker] page 
for `apache/hop` (hop-run and Hop Server), and 
xref:tech-manual::hop-web-docker.adoc[Hop Web in Docker] for persisting 
projects and config across image upgrades.
 
 == System Requirements
 
@@ -132,6 +132,8 @@ With the environment variables described in the previous 
section, all you need t
 
 TIP: Apache Hop releases are tested for smooth upgrades. You can replace your 
existing installation when a new version is released. If you want to keep 
multiple Apache Hop versions around, consider renaming your unzipped `hop` 
folder to `hop-version-number`, e.g. `hop-2.5.0`, `hop-2.60` etc.
 
+TIP: For Hop Web in Docker, persist `HOP_CONFIG_FOLDER` and project homes on 
volumes and replace the image. See xref:tech-manual::hop-web-docker.adoc[Hop 
Web in Docker: persistence and upgrades].
+
 
 == Additional configuration
 
diff --git a/docs/hop-user-manual/modules/ROOT/pages/projects/index.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/projects/index.adoc
index 66e6b01e0d..f844bc1dcf 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/projects/index.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/projects/index.adoc
@@ -47,6 +47,8 @@ TIP: project variables should only be used when you need 
variables on the projec
 
 TIP: Project configurations are stored in hop-config.json, which is read from 
`hop/config` by default. Use the `HOP_CONFIG_FOLDER` operating system variable 
to store your Hop configuration in a folder outside your Hop folder. This will 
let you keep your project list if you switch Hop installations or upgrade to a 
newer Hop version.
 
+TIP: In Hop Web Docker, keep *project homes* on a host folder or volume as 
well. The image's `default` and `samples` projects are only a starter layout. 
See xref:tech-manual::hop-web-docker.adoc[Hop Web in Docker: persistence and 
upgrades].
+
 Projects can inherit metadata and variables from a parent project.
 
 Projects in Hop Gui will remember opened files, zoom levels and other UI 
settings.

Reply via email to