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
4 changes: 2 additions & 2 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ permissions:
env:
TZ: Asia/Shanghai
BUILDKIT_PROGRESS: "plain" # Full logs for CI build.
REGISTRY_SRC: ${{ vars.REGISTRY_SRC || 'docker.io' }} # For BASE_NAMESPACE of images: where to pull base images from, docker.io or other source registry URL.
REGISTRY_DST: ${{ vars.REGISTRY_DST || 'docker.io' }} # For tags of built images: where to push images to, docker.io or other destination registry URL.
REGISTRY_SRC: ${{ vars.REGISTRY_SRC || 'quay.io' }} # For BASE_NAMESPACE of images: where to pull base images from, docker.io or other source registry URL.
REGISTRY_DST: ${{ vars.REGISTRY_DST || 'quay.io' }} # For tags of built images: where to push images to, docker.io or other destination registry URL.
# DOCKER_REGISTRY_USERNAME and DOCKER_REGISTRY_PASSWORD is required for docker image push, they should be set in CI secrets.
DOCKER_REGISTRY_USERNAME: ${{ vars.DOCKER_REGISTRY_USERNAME }}
DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
Expand Down
8 changes: 3 additions & 5 deletions docker_casdoor/demo/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ services:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports: ["35432:5432"]
networks: ["net-moa"]
volumes:
- /data/storage/pg-common:/var/lib/postgresql/data
# su postgres && psql -d casdoor

svc-casdoor:
image: quay.io/labnow/casdoor
container_name: svc-casdoor
hostname: svc-nocobase
hostname: svc-casdoor
depends_on: ["db-postgres-common"]
command: |
/bin/bash -l -c '
ls -alh /opt/casdoor
Expand All @@ -30,9 +30,7 @@ services:
sleep 8s
cat /opt/casdoor/conf/app.conf
/opt/casdoor/server -createDatabase=true'
ports:
- 8000:8000
depends_on: ["db-postgres-common"]
ports: ["8000:8000"]
healthcheck:
test: ["CMD-SHELL", "curl --head -fsSk http://localhost:8000/health/ready" ]
interval: 30s
Expand Down
2 changes: 1 addition & 1 deletion docker_gui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ docker run --rm -p 8080:8080 labnow/gui:selkies --encoder=vp8enc --enable_resize

```bash
docker run --rm -it -p 8080:8080 \
quay.io/labnow0dev/gui-linux bash
quay.io/labnow/gui-linux bash

# optional env:
-e SELKIES_TURN_PROTOCOL=tcp \
Expand Down
6 changes: 3 additions & 3 deletions docker_hermes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ The Hermes Agent container hosts services on the following port:

Hermes persists session data, memory, custom skills, and configurations under:

- **`/root/workspace`**: Sourced home directory for all agent states. Must be mounted via Docker Compose or a workspace volume.
- **`/root/.hermes`**: Sourced home directory for all agent states. Must be mounted via Docker Compose or a workspace volume.

### Subdirectories under `/root/workspace`:
### Subdirectories under `/root/.hermes`:
- `sessions/`, `memories/` - Database and conversation history.
- `skills/`, `plans/` - Executable custom agent skills and plan workflows.
- `config.yaml`, `.env` - Main configuration and environment profiles.
Expand Down Expand Up @@ -107,7 +107,7 @@ docker run -d \
--name svc-hermes \
--hostname hermes \
-p 9119:9119 \
-v /path/to/your/data:/root/workspace \
-v /path/to/your/data:/root/.hermes \
-e HERMES_DASHBOARD=true \
quay.io/labnow/hermes:local
```
4 changes: 2 additions & 2 deletions docker_hermes/demo/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
command: ["start-hermes.sh", "all"]
environment:
TZ: ${TZ:-Asia/Shanghai}
HERMES_HOME: /root/workspace
HERMES_HOME: /root/.hermes
HERMES_DASHBOARD: ${HERMES_DASHBOARD:-true}
HERMES_DASHBOARD_HOST: ${HERMES_DASHBOARD_HOST:-0.0.0.0}
HERMES_DASHBOARD_PORT: ${HERMES_DASHBOARD_PORT:-9119}
Expand All @@ -36,7 +36,7 @@ services:
start_period: 20s
retries: 3
volumes:
- ${HERMES_DATA_DIR:-../../.data/hermes}:/root/workspace
- ${HERMES_DATA_DIR:-../../.data/hermes}:/root/.hermes
logging:
driver: "json-file"
options:
Expand Down
108 changes: 66 additions & 42 deletions docker_hermes/hermes.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,72 +1,96 @@
# Distributed under the terms of the Modified BSD License.

