Skip to content
Merged
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
33 changes: 26 additions & 7 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
#!/bin/sh
# Runs as root so we can fix ownership of a freshly-mounted persistent disk
# (Render mounts new disks root-owned) before dropping to the non-root app user.
# Prepares the (possibly root-owned, freshly-mounted) data disk and runs the app
# as the non-root nanobot user when the platform allows it, falling back to root
# only when privilege-dropping is not permitted. Logs each decision so a failed
# start is diagnosable in the platform's logs instead of a silent exit.
echo "[entrypoint] starting as $(id)"

dir="$HOME/.nanobot"
mkdir -p "$dir"
chown -R nanobot:nanobot "$dir"
mkdir -p "$dir" 2>&1 || echo "[entrypoint] warning: mkdir $dir failed"

if [ "$(id -u)" != "0" ]; then
# Already non-root (platform forced a user). Can't chown; just run.
echo "[entrypoint] not root — running app as $(id -un 2>/dev/null || id -u)"
exec nanobot "$@"
fi

# Running as root: make the mounted disk writable by the app user.
chown -R nanobot:nanobot "$dir" 2>&1 || echo "[entrypoint] warning: chown $dir failed"

# Drop to the non-root user if the runtime grants the capability to do so
# (setpriv needs CAP_SETUID/CAP_SETGID). Otherwise stay root so the app can
# still write the root-owned disk.
if setpriv --reuid=nanobot --regid=nanobot --init-groups true 2>/dev/null; then
echo "[entrypoint] dropping privileges to nanobot via setpriv"
exec setpriv --reuid=nanobot --regid=nanobot --init-groups nanobot "$@"
fi

# Drop privileges to the non-root user and exec the app as PID 1 so signals
# (SIGTERM / graceful shutdown) reach it directly.
exec setpriv --reuid=nanobot --regid=nanobot --init-groups nanobot "$@"
echo "[entrypoint] setpriv privilege-drop not permitted — running app as root"
exec nanobot "$@"
8 changes: 5 additions & 3 deletions render.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ services:
runtime: docker
dockerfilePath: ./Dockerfile
dockerContext: .
# entrypoint.sh execs `nanobot "$@"`, so this becomes:
# nanobot gateway --config /app/render-config.json
dockerCommand: gateway --config /app/render-config.json
# Render's Docker Command REPLACES the Dockerfile ENTRYPOINT (it is not
# appended to it), so invoke the entrypoint explicitly. The entrypoint
# prepares the mounted disk, drops to the non-root user when permitted, then
# execs `nanobot gateway --config /app/render-config.json`.
dockerCommand: /usr/local/bin/entrypoint.sh gateway --config /app/render-config.json
plan: starter
healthCheckPath: /
envVars:
Expand Down
Loading