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
27 changes: 27 additions & 0 deletions hugegraph-server/hugegraph-dist/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,30 @@ native `HEALTHCHECK` instructions. `docker ps` shows real health status:
| `hugegraph/hugegraph-store` | `GET /v1/health` on port 8520 |

The entrypoints supervise the Java process directly — when Java exits, the container exits. If started with a restart policy (the provided compose files use `restart: unless-stopped`), Docker will bring it back automatically. The old cron-based monitor (`-m true`) is for VM/bare-metal deployments only and is not used in Docker images.

## 7. Server Startup Timeout

The entrypoint gives the Server a fixed budget to answer on its REST port and
ends the container when the budget runs out. It is 120 seconds by default. Set
`HG_SERVER_STARTUP_TIMEOUT_S` to a whole number of seconds between 1 and 86400
to change it:

```bash
docker run -itd --name=graph -p 8080:8080 -e HG_SERVER_STARTUP_TIMEOUT_S=450 hugegraph/hugegraph:1.7.0
```

Raise it on slow or contended hosts, and wherever an orchestrator already owns

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🧹 Section 6 directly above says docker ps shows real health status, but the health budget does not move with this variable. For the docker run example above, hugegraph-server/Dockerfile:74 and hugegraph-server/Dockerfile-hstore:76 set --start-period=90s --interval=15s --retries=3, so a container given 450s is marked unhealthy about two minutes in while the entrypoint is still legitimately waiting. The compose files replace that with their own (docker/docker-compose.yml:41-46: start_period: 60s, interval: 10s, retries: 30, so roughly 360s) and hubble gates on it through depends_on: condition: service_healthy, so a timeout raised past that budget blocks dependents rather than only mislabeling the container. Please add a sentence pointing at --health-start-period and the compose start_period.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 6ca3df3. Section 7 now says the health check keeps a budget of its own that this variable does not move: the images' --interval=15s --start-period=90s --retries=3 marks a container unhealthy around 135 seconds, raised with --health-start-period, while the Compose files substitute start_period: 60s, interval: 10s, retries: 30, roughly 360 seconds, which is what depends_on: condition: service_healthy gates Hubble on.

the startup budget through a probe of its own: a startup probe cannot extend a
container that has already ended the JVM it was waiting for. Anything outside
the accepted range, an empty value included, stops the container at startup
instead of silently falling back to the default.

Raising this budget does not move the health check described in section 6,
which runs on a clock of its own. The images set `--interval=15s
--start-period=90s --retries=3`, so a container given a longer startup budget
is reported `unhealthy` around 135 seconds while the entrypoint is still
legitimately waiting; raise it with `--health-start-period` on `docker run`.
The Compose files replace those values with their own (`start_period: 60s`,
`interval: 10s`, `retries: 30`, so roughly 360 seconds), and anything gated on
`depends_on: condition: service_healthy`, Hubble included, waits on that budget
rather than on this variable. Move the two together.
57 changes: 57 additions & 0 deletions hugegraph-server/hugegraph-dist/docker/docker-entrypoint-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ backend=rocksdb
EOF
cat > "${TEST_HOME}/bin/start-hugegraph.sh" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$*" >> ./docker/start-hugegraph-args
exit 0
EOF
cat > "${TEST_HOME}/bin/init-store.sh" <<'EOF'
Expand Down Expand Up @@ -232,4 +233,60 @@ rm -f "${TEST_HOME}/docker/init_complete"
)
grep -Fqx -- '-n' "${TEST_HOME}/docker/init-store-password"

last_start_args() { tail -n 1 "${TEST_HOME}/docker/start-hugegraph-args"; }

[[ "$(last_start_args)" == *"-t 120"* ]]

(
cd "${TEST_HOME}"
HG_SERVER_STARTUP_TIMEOUT_S=450 bash ./docker-entrypoint.sh
)
[[ "$(last_start_args)" == *"-t 450"* ]]

(
cd "${TEST_HOME}"
HG_SERVER_STARTUP_TIMEOUT_S=86400 bash ./docker-entrypoint.sh
)
[[ "$(last_start_args)" == *"-t 86400"* ]]

