chore: import upstream snapshot with attribution
docmd CI verification / verify (push) Failing after 0s
docmd CI verification / verify (push) Failing after 0s
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
# docmd Docker entrypoint
|
||||
#
|
||||
# Handles two cases:
|
||||
#
|
||||
# 1. No volume / empty /docs → seeds the demo template so `docmd dev`
|
||||
# works out of the box with no arguments.
|
||||
#
|
||||
# 2. Host-mounted volume → detects the uid:gid that owns /docs and
|
||||
# re-execs as that identity (via su-exec), so file writes from any
|
||||
# subcommand — including `docmd init` — land with the correct host
|
||||
# ownership without needing `-u $(id -u):$(id -g)` from the caller.
|
||||
#
|
||||
# This mirrors the pattern used by official images (postgres, redis, etc.).
|
||||
set -e
|
||||
|
||||
FIRST_ARG="${1:-}"
|
||||
|
||||
# ── uid remapping ────────────────────────────────────────────────────────────
|
||||
# If we are currently running as root (the entrypoint is exec'd as root so it
|
||||
# can inspect /docs ownership), detect the uid:gid of /docs and re-exec as
|
||||
# that user. This lets `docmd init` and `docmd dev` write to host-mounted
|
||||
# volumes without permission errors regardless of the host user's uid.
|
||||
if [ "$(id -u)" = "0" ] && [ -d /docs ]; then
|
||||
DOCS_UID=$(stat -c '%u' /docs 2>/dev/null || echo "1001")
|
||||
DOCS_GID=$(stat -c '%g' /docs 2>/dev/null || echo "1001")
|
||||
|
||||
# If /docs is owned by root (uid 0) on the host, fall back to the docmd
|
||||
# user — writing as root inside the container is a security anti-pattern.
|
||||
if [ "$DOCS_UID" = "0" ]; then
|
||||
DOCS_UID="1001"
|
||||
DOCS_GID="1001"
|
||||
fi
|
||||
|
||||
# ── writability check (N-18) ───────────────────────────────────────────
|
||||
# Catch read-only volume mounts early with a clear message instead of
|
||||
# letting docmd crash mid-build with a cryptic EROFS / EACCES error.
|
||||
# Only applies to write commands — `dev`, `build`, `init`.
|
||||
# Read-only mounts are valid for `validate`, `mcp`, etc.
|
||||
case "$FIRST_ARG" in
|
||||
dev|build|init)
|
||||
if ! touch /docs/.docmd_write_test 2>/dev/null; then
|
||||
printf '\n[docmd] ERROR: /docs is read-only (or not writable by uid %s).\n' "$DOCS_UID" >&2
|
||||
printf '[docmd] Mount a writable directory:\n' >&2
|
||||
printf '[docmd] docker run -v $(pwd)/docs:/docs ghcr.io/docmd-io/docmd\n' >&2
|
||||
printf '[docmd] Or check directory permissions on the host.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
rm -f /docs/.docmd_write_test
|
||||
;;
|
||||
esac
|
||||
|
||||
# Seed demo template before dropping privileges (root can always write).
|
||||
if [ "$FIRST_ARG" != "init" ] && \
|
||||
[ -z "$(ls -A /docs 2>/dev/null)" ] && \
|
||||
[ -d /template ]; then
|
||||
echo "[docmd] /docs is empty — seeding demo template from /template"
|
||||
cp -r /template/. /docs/
|
||||
chown -R "$DOCS_UID:$DOCS_GID" /docs 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Re-exec as the detected uid:gid so all subsequent writes are correctly owned.
|
||||
exec su-exec "$DOCS_UID:$DOCS_GID" "$0" "$@"
|
||||
fi
|
||||
|
||||
# ── already the right user (re-exec path lands here) ────────────────────────
|
||||
exec docmd "$@"
|
||||
Reference in New Issue
Block a user