mirror of
https://github.com/tale/headplane.git
synced 2026-08-29 00:17:13 +00:00
feat: add docker health check
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
- Correctly apply Gravatar profile pictures on the user page if applicable (closes [#405](https://github.com/tale/headplane/issues/405)).
|
- Correctly apply Gravatar profile pictures on the user page if applicable (closes [#405](https://github.com/tale/headplane/issues/405)).
|
||||||
- Machine key registration no longer works if the key isn't 24 characters long (closes [#415](https://github.com/tale/headplane/issues/415)).
|
- Machine key registration no longer works if the key isn't 24 characters long (closes [#415](https://github.com/tale/headplane/issues/415)).
|
||||||
- Fixed some mobile CSS issues across the application (closes [#401](https://github.com/tale/headplane/issues/401)).
|
- Fixed some mobile CSS issues across the application (closes [#401](https://github.com/tale/headplane/issues/401)).
|
||||||
|
- Added a Docker healthcheck to the container (closes [#411](https://github.com/tale/headplane/issues/411)).
|
||||||
---
|
---
|
||||||
|
|
||||||
# 0.6.1 (October 12, 2025)
|
# 0.6.1 (October 12, 2025)
|
||||||
|
|||||||
+12
-2
@@ -11,14 +11,16 @@ ARG TARGETOS
|
|||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG IMAGE_TAG
|
ARG IMAGE_TAG
|
||||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 IMAGE_TAG=$IMAGE_TAG \
|
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 IMAGE_TAG=$IMAGE_TAG \
|
||||||
./build.sh --wasm --agent --fake-shell \
|
./build.sh --wasm --agent --fake-shell --healthcheck \
|
||||||
--wasm-output /bin/hp_ssh.wasm \
|
--wasm-output /bin/hp_ssh.wasm \
|
||||||
--agent-output /bin/hp_agent \
|
--agent-output /bin/hp_agent \
|
||||||
--fake-shell-output /bin/fake-sh
|
--fake-shell-output /bin/fake-sh \
|
||||||
|
--healthcheck-output /bin/hp_healthcheck
|
||||||
|
|
||||||
RUN chmod +x /bin/hp_ssh.wasm
|
RUN chmod +x /bin/hp_ssh.wasm
|
||||||
RUN chmod +x /bin/hp_agent
|
RUN chmod +x /bin/hp_agent
|
||||||
RUN chmod +x /bin/fake-sh
|
RUN chmod +x /bin/fake-sh
|
||||||
|
RUN chmod +x /bin/hp_healthcheck
|
||||||
|
|
||||||
# Folder needs to exist for later stages
|
# Folder needs to exist for later stages
|
||||||
RUN mkdir -p /var/lib/headplane/agent
|
RUN mkdir -p /var/lib/headplane/agent
|
||||||
@@ -49,6 +51,10 @@ COPY --from=go-base /var/lib/headplane /var/lib/headplane
|
|||||||
COPY --from=go-base /bin/fake-sh /bin/sh
|
COPY --from=go-base /bin/fake-sh /bin/sh
|
||||||
COPY --from=go-base /bin/fake-sh /bin/bash
|
COPY --from=go-base /bin/fake-sh /bin/bash
|
||||||
|
|
||||||
|
COPY --from=go-base /bin/hp_healthcheck /bin/hp_healthcheck
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
||||||
|
CMD ["/bin/hp_healthcheck"]
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
CMD [ "/app/build/server/index.js" ]
|
CMD [ "/app/build/server/index.js" ]
|
||||||
|
|
||||||
@@ -61,6 +67,10 @@ COPY --from=js-base /run/node_modules /app/node_modules
|
|||||||
|
|
||||||
COPY --from=go-base /bin/hp_agent /usr/libexec/headplane/agent
|
COPY --from=go-base /bin/hp_agent /usr/libexec/headplane/agent
|
||||||
COPY --from=go-base /var/lib/headplane /var/lib/headplane
|
COPY --from=go-base /var/lib/headplane /var/lib/headplane
|
||||||
|
COPY --from=go-base /bin/hp_healthcheck /bin/hp_healthcheck
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
||||||
|
CMD ["/bin/hp_healthcheck"]
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
CMD [ "node", "/app/build/server/index.js" ]
|
CMD [ "node", "/app/build/server/index.js" ]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ BUILD_WASM=0
|
|||||||
BUILD_APP=0
|
BUILD_APP=0
|
||||||
BUILD_AGENT=0
|
BUILD_AGENT=0
|
||||||
BUILD_FAKE_SHELL=0
|
BUILD_FAKE_SHELL=0
|
||||||
|
BUILD_HEALTHCHECK=0
|
||||||
SKIP_PATH_CHECKS=0
|
SKIP_PATH_CHECKS=0
|
||||||
SKIP_PNPM_PRUNE=0
|
SKIP_PNPM_PRUNE=0
|
||||||
APP_INSTALL_ONLY=0
|
APP_INSTALL_ONLY=0
|
||||||
@@ -23,6 +24,7 @@ APP_INSTALL_ONLY=0
|
|||||||
WASM_OUTPUT="$PUBLIC_DIR/hp_ssh.wasm"
|
WASM_OUTPUT="$PUBLIC_DIR/hp_ssh.wasm"
|
||||||
AGENT_OUTPUT="$BUILD_DIR/hp_agent"
|
AGENT_OUTPUT="$BUILD_DIR/hp_agent"
|
||||||
FAKE_SHELL_OUTPUT="$BUILD_DIR/hp_fake_sh"
|
FAKE_SHELL_OUTPUT="$BUILD_DIR/hp_fake_sh"
|
||||||
|
HEALTHCHECK_OUTPUT="$BUILD_DIR/hp_healthcheck"
|
||||||
|
|
||||||
die() { echo "error: $*" >&2; exit 1; }
|
die() { echo "error: $*" >&2; exit 1; }
|
||||||
run() { echo ">> $*"; "$@"; }
|
run() { echo ">> $*"; "$@"; }
|
||||||
@@ -33,6 +35,7 @@ while [ $# -gt 0 ]; do
|
|||||||
--app) BUILD_APP=1 ;;
|
--app) BUILD_APP=1 ;;
|
||||||
--agent) BUILD_AGENT=1 ;;
|
--agent) BUILD_AGENT=1 ;;
|
||||||
--fake-shell) BUILD_FAKE_SHELL=1 ;;
|
--fake-shell) BUILD_FAKE_SHELL=1 ;;
|
||||||
|
--healthcheck) BUILD_HEALTHCHECK=1 ;;
|
||||||
--skip-path-checks) SKIP_PATH_CHECKS=1 ;;
|
--skip-path-checks) SKIP_PATH_CHECKS=1 ;;
|
||||||
--skip-pnpm-prune) SKIP_PNPM_PRUNE=1 ;;
|
--skip-pnpm-prune) SKIP_PNPM_PRUNE=1 ;;
|
||||||
--app-install-only) APP_INSTALL_ONLY=1 ;;
|
--app-install-only) APP_INSTALL_ONLY=1 ;;
|
||||||
@@ -55,6 +58,12 @@ while [ $# -gt 0 ]; do
|
|||||||
FAKE_SHELL_OUTPUT=$1
|
FAKE_SHELL_OUTPUT=$1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--healthcheck-output)
|
||||||
|
shift
|
||||||
|
[ $# -gt 0 ] || die "--healthcheck-output requires a path"
|
||||||
|
HEALTHCHECK_OUTPUT=$1
|
||||||
|
;;
|
||||||
|
|
||||||
--help)
|
--help)
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $0 [flags]
|
Usage: $0 [flags]
|
||||||
@@ -62,12 +71,14 @@ Usage: $0 [flags]
|
|||||||
--app build react-router app
|
--app build react-router app
|
||||||
--agent build tailscale agent
|
--agent build tailscale agent
|
||||||
--fake-shell build fake shell binary (for Docker)
|
--fake-shell build fake shell binary (for Docker)
|
||||||
|
--healthcheck build healthcheck binary
|
||||||
--skip-path-checks skip safety checks (ie. checking PATH)
|
--skip-path-checks skip safety checks (ie. checking PATH)
|
||||||
--skip-pnpm-prune skip pruning devDependencies from node_modules
|
--skip-pnpm-prune skip pruning devDependencies from node_modules
|
||||||
--app-install-only only install app dependencies, skip build
|
--app-install-only only install app dependencies, skip build
|
||||||
--wasm-output <path> override wasm output path
|
--wasm-output <path> override wasm output path
|
||||||
--agent-output <path> override agent output path
|
--agent-output <path> override agent output path
|
||||||
--fake-shell-output <path> override fake shell output path
|
--fake-shell-output <path> override fake shell output path
|
||||||
|
--healthcheck-output <path> override healthcheck output path
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
@@ -84,6 +95,8 @@ if [ "$BUILD_WASM" -eq 0 ] && [ "$BUILD_APP" -eq 0 ] && \
|
|||||||
BUILD_WASM=1
|
BUILD_WASM=1
|
||||||
BUILD_APP=1
|
BUILD_APP=1
|
||||||
BUILD_AGENT=1
|
BUILD_AGENT=1
|
||||||
|
BUILD_HEALTHCHECK=1
|
||||||
|
BUILD_FAKE_SHELL=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$SKIP_PATH_CHECKS" -eq 0 ]; then
|
if [ "$SKIP_PATH_CHECKS" -eq 0 ]; then
|
||||||
@@ -96,6 +109,7 @@ if [ "$SKIP_PATH_CHECKS" -eq 0 ]; then
|
|||||||
[ "$BUILD_APP" -eq 1 ] && need_pnpm=1
|
[ "$BUILD_APP" -eq 1 ] && need_pnpm=1
|
||||||
[ "$BUILD_AGENT" -eq 1 ] && need_go=1
|
[ "$BUILD_AGENT" -eq 1 ] && need_go=1
|
||||||
[ "$BUILD_FAKE_SHELL" -eq 1 ] && need_go=1
|
[ "$BUILD_FAKE_SHELL" -eq 1 ] && need_go=1
|
||||||
|
[ "$BUILD_HEALTHCHECK" -eq 1 ] && need_go=1
|
||||||
|
|
||||||
if [ $need_go -eq 1 ]; then
|
if [ $need_go -eq 1 ]; then
|
||||||
echo "==> Checking for Go toolchain"
|
echo "==> Checking for Go toolchain"
|
||||||
@@ -160,11 +174,16 @@ build_fake_shell() {
|
|||||||
-o "$FAKE_SHELL_OUTPUT" ./cmd/fake_sh
|
-o "$FAKE_SHELL_OUTPUT" ./cmd/fake_sh
|
||||||
}
|
}
|
||||||
|
|
||||||
[ "$BUILD_FAKE_SHELL" = 1 ] && build_fake_shell
|
build_healthcheck() {
|
||||||
|
echo "==> Building healthcheck binary → $HEALTHCHECK_OUTPUT"
|
||||||
|
mkdir -p "$(dirname "$HEALTHCHECK_OUTPUT")"
|
||||||
|
go build -o "$HEALTHCHECK_OUTPUT" ./cmd/hp_healthcheck
|
||||||
|
}
|
||||||
|
|
||||||
[ "$BUILD_WASM" = 1 ] && build_wasm
|
[ "$BUILD_WASM" = 1 ] && build_wasm
|
||||||
[ "$BUILD_APP" = 1 ] && build_app
|
[ "$BUILD_APP" = 1 ] && build_app
|
||||||
[ "$BUILD_AGENT" = 1 ] && build_agent
|
[ "$BUILD_AGENT" = 1 ] && build_agent
|
||||||
[ "$BUILD_FAKE_SHELL" = 1 ] && build_fake_shell
|
[ "$BUILD_FAKE_SHELL" = 1 ] && build_fake_shell
|
||||||
|
[ "$BUILD_HEALTHCHECK" = 1 ] && build_healthcheck
|
||||||
|
|
||||||
echo "✅ Build complete."
|
echo "✅ Build complete."
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Get("http://localhost:3000/admin/healthz")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Health check failed: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
fmt.Fprintf(os.Stderr, "Health check returned non-OK status: %d\n", resp.StatusCode)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Health check passed.")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
@@ -39,6 +39,28 @@ It's important to mount your configuration file and also provide a persistent
|
|||||||
storage location for Headplane to store its own data. You can also change the
|
storage location for Headplane to store its own data. You can also change the
|
||||||
port mapping if you want to run it on a different port.
|
port mapping if you want to run it on a different port.
|
||||||
|
|
||||||
|
## Health Checks
|
||||||
|
|
||||||
|
The Docker image includes a built-in healthcheck that verifies the Headplane
|
||||||
|
server is running and responding. Docker will automatically monitor the
|
||||||
|
container and report its health status. No additional configuration is required.
|
||||||
|
|
||||||
|
The healthcheck binary is located at `/bin/hp_healthcheck` inside the container.
|
||||||
|
If you need to override the default healthcheck behavior, you can do so in your
|
||||||
|
`compose.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
headplane:
|
||||||
|
image: ghcr.io/tale/headplane:latest
|
||||||
|
healthcheck:
|
||||||
|
test: ["/bin/hp_healthcheck"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
start_period: 5s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
## Accessing Headplane
|
## Accessing Headplane
|
||||||
|
|
||||||
After starting the container, you can access the Headplane web interface by
|
After starting the container, you can access the Headplane web interface by
|
||||||
|
|||||||
Reference in New Issue
Block a user