Repository navigation
Conversation
…allation Guide Add the procedures "To Run OpenDJ in Docker", "To Upgrade a Docker Container" and "To Remove a Docker Container", point the preface to the first of them, and add notes to the replication and certificates chapters of the Administration Guide about what the image manages itself. The environment variables, health check, replication and certificates of the image stay described in opendj-packages/opendj-docker/README.md only, which the new text links to instead of repeating it.
maximthomas
left a comment
There was a problem hiding this comment.
praise: The upgrade and revert procedures handle the parts that are easy to get wrong.
- The backup runs under
umask 077in a throwaway container and says why: the archive holds the server's keys and the password hashes (chap-upgrade.adoc:331-338). - The revert restores into an empty volume (
docker volume rm opendj-databefore the extract) and gives the reason: files that the upgrade added would otherwise stay behind (chap-upgrade.adoc:366-374). - The upgrade step warns that from 5.2.0 the health check searches anonymously, so an instance with
reject-unauthenticated-requests:trueneedsHEALTHCHECK_BIND_DN/HEALTHCHECK_BIND_PASSWORD_FILE(chap-upgrade.adoc:354).
issue (non-blocking): The guide presents ROOT_PASSWORD as the root password, but the image reads it on the first start only.
opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-install.adoc:679
run.sh reads ROOT_PASSWORD only on the bootstrap road (run.sh:183, bootstrap/setup.sh:51). A container started over an existing instance goes through run.sh:137-174 (upgrade, marker, start_server) and never reads it. Take a reader who ran the example with password and then follows ":679 before you publish them on other interfaces, set a ROOT_PASSWORD of your own": they recreate the container with a new ROOT_PASSWORD and the ports on all interfaces. The server comes up healthy and exposed, and its root password is still password. The README says "only the initial root password" (README.md:34); the guide does not.
The example publishes these ports on the loopback interface of the host only; before you publish them on other interfaces, set a `ROOT_PASSWORD` of your own on the first start. The image reads `ROOT_PASSWORD` only when it creates the instance: a container started over an instance that is already there keeps the root password of that instance, which you change with `ldappasswordmodify` as on any other server. The root user is `cn=Directory Manager`, with the initial password `ROOT_PASSWORD`, and the base DN is `dc=example,dc=com`; without `ADD_BASE_ENTRY` that suffix is created empty.suggestion (non-blocking): The guide does not say what to do after a failed first start. A later start over the same volume can report healthy on a half-bootstrapped instance.
opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-install.adoc:689, :702
Suppose setup has written data/config and then dsconfig create-backend (bootstrap/setup.sh:86-88) or the import fails. The first start stays unhealthy (run.sh:195-198), as the text says. The next start can come from docker start, which :702 offers, from docker restart, from a restart policy, or from docker rm plus docker run with fixed variables. In every case it deletes the marker (run.sh:35), finds ./data/config (:137) and runs upgrade -n --force. On equal versions that exits 0 (Upgrade.java:994-999), and :161 writes the marker. The container then reports healthy with no userRoot backend or no base entry. That contradicts ":689 healthy once all of this has succeeded".
A first start that fails never reports healthy: what failed is in `docker logs opendj`. To try again, remove the container and its volume, with `docker rm -f opendj` and `docker volume rm opendj-data`, then start over: a container started over the volume of a failed first start takes it for an installed instance, and can report itself healthy without the backend or the base entry.suggestion (non-blocking): The backup, step 3 and the revert hard-code the volume opendj-data. Nothing tells the reader to use the name step 1 printed, and a bind mount cannot be backed up this way.
opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc:313-319, :337, :350, :372-374
Step 1 lists {{.Name}} {{.Destination}}. It counts the instance as on a volume when any mount is at /opt/opendj/data, so a compose-prefixed or anonymous volume passes, and so does a bind mount, which prints an empty name. Step 2 then runs -v opendj-data:/data as written. Docker creates a new empty opendj-data, tar archives only ./ and exits 0, and the revert later restores that empty archive. Step 3's "over the same volume, with every other option of the old container" covers step 3 only.
The following steps use the volume `opendj-data`: use the name that the command printed instead. An empty name is a bind mount of a host directory, which the following command shows; back up that directory instead of running the commands of the next step, and mount it again in step 3:
+
[source, console]
----
$ docker inspect -f '{{range .Mounts}}{{.Source}} {{.Destination}}{{println}}{{end}}' opendj
----suggestion (non-blocking): No CI step starts the build image over a volume written by a released image, so the road this procedure documents has no observable.
opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc:306
CI reuses volumes only between containers of the same build image (build.yml:640/:675, docker-test-replication.sh). Released images run only in the benchmark (build.yml:847/:1222), with no volume. A restart on the same image does reach run.sh:142, but Upgrade.isVersionCanBeUpdated returns success on equal versions before any task runs (Upgrade.java:994-999). A 5.1.x to 5.2.0 regression in the image's upgrade-on-start therefore stays green in every cell. The PR's own run, 5.1.2 over 5.1.2, was the same no-op.
- name: Docker test upgrade from a released image
shell: bash
run: |
docker run -d --name test_upgrade --init -e ADD_BASE_ENTRY=--addBaseEntry \
-v test_upgrade_data:/opt/opendj/data openidentityplatform/opendj:5.1.2
timeout 5m bash -c 'until docker exec test_upgrade /opt/opendj/bin/ldapsearch --port 1389 --bindDN "cn=Directory Manager" --bindPassword password --baseDN dc=example,dc=com --searchScope base "(objectClass=*)" dn 2>/dev/null | grep -q "^dn: dc=example,dc=com"; do sleep 5; done'
docker stop -t 60 test_upgrade && docker rm test_upgrade
docker run -d --name test_upgrade --init -v test_upgrade_data:/opt/opendj/data "$IMAGE"
timeout 10m bash -c 'until [ "$(docker inspect -f "{{.State.Health.Status}}" test_upgrade)" = healthy ]; do sleep 5; done'
docker exec test_upgrade /opt/opendj/bin/ldapsearch --port 1389 --bindDN "cn=Directory Manager" --bindPassword password \
--baseDN dc=example,dc=com --searchScope base "(objectClass=*)" dn | grep -q "^dn: dc=example,dc=com"Pin: the step goes red when the new image fails to upgrade or serve a 5.1.2 volume. Not run. The first wait polls the base entry because the 5.1.2 health check turned healthy before import-ldif ended.
nitpick (non-blocking): "so only the administrators of the server may be able to read it" reads as a possibility, not as a requirement.
opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc:331
The archive holds the private keys of the server and the password hashes of its users, so make sure that only the administrators of the server can read it:…o after a failed first start, and which volume the Docker upgrade backs up The Docker image reads ROOT_PASSWORD only when it creates the instance, and a container started over the volume of a failed first start can report itself healthy without the backend (OpenIdentityPlatform#1182), so the install procedure says to remove that volume before trying again. The upgrade procedure uses the volume name that its first step prints, and backs up a bind mount as a host directory instead of archiving a fresh empty volume.
|
Thank you for the review. All five points hold against the code. Four of them are in f5e8ca0; the CI step is tracked separately.
Restart after a failed first start. Confirmed, and reproduced on an image built from master: with Hard-coded volume name. Confirmed: an empty No CI for an upgrade from a released image. Agreed. You are also right that my own run, 5.1.2 over 5.1.2, upgraded nothing; I have corrected the Testing section of the description. The step tests the image rather than this text, so it is #1183, with your sketch. If it finds a 5.1.x volume that the current image cannot upgrade, that deserves its own fix rather than holding this documentation back. "may be able to read". Taken as suggested. |
Problem
The AsciiDoc guides say almost nothing about the Docker image. Docker comes up once, in passing, in
install-guide/chap-upgrade.adoc("as do the Docker image and the native packages, which runupgrade --no-prompt --force"). The Installation Guide has procedures for ZIP, GUI, CLI,.deb,.rpmand MSI, but none for Docker: not for installing, not for upgrading, not for removing. The replication and certificates chapters do not mention that the image manages both itself.Change
Each new piece links to
opendj-packages/opendj-docker/README.md. The README stays the only place that describes the environment variables, the health check, replication and certificates of the image, so this PR does not repeat any of that.Installation Guide
chap-install.adoc: a new procedure, To Run OpenDJ in Docker (#install-docker). It covers:docker runwith a volume at/opt/opendj/dataand--init, and why the volume is needed: the image declares noVOLUME;ROOT_PASSWORDon the first start before you publish them on other interfaces: the image reads it only when it creates the instance;healthy, then a check withldapsearch;"To Prepare For Installation" also points to it.
chap-upgrade.adoc: a new procedure, To Upgrade a Docker Container (#upgrade-docker). Its steps:docker cp … - | tar -xif it is not. The following steps use the volume name that this check prints; a bind mount is backed up as a host directory.docker stop -t 60and atarunderumask 077. The archive holds keys and password hashes.reject-unauthenticated-requests:true, setHEALTHCHECK_BIND_DN/HEALTHCHECK_BIND_PASSWORD_FILE. Images before 5.2.0 probed as the root user, the current one probes anonymously ([#1092] Probe the Docker container's health without binding as the root user #1102).healthy, and expect long upgrade tasks to keep the containerunhealthypast the start period.It also gives a revert, which restores into an empty volume, and points to
#upgrade-replfor rolling upgrades. The passing mention of the Docker image now links to this procedure.chap-uninstall.adoc: a new procedure, To Remove a Docker Container (#uninstall-docker). It says whendsreplication disableis still needed: onlyOPENDJ_REPLICATION_TYPE=simplewithREPLICATION_PEERSremoves a server registered by name. It gives the order: remove the container first, then recreate every other container without it inREPLICATION_PEERS. The environment of a container cannot be changed, so a restart is not enough. The last step removes the volume.preface.adoc: one sentence pointing "just trying it" readers to the Docker procedure.Administration Guide
chap-replication.adoc: a NOTE saying that the image joins the topology itself and that, withREPLICATION_PEERS, it removes servers that are not listed. It says how to add a server: list it in every container first, then start it. It says how to remove one: remove its container first, then update the list everywhere. A server registered by an address is never removed.chap-change-certs.adoc: a NOTE on the image's certificate handling:key*/trust*files onSECRET_VOLUMEare copied into the instance, on start and, by default, while the server runs.admin-keystore,admin-truststoreandads-truststorestay in the instance and are replaced with the procedures of this chapter.Testing
-v) without warnings. The new anchors resolve,{opendj-version}is substituted, and{{.State.Health.Status}}stays verbatim.openidentityplatform/opendjimage (5.1.2): the installdocker run, theldapsearchcheck (it printsdn: dc=example,dc=com), the volume backup, a new container of the same image over the same volume (its start ranupgrade, which is a no-op on equal versions, and the data was kept), and the removal steps.1001:0: thedocker inspectmount check, the backup underumask 077(the archive is-rw-------), the restore into a fresh volume, and the move withdocker cp … -. Owner and modes are kept, including on the volume root.3f4deb9178: after a first start that failed increate-backend,docker restartreportedhealthywith onlyadminRoot, which is why the install procedure says to remove the volume (Docker image: a restart after a failed first start reports healthy over a half-bootstrapped volume #1182).healthycomes only after the whole bootstrap. The 5.1.2 image still has the old health check, which turnedhealthybeforeimport-ldifhad finished. The text followshealthcheck.shon master, which is what the next release ships.