# An empty value is a set value, not an absent one: Compose writes it whenever
# an interpolated host variable is missing. 2m is the shape of a typo, and the
# two large values bracket the point where the deadline arithmetic in
# wait_for_startup would wrap negative and end the wait before its first probe.
for invalid_timeout in "" " " 0 +5 2m 86401 9223372036854775807; do
start_calls_before_invalid=$(wc -l < "${TEST_HOME}/docker/start-hugegraph-args")
init_calls_before_invalid=$(wc -l < "${TEST_HOME}/docker/init-store-calls")
if (
cd "${TEST_HOME}"
HG_SERVER_STARTUP_TIMEOUT_S="${invalid_timeout}" \
bash ./docker-entrypoint.sh
); then
echo "startup timeout '${invalid_timeout}' unexpectedly succeeded" >&2
exit 1
fi
# The server must not have started, and the guard must have run ahead of
# init-store, as the comment above it in the entrypoint claims. Spelled
# with an explicit exit rather than a bare [[ ]]: bash 3.2, still the
# /bin/bash of macOS, does not apply set -e to a failing [[ ]], so a bare
# assertion passes silently there while CI catches the regression.
[[ "$(wc -l < "${TEST_HOME}/docker/start-hugegraph-args")" -eq \
"${start_calls_before_invalid}" ]] || {
echo "startup timeout '${invalid_timeout}' started the server" >&2
exit 1
}
[[ "$(wc -l < "${TEST_HOME}/docker/init-store-calls")" -eq \
"${init_calls_before_invalid}" ]] || {
echo "startup timeout '${invalid_timeout}' was rejected only after" \
"init-store ran" >&2
exit 1
}
done

# An unset variable still keeps the historical default.
(
cd "${TEST_HOME}"
bash ./docker-entrypoint.sh
)
[[ "$(last_start_args)" == *"-t 120"* ]]

echo "PASS: Docker entrypoint configures HStore discovery and authentication"
25 changes: 24 additions & 1 deletion hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,29 @@ if [[ -n "${HG_SERVER_AUTH_TOKEN_SECRET:-}" ]]; then
fi
fi

# How long the entrypoint lets the server take to answer on its REST port
# before it gives up and ends the container. An orchestrator that already
# owns this budget through a startup probe needs to raise it, otherwise the
# container terminates a JVM that is still starting and the probe never gets
# to decide. Validated here so a bad value fails before init-store runs,
# rather than reaching the arithmetic in wait_for_startup: that deadline is
# $((now_s + timeout_s)), which wraps negative near the 64-bit ceiling and
# makes the wait exit before its first probe, the very failure this variable
# exists to avoid. The five-digit bound keeps this comparison in range too,
# and a day is already far past any real start. Plain '-' rather than ':-',
# so an explicitly empty value is rejected instead of quietly becoming the
# default: Compose interpolation such as ${SOME_VAR:-} yields empty, not
# unset, whenever the host variable is missing.
SERVER_STARTUP_TIMEOUT_MAX_S=86400
SERVER_STARTUP_TIMEOUT_S="${HG_SERVER_STARTUP_TIMEOUT_S-120}"
if [[ ! "${SERVER_STARTUP_TIMEOUT_S}" =~ ^[1-9][0-9]{0,4}$ ]] ||
(( SERVER_STARTUP_TIMEOUT_S > SERVER_STARTUP_TIMEOUT_MAX_S )); then
log "ERROR: HG_SERVER_STARTUP_TIMEOUT_S must be a whole number of" \
"seconds from 1 to ${SERVER_STARTUP_TIMEOUT_MAX_S}," \
"got '${SERVER_STARTUP_TIMEOUT_S}'"
exit 1
fi

if [[ -n "${PASSWORD:-}" &&
"${HG_SERVER_REQUIRE_AUTH_TOKEN_SECRET:-false}" == "true" &&
-z "${HG_SERVER_AUTH_TOKEN_SECRET:-}" ]]; then
Expand Down Expand Up @@ -217,7 +240,7 @@ else
./bin/init-store.sh
fi

./bin/start-hugegraph.sh -j "${JAVA_OPTS:-}" -t 120
./bin/start-hugegraph.sh -j "${JAVA_OPTS:-}" -t "${SERVER_STARTUP_TIMEOUT_S}"

# Post-startup cluster stabilization check (hstore only — rocksdb has no partitions)
ACTUAL_BACKEND=$(grep -E '^[[:space:]]*backend[[:space:]]*=' "${GRAPH_CONF}" | head -n 1 | sed 's/.*=//' | tr -d '[:space:]' || true)
Expand Down
Loading