ARG BASE_NAMESPACE
ARG BASE_IMG="node"
ARG BASE_IMG_BUILD="node"
ARG BASE_IMG="base"

# --- Building Stage ---
FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG} AS builder
FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG_BUILD} AS builder

# Build-time environment
ENV NODE_ENV=development
WORKDIR /build
ENV UV_LINK_MODE=copy
ENV npm_config_install_links=false
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright

# Clone source
RUN git clone --depth 1 --branch main https://github.com/nousresearch/hermes-agent.git .
WORKDIR /opt/hermes

# Install Node dependencies and build frontend
RUN set -eux \
&& export npm_config_install_links=false \
&& npm install --include=dev --prefer-offline --no-audit \
&& (cd web && npm run build) \
&& (cd ui-tui && npm run build) \
&& mkdir -p hermes_cli/tui_dist && cp ui-tui/dist/entry.js hermes_cli/tui_dist/
# Copy utilities and tools
COPY work /opt/utils/

# Build Python wheel
# Install build-time system dependencies (compilers + native libs needed for Python extensions).
# Without these, `uv sync` fails when compiling packages like `matrix-*-crypto`, `cryptography`, or `ffi`-based wheels on cold builds.
RUN set -eux \
&& . /opt/utils/script-utils.sh && install_apt /opt/utils/install_list_hermes.apt \
## Clone source (full clone for reproducibility; depth 1 for speed)
&& git clone --depth 1 --branch main https://github.com/nousresearch/hermes-agent.git . \
&& chmod +x /opt/utils/*.sh && mv /opt/utils/*hermes*.sh /opt/utils/install_list_hermes.apt /opt/hermes/ \
## ---------- hack python-olm for building compatible wheels ----------
&& mkdir -pv /opt/hermes/vendor \
&& mkdir -pv /tmp/olm && cd /tmp/olm \
&& curl -s https://pypi.org/pypi/python-olm/3.2.16/json \
| jq -r '.urls[] | select(.packagetype=="sdist").url' \
| xargs curl -L -o python-olm-3.2.16.tar.gz \
&& tar xf python-olm-3.2.16.tar.gz \
&& cd python-olm-3.2.16 \
&& sed -i 's/cmake_minimum_required(VERSION [0-9.]*)/cmake_minimum_required(VERSION 3.5)/' libolm/CMakeLists.txt \
&& pip wheel . --no-build-isolation -w /tmp/olm/wheels \
&& mv /tmp/olm/wheels/*olm*.whl /opt/hermes/vendor/ \
&& cd /opt/hermes && rm ./uv.lock \
&& printf '\n[tool.uv.sources]\npython-olm = { path = "vendor/python_olm-3.2.16-cp313-cp313-linux_x86_64.whl" }\n' >> pyproject.toml \
&& uv pip install ./vendor/*.whl
## ---------- (hack finished) ----------

### ---------- Frontend build (web + ui-tui) ----------
RUN set -eux \
&& python3 -m pip install --upgrade pip build \
&& python3 -m build --wheel --outdir dist
## ---------- Node dependencies + Playwright (cached on manifests) ----------
&& npm install --prefer-offline --no-audit --fetch-retries=5 \
&& npm install -g playwright && playwright install --with-deps chromium --only-shell \
&& npm cache clean --force \
&& (cd web && npm run build) \
&& (cd ui-tui && npm run build) \
&& mkdir -pv hermes_cli/tui_dist && cp ui-tui/dist/entry.js hermes_cli/tui_dist/ \
## ---------- Link hermes-agent itself (editable, no deps) + install-method stamp ----------
&& cd /opt/hermes \
&& uv pip install -e ".[all,messaging,anthropic,bedrock,azure-identity,hindsight,matrix]" \
&& mkdir -pv /opt/hermes/bin \
&& ln -sf /opt/hermes/docker/hermes-exec-shim.sh /opt/hermes/bin/hermes \
&& chmod 0755 /opt/hermes/bin/hermes \
&& printf 'docker\n' > /opt/hermes/.install_method

# --- Runtime Stage ---
### --- Runtime Stage ---
FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG}

LABEL maintainer="postmaster@labnow.ai"

# Production environment
ENV NODE_ENV=production
ENV HERMES_HOME=/root/workspace
ENV HERMES_WEB_DIST=/usr/local/lib/python3.12/dist-packages/hermes_cli/web_dist
ENV HERMES_TUI_DIR=/usr/local/lib/python3.12/dist-packages/hermes_cli/tui_dist
ENV HERMES_HOME=/root/.hermes
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright
ENV PATH="/opt/node/bin:/opt/conda/bin:/root/.local/bin:${PATH}"
ENV HOME=/root/workspace
WORKDIR /root/workspace
ENV PYTHONPATH="/opt/hermes:${PYTHONPATH:-}"
ENV PATH="/opt/hermes/bin:/opt/node/bin:/opt/conda/bin:/root/.local/bin:${PATH}"
ENV HOME=/root/.hermes
# Copy the full hermes install tree from the builder (source + browsers + built frontends)
COPY --from=builder /opt/hermes /opt/hermes


# Copy build artifacts from builder
COPY --from=builder /build/dist/*.whl /tmp/

# Copy utilities and tools
COPY work /opt/utils/

RUN set -eux \
&& chmod +x /opt/utils/*.sh \
&& ln -sf /opt/utils/start-hermes.sh /usr/local/bin/start-hermes.sh \
&& ln -sf /opt/utils/healthcheck-hermes.sh /usr/local/bin/healthcheck-hermes.sh \
## Install Runtime dependencies
&& printf 'Acquire::Retries "5";\nAcquire::http::Timeout "30";\nAcquire::https::Timeout "30";\n' > /etc/apt/apt.conf.d/80-retries \
&& pip install --no-cache-dir /tmp/*.whl \
&& npx playwright install --with-deps chromium --only-shell \
## Install supervisord (Go version)
&& source /opt/utils/script-setup-sys.sh && setup_supervisord \
&& source /opt/utils/script-utils.sh && install_apt /opt/utils/install_list_hermes.apt \
# Discover the real python site-packages so legacy env-var fallbacks point at the right tree.
# Keep explicit versioned fallbacks around in case detection runs before the first pip install.
RUN set -eux && cd /opt/hermes \
&& . /opt/utils/script-utils.sh && install_apt /opt/hermes/install_list_hermes.apt \
&& uv pip install ./vendor/*.whl \
&& uv pip install -e ".[all,messaging,anthropic,bedrock,azure-identity,hindsight,matrix]" \
&& ln -sf /opt/hermes/*hermes*.sh /usr/local/bin/ \
&& ln -sf /opt/hermes/bin/*hermes*.sh /usr/local/bin/ \
&& . /opt/utils/script-setup-sys.sh && setup_supervisord \
&& install__clean

# Data persistence is owned by the runtime orchestrator.
# Compose and external workspace wrappers must provide the explicit `/root/workspace` mount.
# Compose and external workspace wrappers must provide the explicit `${HERMES_HOME}` mount.

# Standalone containers keep the historical gateway+dashboard behavior.
# The labnow-open wrapper calls start-hermes.sh with explicit gateway/dashboard modes and therefore does not use this CMD.
WORKDIR /root/.hermes
CMD ["start-hermes.sh", "all"]
EXPOSE 9119
HEALTHCHECK --interval=10s --timeout=5s --start-period=20s --retries=3 \
HEALTHCHECK --interval=10s --timeout=5s --start-period=40s --retries=5 \
CMD ["/usr/local/bin/healthcheck-hermes.sh"]
6 changes: 3 additions & 3 deletions docker_hermes/work/install_list_hermes.apt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
libffi-dev
libolm-dev
iputils-ping
xz-utils
ripgrep
ffmpeg
libffi-dev
libolm-dev
procps
openssh-client
docker-cli
xz-utils
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set -eu
# Set up dashboard parameters
dash_host="${HERMES_DASHBOARD_HOST:-0.0.0.0}"
dash_port="${HERMES_DASHBOARD_PORT:-9119}"
hermes_home="${HERMES_HOME:-/root/workspace}"
hermes_home="${HERMES_HOME:-/root/.hermes}"

insecure=""
case "${HERMES_DASHBOARD_INSECURE:-}" in
Expand Down
8 changes: 4 additions & 4 deletions docker_hermes/work/start-hermes.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -eu

HERMES_HOME="${HERMES_HOME:-/root/workspace}"
HERMES_HOME="${HERMES_HOME:-/root/.hermes}"
mkdir -p "$HERMES_HOME"

bootstrap_lock_dir="$HERMES_HOME/.hermes-bootstrap.lock"
Expand Down Expand Up @@ -124,8 +124,8 @@ if [ -z "${AGENT_BROWSER_EXECUTABLE_PATH:-}" ] && [ -n "${PLAYWRIGHT_BROWSERS_PA
fi

# Configure environments for command invocation
export HOME=/root/workspace
cd /root/workspace
export HOME="${HERMES_HOME}"
cd "${HERMES_HOME}"

# Explicit service modes allow an outer supervisor (for example labnow-open) to
# manage Hermes processes directly instead of starting a nested supervisor.
Expand All @@ -141,7 +141,7 @@ case "$1" in
echo "[start-hermes] the all mode does not accept extra arguments" >&2
exit 2
fi
exec /opt/utils/supervisord.sh
exec /opt/hermes/start-hermes-supervisord.sh
;;
gateway)
shift
Expand Down
23 changes: 12 additions & 11 deletions docker_keycloak/demo/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
services:
db-postgres:
db-postgres-common:
# su postgres && psql -d keycloak -U pg-keycloak-username
image: docker.io/library/postgres:16
container_name: db-postgres
image: quay.io/labnow/postgres-17:latest
container_name: db-postgres-common
hostname: db-postgres-common
pull_policy: always
restart: unless-stopped
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: pg-keycloak-username
POSTGRES_PASSWORD: pg-keycloak-password

svc-keycloak:
image: docker.io/labnow/keycloak
image: quay.io/labnow/keycloak
# build:
# context: ../
# dockerfile: Dockerfile
# args:
# BASE_NAMESPACE: labnow0dev
# BASE_NAMESPACE: labnow
container_name: svc-keycloak
hostname: svc-keycloak
depends_on: ["db-postgres-common"]
# command: ["/bin/bash", "--login", "bin/kc.sh", "start-dev", "--verbose"]
command: |
/bin/bash -l -c '
Expand All @@ -30,20 +35,16 @@ services:
environment:
KC_HOSTNAME: localhost
KC_DB: postgres
KC_DB_URL: "jdbc:postgresql://db-postgres:5432/keycloak"
KC_DB_URL: "jdbc:postgresql://db-postgres-common:5432/keycloak"
KC_DB_USERNAME: "pg-keycloak-username"
KC_DB_PASSWORD: "pg-keycloak-password"
KEYCLOAK_ADMIN: keycloak-admin
KEYCLOAK_ADMIN_PASSWORD: keycloak-password
PROXY_ADDRESS_FORWARDING: "true"
ports:
- 8080:8080
depends_on:
- db-postgres
ports: ["8080:8080"]
healthcheck:
test: ["CMD-SHELL", "curl", "--head", "-fsSk", "https://localhost:8080/health/ready" ]
interval: 30s
timeout: 30s
start_period: 5s
retries: 3

2 changes: 1 addition & 1 deletion docker_nocobase/demo/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ services:
# su postgres && psql -d nocobase

svc-nocobase:
image: quay.io/labnow0dev/nocobase
image: quay.io/labnow/nocobase
container_name: svc-nocobase
hostname: svc-nocobase
depends_on: ["db-postgres-common"]
Expand Down