feat: init
Main Release / hadolint (push) Successful in 7s
Main Release / build (push) Successful in 2m34s
Main Release / tag (push) Successful in 9s
Tag Release / hadolint (push) Successful in 12s
Tag Release / build (push) Successful in 2m53s
Tag Release / build-push (push) Successful in 3m29s
Main Release / hadolint (push) Successful in 7s
Main Release / build (push) Successful in 2m34s
Main Release / tag (push) Successful in 9s
Tag Release / hadolint (push) Successful in 12s
Tag Release / build (push) Successful in 2m53s
Tag Release / build-push (push) Successful in 3m29s
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
name: Nightly Rebuild
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hadolint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
|
with:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||||
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
|
|
||||||
|
build-push:
|
||||||
|
needs: [build]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||||
|
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- id: get-latest-tag
|
||||||
|
run: |
|
||||||
|
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
||||||
|
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||||
|
- id: meta
|
||||||
|
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6
|
||||||
|
with:
|
||||||
|
images: jcabillot/hermes-agent-webui
|
||||||
|
tags: |
|
||||||
|
type=raw,value=${{ steps.get-latest-tag.outputs.tag }}-latest,enable=${{ steps.get-latest-tag.outputs.tag != '' }}
|
||||||
|
- uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
pull: true
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
name: Main Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hadolint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
|
with:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||||
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
|
|
||||||
|
tag:
|
||||||
|
needs: [build]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Configure git auth
|
||||||
|
run: |
|
||||||
|
git remote set-url origin "https://x-access-token:${{ secrets.SA_TOKEN_ACTION_PUSH_TAGS }}@scm.cabillot.eu/web/hermes-agent-webui.git"
|
||||||
|
- uses: anothrNick/github-tag-action@4ed44965e0db8dab2b466a16da04aec3cc312fd8 # v1.75.0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.SA_TOKEN_ACTION_PUSH_TAGS }}
|
||||||
|
DEFAULT_BUMP: patch
|
||||||
|
RELEASE_BRANCHES: main
|
||||||
|
WITH_V: true
|
||||||
|
GIT_API_TAGGING: false
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
name: PR Checks
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hadolint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
|
with:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||||
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
name: Tag Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ['*']
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hadolint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
|
with:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||||
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
|
|
||||||
|
build-push:
|
||||||
|
needs: [build]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||||
|
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- id: meta
|
||||||
|
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6
|
||||||
|
with:
|
||||||
|
images: jcabillot/hermes-agent-webui
|
||||||
|
tags: |
|
||||||
|
type=ref,event=tag
|
||||||
|
type=ref,event=tag,suffix=-latest
|
||||||
|
- uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
pull: true
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## 1. Overview
|
||||||
|
|
||||||
|
Container image for Hermes Agent WebUI with a bundled Hermes Agent runtime, distributed via Docker Hub as `jcabillot/hermes-agent-webui`.
|
||||||
|
|
||||||
|
## 2. Folder Structure
|
||||||
|
|
||||||
|
- `Dockerfile`: Multi-stage image build — clones `nousresearch/hermes-agent` and `nesquena/hermes-webui`, installs both in a shared venv, copies to a slim runtime stage. Exposes port `8787`.
|
||||||
|
- `.gitea/workflows/docker-build.yaml`: Gitea Actions pipeline — builds and pushes the image to Docker Hub on push to `main` and on a daily cron schedule.
|
||||||
|
- `renovate.json`: Regex-based custom manager tracking upstream `nousresearch/hermes-agent` and `nesquena/hermes-webui` Docker tag updates.
|
||||||
|
- `README.md`: Public-facing documentation.
|
||||||
|
- `AGENTS.md`: This file — contributor guide for AI agents.
|
||||||
|
|
||||||
|
## 3. Core Behaviors & Patterns
|
||||||
|
|
||||||
|
- **Build & Release**: The Dockerfile pins two upstream repos via `ARG HERMES_AGENT_VERSION` and `ARG HERMES_WEBUI_VERSION`. On push to `main`, the CI pipeline builds the image, bumps the git tag (`patch`), which triggers a tag release that pushes to `jcabillot/hermes-agent-webui`. A daily cron rebuild pushes `<latest-tag>-latest`.
|
||||||
|
- **Dependency Tracking**: Renovate scans `Dockerfile` for both `ARG` version pins and opens PRs when either upstream publishes a new tag.
|
||||||
|
- **Multi-stage Build**: Build stage clones repos and creates a venv; runtime stage is a clean `python:3.12-slim` with only the venv and source trees copied over.
|
||||||
|
- **Health Check**: The container exposes port `8787` with a `/health` endpoint polled every 30s.
|
||||||
|
|
||||||
|
## 4. Conventions
|
||||||
|
|
||||||
|
- **Version Pinning**: Both upstream versions (`HERMES_AGENT_VERSION`, `HERMES_WEBUI_VERSION`) are pinned via `ARG` at the top of the builder stage, managed by renovate.
|
||||||
|
- **CI Secrets**: `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, `SA_TOKEN_ACTION_PUSH_TAGS` required. Login skipped on PR events.
|
||||||
|
- **Dockerfile Style**: Multi-stage with `AS builder` / runtime split. `apt-get` in a single `RUN` with cleanup. `COPY --from=builder` for artifacts. Comments annotate stage boundaries.
|
||||||
|
- **Pin Hashing**: All GitHub Action versions pinned to commit SHA hashes with semantic version in trailing comment.
|
||||||
|
|
||||||
|
## 5. Working Agreements
|
||||||
|
|
||||||
|
- Respond in the user's preferred language (French or English); keep technical terms in English, never translate code blocks
|
||||||
|
- Create tests/lint only when explicitly requested
|
||||||
|
- Build context by reviewing related usages and patterns before editing
|
||||||
|
- Prefer simple solutions; avoid unnecessary abstraction
|
||||||
|
- Ask for clarification when requirements are ambiguous
|
||||||
|
- Make minimal changes; preserve public APIs and behavior
|
||||||
|
- Run type-check after code changes (no type-checker in this project — skip)
|
||||||
|
- New files: single-purpose, colocated with related concerns
|
||||||
|
- External dependencies: only when necessary, explain why
|
||||||
+94
@@ -0,0 +1,94 @@
|
|||||||
|
# Build stage: clone and install Hermes Agent + WebUI dependencies
|
||||||
|
FROM python:3.12-slim AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# hadolint ignore=DL3008
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install uv system-wide
|
||||||
|
# hadolint ignore=DL4006
|
||||||
|
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh
|
||||||
|
|
||||||
|
# Clone Hermes Agent at a pinned commit
|
||||||
|
ARG HERMES_AGENT_VERSION=v2026.6.5
|
||||||
|
RUN git clone --depth 1 --branch ${HERMES_AGENT_VERSION} \
|
||||||
|
https://github.com/NousResearch/hermes-agent.git /build/hermes-agent
|
||||||
|
|
||||||
|
# Clone Hermes WebUI at a pinned commit
|
||||||
|
ARG HERMES_WEBUI_VERSION=v0.51.350
|
||||||
|
RUN git clone --depth 1 --branch ${HERMES_WEBUI_VERSION} \
|
||||||
|
https://github.com/nesquena/hermes-webui.git /build/hermes-webui
|
||||||
|
|
||||||
|
# Create a shared venv and install both projects
|
||||||
|
# hadolint ignore=DL3059
|
||||||
|
RUN uv venv /build/venv
|
||||||
|
ENV VIRTUAL_ENV=/build/venv
|
||||||
|
ENV PATH="/build/venv/bin:$PATH"
|
||||||
|
|
||||||
|
# Install hermes-agent with all extras (includes ML/agent deps)
|
||||||
|
# hadolint ignore=DL3013,DL3059
|
||||||
|
RUN uv pip install \
|
||||||
|
"/build/hermes-agent[all]"
|
||||||
|
|
||||||
|
# Install hermes-webui deps (pyyaml + cryptography)
|
||||||
|
# hadolint ignore=DL3059
|
||||||
|
RUN uv pip install \
|
||||||
|
-r /build/hermes-webui/requirements.txt
|
||||||
|
|
||||||
|
# Install uv in the venv so the webui server can use it for profile/skill management
|
||||||
|
# hadolint ignore=DL3059
|
||||||
|
RUN uv pip install \
|
||||||
|
"uv>=0.6.0"
|
||||||
|
|
||||||
|
# Runtime stage
|
||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# hadolint ignore=DL3008
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
openssh-client \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy the virtual environment and source trees from builder
|
||||||
|
COPY --from=builder /build/venv /opt/venv
|
||||||
|
COPY --from=builder /build/hermes-agent /opt/hermes-agent
|
||||||
|
COPY --from=builder /build/hermes-webui /app
|
||||||
|
|
||||||
|
# Set environment
|
||||||
|
ENV PATH="/opt/venv/bin:$PATH" \
|
||||||
|
VIRTUAL_ENV=/opt/venv \
|
||||||
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
PYTHONIOENCODING=utf-8
|
||||||
|
|
||||||
|
# Tell the WebUI where to find the agent
|
||||||
|
ENV HERMES_WEBUI_AGENT_DIR=/opt/hermes-agent \
|
||||||
|
HERMES_WEBUI_HOST=0.0.0.0 \
|
||||||
|
HERMES_WEBUI_PORT=8787 \
|
||||||
|
HERMES_WEBUI_STATE_DIR=/home/hermes/.hermes/webui \
|
||||||
|
HERMES_WEBUI_DEFAULT_WORKSPACE=/workspace \
|
||||||
|
HERMES_HOME=/home/hermes/.hermes
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN useradd --create-home --shell /bin/bash hermes \
|
||||||
|
&& mkdir -p /workspace \
|
||||||
|
&& chown -R hermes:hermes /app /opt/venv /opt/hermes-agent /workspace /home/hermes
|
||||||
|
|
||||||
|
USER hermes
|
||||||
|
|
||||||
|
EXPOSE 8787
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8787/health || exit 1
|
||||||
|
|
||||||
|
# Run the WebUI server (which runs Hermes Agent in-process)
|
||||||
|
CMD ["python", "/app/server.py"]
|
||||||
@@ -1,3 +1,29 @@
|
|||||||
# hermes-agent-webui
|
# hermes-agent-webui
|
||||||
|
|
||||||
Hermes Agent WebUI container image
|
Container image for [Hermes WebUI](https://github.com/nesquena/hermes-webui) with a bundled [Hermes Agent](https://github.com/NousResearch/hermes-agent) runtime.
|
||||||
|
|
||||||
|
## Image
|
||||||
|
|
||||||
|
`jcabillot/hermes-agent-webui` — [Docker Hub](https://hub.docker.com/r/jcabillot/hermes-agent-webui)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker pull jcabillot/hermes-agent-webui
|
||||||
|
docker run -p 8787:8787 jcabillot/hermes-agent-webui
|
||||||
|
```
|
||||||
|
|
||||||
|
Open http://localhost:8787
|
||||||
|
|
||||||
|
## Build locally
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t jcabillot/hermes-agent-webui .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tags
|
||||||
|
|
||||||
|
| Tag | Description |
|
||||||
|
|-----|-------------|
|
||||||
|
| `latest` | Latest stable build from `main` |
|
||||||
|
| `sha-<commit>` | Per-commit build |
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"customManagers": [
|
||||||
|
{
|
||||||
|
"customType": "regex",
|
||||||
|
"description": "Track nousresearch/hermes-agent Docker tag pinned in Dockerfile ARG",
|
||||||
|
"managerFilePatterns": ["/^Dockerfile$/"],
|
||||||
|
"matchStrings": ["ARG HERMES_AGENT_VERSION=v(?<currentValue>[^\\s]+)"],
|
||||||
|
"depNameTemplate": "nousresearch/hermes-agent",
|
||||||
|
"datasourceTemplate": "docker",
|
||||||
|
"versioningTemplate": "docker",
|
||||||
|
"extractVersionTemplate": "v^(?<version>.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"customType": "regex",
|
||||||
|
"description": "Track nesquena/hermes-webui Docker tag pinned in Dockerfile ARG",
|
||||||
|
"managerFilePatterns": ["/^Dockerfile$/"],
|
||||||
|
"matchStrings": ["ARG HERMES_WEBUI_VERSION=v(?<currentValue>[^\\s]+)"],
|
||||||
|
"depNameTemplate": "nesquena/hermes-webui",
|
||||||
|
"datasourceTemplate": "docker",
|
||||||
|
"versioningTemplate": "docker",
|
||||||
|
"extractVersionTemplate": "v^(?<version>.*)$"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user