mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(docker): fix HERMES_UID permission handling and add docker-compose.yml
- Remove 'USER hermes' from Dockerfile so entrypoint runs as root and can usermod/groupmod before gosu drop. Add chmod -R a+rX /opt/hermes so any remapped UID can read the install directory. - Fix entrypoint chown logic: always chown -R when HERMES_UID is remapped from default 10000, not just when top-level dir ownership mismatches. - Add docker-compose.yml with gateway + dashboard services. - Add .hermes to .gitignore.
This commit is contained in:
parent
ccc8fccf77
commit
14c9f7272c
3 changed files with 49 additions and 4 deletions
10
Dockerfile
10
Dockerfile
|
|
@ -41,9 +41,15 @@ COPY --chown=hermes:hermes . .
|
||||||
# Build web dashboard (Vite outputs to hermes_cli/web_dist/)
|
# Build web dashboard (Vite outputs to hermes_cli/web_dist/)
|
||||||
RUN cd web && npm run build
|
RUN cd web && npm run build
|
||||||
|
|
||||||
|
# ---------- Permissions ----------
|
||||||
|
# Make install dir world-readable so any HERMES_UID can read it at runtime.
|
||||||
|
# The venv needs to be traversable too.
|
||||||
|
USER root
|
||||||
|
RUN chmod -R a+rX /opt/hermes
|
||||||
|
# Start as root so the entrypoint can usermod/groupmod + gosu.
|
||||||
|
# If HERMES_UID is unset, the entrypoint drops to the default hermes user (10000).
|
||||||
|
|
||||||
# ---------- Python virtualenv ----------
|
# ---------- Python virtualenv ----------
|
||||||
RUN chown hermes:hermes /opt/hermes
|
|
||||||
USER hermes
|
|
||||||
RUN uv venv && \
|
RUN uv venv && \
|
||||||
uv pip install --no-cache-dir -e ".[all]"
|
uv pip install --no-cache-dir -e ".[all]"
|
||||||
|
|
||||||
|
|
|
||||||
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
services:
|
||||||
|
gateway:
|
||||||
|
build: .
|
||||||
|
image: hermes-agent
|
||||||
|
container_name: hermes
|
||||||
|
restart: unless-stopped
|
||||||
|
network_mode: host
|
||||||
|
volumes:
|
||||||
|
- ~/.hermes:/opt/data
|
||||||
|
environment:
|
||||||
|
- HERMES_UID=${HERMES_UID:-1001}
|
||||||
|
- HERMES_GID=${HERMES_GID:-1001}
|
||||||
|
# Uncomment to expose API server beyond localhost (requires API_SERVER_KEY):
|
||||||
|
# - API_SERVER_HOST=0.0.0.0
|
||||||
|
# - API_SERVER_KEY=${API_SERVER_KEY}
|
||||||
|
command: ["gateway", "run"]
|
||||||
|
|
||||||
|
dashboard:
|
||||||
|
image: hermes-agent
|
||||||
|
container_name: hermes-dashboard
|
||||||
|
restart: unless-stopped
|
||||||
|
network_mode: host
|
||||||
|
depends_on:
|
||||||
|
- gateway
|
||||||
|
volumes:
|
||||||
|
- ~/.hermes:/opt/data
|
||||||
|
environment:
|
||||||
|
- HERMES_UID=${HERMES_UID:-1001}
|
||||||
|
- HERMES_GID=${HERMES_GID:-1001}
|
||||||
|
command: ["dashboard", "--host", "0.0.0.0", "--insecure"]
|
||||||
|
|
@ -22,9 +22,18 @@ if [ "$(id -u)" = "0" ]; then
|
||||||
groupmod -o -g "$HERMES_GID" hermes 2>/dev/null || true
|
groupmod -o -g "$HERMES_GID" hermes 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Fix ownership of the data volume. When HERMES_UID remaps the hermes user,
|
||||||
|
# files created by previous runs (under the old UID) become inaccessible.
|
||||||
|
# Always chown -R when UID was remapped; otherwise only if top-level is wrong.
|
||||||
actual_hermes_uid=$(id -u hermes)
|
actual_hermes_uid=$(id -u hermes)
|
||||||
if [ "$(stat -c %u "$HERMES_HOME" 2>/dev/null)" != "$actual_hermes_uid" ]; then
|
needs_chown=false
|
||||||
echo "$HERMES_HOME is not owned by $actual_hermes_uid, fixing"
|
if [ -n "$HERMES_UID" ] && [ "$HERMES_UID" != "10000" ]; then
|
||||||
|
needs_chown=true
|
||||||
|
elif [ "$(stat -c %u "$HERMES_HOME" 2>/dev/null)" != "$actual_hermes_uid" ]; then
|
||||||
|
needs_chown=true
|
||||||
|
fi
|
||||||
|
if [ "$needs_chown" = true ]; then
|
||||||
|
echo "Fixing ownership of $HERMES_HOME to hermes ($actual_hermes_uid)"
|
||||||
# In rootless Podman the container's "root" is mapped to an unprivileged
|
# In rootless Podman the container's "root" is mapped to an unprivileged
|
||||||
# host UID — chown will fail. That's fine: the volume is already owned
|
# host UID — chown will fail. That's fine: the volume is already owned
|
||||||
# by the mapped user on the host side.
|
# by the mapped user on the host side.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue